aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm
diff options
context:
space:
mode:
authorJush Lu <jush.msn@gmail.com>2011-03-09 19:39:16 +0800
committerJush Lu <jush.msn@gmail.com>2011-03-09 19:39:16 +0800
commitb5530586d68bd25831a6796b5d3199cb0769a35c (patch)
treefac4a03b53b6a64b0c00f433e4d8b3c9f2bc67cd /include/llvm
parentb4e17c5bf4361bbdeced39aa071150d7fa9c3c10 (diff)
parentd01f50f42ce60207ed6d27fb1778e456d83be06c (diff)
downloadexternal_llvm-b5530586d68bd25831a6796b5d3199cb0769a35c.tar.gz
external_llvm-b5530586d68bd25831a6796b5d3199cb0769a35c.tar.bz2
external_llvm-b5530586d68bd25831a6796b5d3199cb0769a35c.zip
Merge upstream r127116
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/APFloat.h7
-rw-r--r--include/llvm/ADT/APInt.h120
-rw-r--r--include/llvm/ADT/APSInt.h18
-rw-r--r--include/llvm/ADT/ArrayRef.h137
-rw-r--r--include/llvm/ADT/BitVector.h30
-rw-r--r--include/llvm/ADT/DenseMap.h42
-rw-r--r--include/llvm/ADT/DenseSet.h3
-rw-r--r--include/llvm/ADT/DepthFirstIterator.h3
-rw-r--r--include/llvm/ADT/EquivalenceClasses.h2
-rw-r--r--include/llvm/ADT/FoldingSet.h2
-rw-r--r--include/llvm/ADT/ImmutableIntervalMap.h54
-rw-r--r--include/llvm/ADT/ImmutableList.h14
-rw-r--r--include/llvm/ADT/ImmutableMap.h53
-rw-r--r--include/llvm/ADT/ImmutableSet.h553
-rw-r--r--include/llvm/ADT/InMemoryStruct.h77
-rw-r--r--include/llvm/ADT/IndexedMap.h14
-rw-r--r--include/llvm/ADT/IntEqClasses.h88
-rw-r--r--include/llvm/ADT/IntervalMap.h2139
-rw-r--r--include/llvm/ADT/Optional.h54
-rw-r--r--include/llvm/ADT/PointerIntPair.h7
-rw-r--r--include/llvm/ADT/PointerUnion.h12
-rw-r--r--include/llvm/ADT/PostOrderIterator.h6
-rw-r--r--include/llvm/ADT/SCCIterator.h2
-rw-r--r--include/llvm/ADT/ScopedHashTable.h125
-rw-r--r--include/llvm/ADT/SmallPtrSet.h5
-rw-r--r--include/llvm/ADT/SmallString.h12
-rw-r--r--include/llvm/ADT/SmallVector.h6
-rw-r--r--include/llvm/ADT/SparseBitVector.h2
-rw-r--r--include/llvm/ADT/Statistic.h5
-rw-r--r--include/llvm/ADT/StringExtras.h9
-rw-r--r--include/llvm/ADT/StringMap.h5
-rw-r--r--include/llvm/ADT/StringRef.h18
-rw-r--r--include/llvm/ADT/Triple.h11
-rw-r--r--include/llvm/ADT/Twine.h30
-rw-r--r--include/llvm/ADT/ValueMap.h2
-rw-r--r--include/llvm/ADT/ilist.h1
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h45
-rw-r--r--include/llvm/Analysis/CallGraph.h13
-rw-r--r--include/llvm/Analysis/CodeMetrics.h7
-rw-r--r--include/llvm/Analysis/ConstantFolding.h13
-rw-r--r--include/llvm/Analysis/DIBuilder.h405
-rw-r--r--include/llvm/Analysis/DebugInfo.h260
-rw-r--r--include/llvm/Analysis/DominanceFrontier.h189
-rw-r--r--include/llvm/Analysis/DominatorInternals.h187
-rw-r--r--include/llvm/Analysis/Dominators.h233
-rw-r--r--include/llvm/Analysis/InlineCost.h13
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h82
-rw-r--r--include/llvm/Analysis/LiveValues.h99
-rw-r--r--include/llvm/Analysis/LoopInfo.h32
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h4
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h13
-rw-r--r--include/llvm/Analysis/Passes.h30
-rw-r--r--include/llvm/Analysis/PathNumbering.h304
-rw-r--r--include/llvm/Analysis/PathProfileInfo.h113
-rw-r--r--include/llvm/Analysis/PostDominators.h2
-rw-r--r--include/llvm/Analysis/ProfileInfoTypes.h33
-rw-r--r--include/llvm/Analysis/RegionInfo.h14
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h146
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h6
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h138
-rw-r--r--include/llvm/Analysis/ValueTracking.h52
-rw-r--r--include/llvm/BasicBlock.h32
-rw-r--r--include/llvm/Bitcode/Archive.h8
-rw-r--r--include/llvm/Bitcode/BitCodes.h2
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h8
-rw-r--r--include/llvm/CMakeLists.txt2
-rw-r--r--include/llvm/CallingConv.h9
-rw-r--r--include/llvm/CodeGen/Analysis.h7
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h10
-rw-r--r--include/llvm/CodeGen/BinaryObject.h2
-rw-r--r--include/llvm/CodeGen/CalcSpillWeights.h19
-rw-r--r--include/llvm/CodeGen/EdgeBundles.h61
-rw-r--r--include/llvm/CodeGen/FunctionLoweringInfo.h76
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h45
-rw-r--r--include/llvm/CodeGen/IntrinsicLowering.h5
-rw-r--r--include/llvm/CodeGen/JITCodeEmitter.h2
-rw-r--r--include/llvm/CodeGen/LatencyPriorityQueue.h22
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h1
-rw-r--r--include/llvm/CodeGen/LiveInterval.h39
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h31
-rw-r--r--include/llvm/CodeGen/LiveStackAnalysis.h14
-rw-r--r--include/llvm/CodeGen/LiveVariables.h7
-rw-r--r--include/llvm/CodeGen/MachORelocation.h2
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h17
-rw-r--r--include/llvm/CodeGen/MachineCodeEmitter.h2
-rw-r--r--include/llvm/CodeGen/MachineCodeInfo.h2
-rw-r--r--include/llvm/CodeGen/MachineConstantPool.h3
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h14
-rw-r--r--include/llvm/CodeGen/MachineFunction.h2
-rw-r--r--include/llvm/CodeGen/MachineFunctionAnalysis.h4
-rw-r--r--include/llvm/CodeGen/MachineInstr.h60
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h10
-rw-r--r--include/llvm/CodeGen/MachineLocation.h7
-rw-r--r--include/llvm/CodeGen/MachineLoopRanges.h112
-rw-r--r--include/llvm/CodeGen/MachineMemOperand.h2
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h7
-rw-r--r--include/llvm/CodeGen/MachineOperand.h12
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h36
-rw-r--r--include/llvm/CodeGen/MachineRelocation.h2
-rw-r--r--include/llvm/CodeGen/Passes.h25
-rw-r--r--include/llvm/CodeGen/PostRAHazardRecognizer.h94
-rw-r--r--include/llvm/CodeGen/RegAllocPBQP.h3
-rw-r--r--include/llvm/CodeGen/RegisterCoalescer.h2
-rw-r--r--include/llvm/CodeGen/RegisterScavenging.h2
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h81
-rw-r--r--include/llvm/CodeGen/ScheduleHazardRecognizer.h28
-rw-r--r--include/llvm/CodeGen/ScoreboardHazardRecognizer.h129
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h61
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h92
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h24
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h162
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h6
-rw-r--r--include/llvm/CodeGen/ValueTypes.h4
-rw-r--r--include/llvm/CompilerDriver/CompilationGraph.h2
-rw-r--r--include/llvm/CompilerDriver/Tool.h2
-rw-r--r--include/llvm/Config/config.h.cmake346
-rw-r--r--include/llvm/Config/config.h.in64
-rw-r--r--include/llvm/Config/llvm-config.h.cmake9
-rw-r--r--include/llvm/Constant.h12
-rw-r--r--include/llvm/Constants.h136
-rw-r--r--include/llvm/DerivedTypes.h2
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h44
-rw-r--r--include/llvm/ExecutionEngine/GenericValue.h2
-rw-r--r--include/llvm/ExecutionEngine/JITEventListener.h2
-rw-r--r--include/llvm/ExecutionEngine/JITMemoryManager.h2
-rw-r--r--include/llvm/ExecutionEngine/MCJIT.h38
-rw-r--r--include/llvm/GlobalAlias.h3
-rw-r--r--include/llvm/GlobalValue.h17
-rw-r--r--include/llvm/GlobalVariable.h3
-rw-r--r--include/llvm/InitializePasses.h30
-rw-r--r--include/llvm/InlineAsm.h9
-rw-r--r--include/llvm/InstrTypes.h193
-rw-r--r--include/llvm/Instruction.h7
-rw-r--r--include/llvm/Instructions.h70
-rw-r--r--include/llvm/IntrinsicInst.h29
-rw-r--r--include/llvm/Intrinsics.td5
-rw-r--r--include/llvm/IntrinsicsARM.td10
-rw-r--r--include/llvm/IntrinsicsPTX.td32
-rw-r--r--include/llvm/IntrinsicsXCore.td41
-rw-r--r--include/llvm/LLVMContext.h16
-rw-r--r--include/llvm/LinkAllPasses.h12
-rw-r--r--include/llvm/LinkAllVMCore.h17
-rw-r--r--include/llvm/MC/EDInstInfo.h2
-rw-r--r--include/llvm/MC/MCAsmInfo.h49
-rw-r--r--include/llvm/MC/MCAsmLayout.h43
-rw-r--r--include/llvm/MC/MCAssembler.h162
-rw-r--r--include/llvm/MC/MCCodeEmitter.h38
-rw-r--r--include/llvm/MC/MCContext.h56
-rw-r--r--include/llvm/MC/MCDirectives.h1
-rw-r--r--include/llvm/MC/MCDisassembler.h2
-rw-r--r--include/llvm/MC/MCDwarf.h82
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h47
-rw-r--r--include/llvm/MC/MCExpr.h29
-rw-r--r--include/llvm/MC/MCFixup.h16
-rw-r--r--include/llvm/MC/MCFixupKindInfo.h43
-rw-r--r--include/llvm/MC/MCInst.h2
-rw-r--r--include/llvm/MC/MCInstPrinter.h3
-rw-r--r--include/llvm/MC/MCMachOSymbolFlags.h4
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h65
-rw-r--r--include/llvm/MC/MCObjectFormat.h54
-rw-r--r--include/llvm/MC/MCObjectStreamer.h16
-rw-r--r--include/llvm/MC/MCObjectWriter.h40
-rw-r--r--include/llvm/MC/MCParser/AsmLexer.h15
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h32
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h4
-rw-r--r--include/llvm/MC/MCParser/MCAsmParserExtension.h4
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h4
-rw-r--r--include/llvm/MC/MCSection.h4
-rw-r--r--include/llvm/MC/MCSectionCOFF.h1
-rw-r--r--include/llvm/MC/MCSectionELF.h129
-rw-r--r--include/llvm/MC/MCSectionMachO.h1
-rw-r--r--include/llvm/MC/MCStreamer.h173
-rw-r--r--include/llvm/MC/MCValue.h2
-rw-r--r--include/llvm/Metadata.h3
-rw-r--r--include/llvm/Module.h11
-rw-r--r--include/llvm/Object/MachOFormat.h367
-rw-r--r--include/llvm/Object/MachOObject.h180
-rw-r--r--include/llvm/Object/ObjectFile.h17
-rw-r--r--include/llvm/OperandTraits.h28
-rw-r--r--include/llvm/Operator.h157
-rw-r--r--include/llvm/PassSupport.h2
-rw-r--r--include/llvm/Support/AIXDataTypesFix.h (renamed from include/llvm/System/AIXDataTypesFix.h)2
-rw-r--r--include/llvm/Support/AlignOf.h2
-rw-r--r--include/llvm/Support/Allocator.h4
-rw-r--r--include/llvm/Support/Atomic.h (renamed from include/llvm/System/Atomic.h)4
-rw-r--r--include/llvm/Support/CFG.h7
-rw-r--r--include/llvm/Support/COFF.h2
-rw-r--r--include/llvm/Support/CallSite.h5
-rw-r--r--include/llvm/Support/Compiler.h19
-rw-r--r--include/llvm/Support/ConstantFolder.h72
-rw-r--r--include/llvm/Support/ConstantRange.h4
-rw-r--r--include/llvm/Support/DOTGraphTraits.h5
-rw-r--r--include/llvm/Support/DataTypes.h.cmake (renamed from include/llvm/System/DataTypes.h.cmake)8
-rw-r--r--include/llvm/Support/DataTypes.h.in (renamed from include/llvm/System/DataTypes.h.in)2
-rw-r--r--include/llvm/Support/Disassembler.h (renamed from include/llvm/System/Disassembler.h)2
-rw-r--r--include/llvm/Support/Dwarf.h3
-rw-r--r--include/llvm/Support/DynamicLibrary.h (renamed from include/llvm/System/DynamicLibrary.h)2
-rw-r--r--include/llvm/Support/DynamicLinker.h40
-rw-r--r--include/llvm/Support/ELF.h223
-rw-r--r--include/llvm/Support/Endian.h4
-rw-r--r--include/llvm/Support/Errno.h (renamed from include/llvm/System/Errno.h)2
-rw-r--r--include/llvm/Support/FEnv.h (renamed from include/llvm/System/FEnv.h)2
-rw-r--r--include/llvm/Support/FileSystem.h690
-rw-r--r--include/llvm/Support/FileUtilities.h2
-rw-r--r--include/llvm/Support/GraphWriter.h10
-rw-r--r--include/llvm/Support/Host.h (renamed from include/llvm/System/Host.h)2
-rw-r--r--include/llvm/Support/IRBuilder.h366
-rw-r--r--include/llvm/Support/IRReader.h24
-rw-r--r--include/llvm/Support/IncludeFile.h (renamed from include/llvm/System/IncludeFile.h)20
-rw-r--r--include/llvm/Support/LICENSE.TXT (renamed from include/llvm/System/LICENSE.TXT)2
-rw-r--r--include/llvm/Support/MachO.h36
-rw-r--r--include/llvm/Support/ManagedStatic.h4
-rw-r--r--include/llvm/Support/MathExtras.h15
-rw-r--r--include/llvm/Support/Memory.h (renamed from include/llvm/System/Memory.h)14
-rw-r--r--include/llvm/Support/MemoryBuffer.h52
-rw-r--r--include/llvm/Support/MemoryObject.h2
-rw-r--r--include/llvm/Support/Mutex.h (renamed from include/llvm/System/Mutex.h)24
-rw-r--r--include/llvm/Support/MutexGuard.h2
-rw-r--r--include/llvm/Support/NoFolder.h198
-rw-r--r--include/llvm/Support/Path.h16
-rw-r--r--include/llvm/Support/PathV1.h (renamed from include/llvm/System/Path.h)67
-rw-r--r--include/llvm/Support/PathV2.h347
-rw-r--r--include/llvm/Support/PatternMatch.h339
-rw-r--r--include/llvm/Support/PointerLikeTypeTraits.h2
-rw-r--r--include/llvm/Support/Process.h (renamed from include/llvm/System/Process.h)4
-rw-r--r--include/llvm/Support/Program.h (renamed from include/llvm/System/Program.h)4
-rw-r--r--include/llvm/Support/RWMutex.h (renamed from include/llvm/System/RWMutex.h)40
-rw-r--r--include/llvm/Support/Signals.h (renamed from include/llvm/System/Signals.h)4
-rw-r--r--include/llvm/Support/Solaris.h (renamed from include/llvm/System/Solaris.h)2
-rw-r--r--include/llvm/Support/SourceMgr.h17
-rw-r--r--include/llvm/Support/StableBasicBlockNumbering.h59
-rw-r--r--include/llvm/Support/StandardPasses.h78
-rw-r--r--include/llvm/Support/SwapByteOrder.h101
-rw-r--r--include/llvm/Support/TargetFolder.h68
-rw-r--r--include/llvm/Support/ThreadLocal.h (renamed from include/llvm/System/ThreadLocal.h)12
-rw-r--r--include/llvm/Support/Threading.h (renamed from include/llvm/System/Threading.h)12
-rw-r--r--include/llvm/Support/TimeValue.h (renamed from include/llvm/System/TimeValue.h)2
-rw-r--r--include/llvm/Support/Timer.h2
-rw-r--r--include/llvm/Support/Valgrind.h (renamed from include/llvm/System/Valgrind.h)2
-rw-r--r--include/llvm/Support/raw_ostream.h22
-rw-r--r--include/llvm/Support/system_error.h910
-rw-r--r--include/llvm/System/Alarm.h51
-rw-r--r--include/llvm/System/SwapByteOrder.h101
-rw-r--r--include/llvm/Target/Mangler.h7
-rw-r--r--include/llvm/Target/SubtargetFeature.h2
-rw-r--r--include/llvm/Target/Target.td59
-rw-r--r--include/llvm/Target/TargetAsmBackend.h55
-rw-r--r--include/llvm/Target/TargetAsmInfo.h75
-rw-r--r--include/llvm/Target/TargetAsmParser.h2
-rw-r--r--include/llvm/Target/TargetData.h4
-rw-r--r--include/llvm/Target/TargetFrameInfo.h112
-rw-r--r--include/llvm/Target/TargetFrameLowering.h196
-rw-r--r--include/llvm/Target/TargetInstrDesc.h13
-rw-r--r--include/llvm/Target/TargetInstrInfo.h99
-rw-r--r--include/llvm/Target/TargetInstrItineraries.h10
-rw-r--r--include/llvm/Target/TargetJITInfo.h2
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h75
-rw-r--r--include/llvm/Target/TargetLowering.h159
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h6
-rw-r--r--include/llvm/Target/TargetMachine.h22
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h195
-rw-r--r--include/llvm/Target/TargetRegistry.h24
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td71
-rw-r--r--include/llvm/Transforms/IPO.h6
-rw-r--r--include/llvm/Transforms/Instrumentation.h3
-rw-r--r--include/llvm/Transforms/RSProfiling.h42
-rw-r--r--include/llvm/Transforms/Scalar.h35
-rw-r--r--include/llvm/Transforms/Utils/AddrModeMatcher.h8
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h26
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h14
-rw-r--r--include/llvm/Transforms/Utils/Local.h14
-rw-r--r--include/llvm/Transforms/Utils/PromoteMemToReg.h3
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdater.h49
-rw-r--r--include/llvm/Transforms/Utils/ValueMapper.h23
-rw-r--r--include/llvm/TypeSymbolTable.h2
-rw-r--r--include/llvm/Use.h37
-rw-r--r--include/llvm/User.h41
-rw-r--r--include/llvm/Value.h16
-rw-r--r--include/llvm/ValueSymbolTable.h2
279 files changed, 11775 insertions, 4426 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index dfe4e0f49a..ca4138b825 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -246,6 +246,13 @@ namespace llvm {
static APFloat getSmallestNormalized(const fltSemantics &Sem,
bool Negative = false);
+ /// getAllOnesValue - Returns a float which is bitcasted from
+ /// an all one value int.
+ ///
+ /// \param BitWidth - Select float type
+ /// \param isIEEE - If 128 bit number, select between PPC and IEEE
+ static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false);
+
/// Profile - Used to insert APFloat objects, or objects that contain
/// APFloat objects, into FoldingSets.
void Profile(FoldingSetNodeID& NID) const;
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index d398f8e3f6..d1fd3e5034 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -275,12 +275,6 @@ public:
/// objects, into FoldingSets.
void Profile(FoldingSetNodeID& id) const;
- /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
- void Emit(Serializer& S) const;
-
- /// @brief Used by the Bitcode deserializer to deserialize APInts.
- void Read(Deserializer& D);
-
/// @}
/// @name Value Tests
/// @{
@@ -302,7 +296,7 @@ public:
/// @returns true if this APInt is positive.
/// @brief Determine if this APInt Value is positive.
bool isStrictlyPositive() const {
- return isNonNegative() && (*this) != 0;
+ return isNonNegative() && !!*this;
}
/// This checks to see if the value has all bits of the APInt are set or not.
@@ -330,15 +324,14 @@ public:
/// value for the APInt's bit width.
/// @brief Determine if this is the smallest unsigned value.
bool isMinValue() const {
- return countPopulation() == 0;
+ return !*this;
}
/// This checks to see if the value of this APInt is the minimum signed
/// value for the APInt's bit width.
/// @brief Determine if this is the smallest signed value.
bool isMinSignedValue() const {
- return BitWidth == 1 ? VAL == 1 :
- isNegative() && countPopulation() == 1;
+ return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2();
}
/// @brief Check if this APInt has an N-bits unsigned integer value.
@@ -349,9 +342,7 @@ public:
if (isSingleWord())
return isUIntN(N, VAL);
- APInt Tmp(N, getNumWords(), pVal);
- Tmp.zext(getBitWidth());
- return Tmp == (*this);
+ return APInt(N, getNumWords(), pVal).zext(getBitWidth()) == (*this);
}
/// @brief Check if this APInt has an N-bits signed integer value.
@@ -361,7 +352,11 @@ public:
}
/// @returns true if the argument APInt value is a power of two > 0.
- bool isPowerOf2() const;
+ bool isPowerOf2() const {
+ if (isSingleWord())
+ return isPowerOf2_64(VAL);
+ return countPopulationSlowCase() == 1;
+ }
/// isSignBit - Return true if this is the value returned by getSignBit.
bool isSignBit() const { return isMinSignedValue(); }
@@ -369,7 +364,7 @@ public:
/// This converts the APInt to a boolean value as a test against zero.
/// @brief Boolean conversion function.
bool getBoolValue() const {
- return *this != 0;
+ return !!*this;
}
/// getLimitedValue - If this value is smaller than the specified limit,
@@ -385,12 +380,14 @@ public:
/// @{
/// @brief Gets maximum unsigned value of APInt for specific bit width.
static APInt getMaxValue(unsigned numBits) {
- return APInt(numBits, 0).set();
+ return getAllOnesValue(numBits);
}
/// @brief Gets maximum signed value of APInt for a specific bit width.
static APInt getSignedMaxValue(unsigned numBits) {
- return APInt(numBits, 0).set().clear(numBits - 1);
+ APInt API = getAllOnesValue(numBits);
+ API.clearBit(numBits - 1);
+ return API;
}
/// @brief Gets minimum unsigned value of APInt for a specific bit width.
@@ -400,7 +397,9 @@ public:
/// @brief Gets minimum signed value of APInt for a specific bit width.
static APInt getSignedMinValue(unsigned numBits) {
- return APInt(numBits, 0).set(numBits - 1);
+ APInt API(numBits, 0);
+ API.setBit(numBits - 1);
+ return API;
}
/// getSignBit - This is just a wrapper function of getSignedMinValue(), and
@@ -413,7 +412,7 @@ public:
/// @returns the all-ones value for an APInt of the specified bit-width.
/// @brief Get the all-ones value.
static APInt getAllOnesValue(unsigned numBits) {
- return APInt(numBits, 0).set();
+ return APInt(numBits, -1ULL, true);
}
/// @returns the '0' value for an APInt of the specified bit-width.
@@ -432,6 +431,13 @@ public:
/// @returns the low "numBits" bits of this APInt.
APInt getLoBits(unsigned numBits) const;
+ /// getOneBitSet - Return an APInt with exactly one bit set in the result.
+ static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {
+ APInt Res(numBits, 0);
+ Res.setBit(BitNo);
+ return Res;
+ }
+
/// Constructs an APInt value that has a contiguous range of bits set. The
/// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other
/// bits will be zero. For example, with parameters(32, 0, 16) you would get
@@ -530,7 +536,7 @@ public:
/// @brief Unary bitwise complement operator.
APInt operator~() const {
APInt Result(*this);
- Result.flip();
+ Result.flipAllBits();
return Result;
}
@@ -1012,80 +1018,78 @@ public:
/// Truncate the APInt to a specified width. It is an error to specify a width
/// that is greater than or equal to the current width.
/// @brief Truncate to new width.
- APInt &trunc(unsigned width);
+ APInt trunc(unsigned width) const;
/// This operation sign extends the APInt to a new width. If the high order
/// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
/// It is an error to specify a width that is less than or equal to the
/// current width.
/// @brief Sign extend to a new width.
- APInt &sext(unsigned width);
+ APInt sext(unsigned width) const;
/// This operation zero extends the APInt to a new width. The high order bits
/// are filled with 0 bits. It is an error to specify a width that is less
/// than or equal to the current width.
/// @brief Zero extend to a new width.
- APInt &zext(unsigned width);
+ APInt zext(unsigned width) const;
/// Make this APInt have the bit width given by \p width. The value is sign
/// extended, truncated, or left alone to make it that width.
/// @brief Sign extend or truncate to width
- APInt &sextOrTrunc(unsigned width);
+ APInt sextOrTrunc(unsigned width) const;
/// Make this APInt have the bit width given by \p width. The value is zero
/// extended, truncated, or left alone to make it that width.
/// @brief Zero extend or truncate to width
- APInt &zextOrTrunc(unsigned width);
+ APInt zextOrTrunc(unsigned width) const;
/// @}
/// @name Bit Manipulation Operators
/// @{
/// @brief Set every bit to 1.
- APInt &set() {
- if (isSingleWord()) {
+ void setAllBits() {
+ if (isSingleWord())
VAL = -1ULL;
- return clearUnusedBits();
+ else {
+ // Set all the bits in all the words.
+ for (unsigned i = 0; i < getNumWords(); ++i)
+ pVal[i] = -1ULL;
}
-
- // Set all the bits in all the words.
- for (unsigned i = 0; i < getNumWords(); ++i)
- pVal[i] = -1ULL;
// Clear the unused ones
- return clearUnusedBits();
+ clearUnusedBits();
}
/// Set the given bit to 1 whose position is given as "bitPosition".
/// @brief Set a given bit to 1.
- APInt &set(unsigned bitPosition);
+ void setBit(unsigned bitPosition);
/// @brief Set every bit to 0.
- APInt &clear() {
+ void clearAllBits() {
if (isSingleWord())
VAL = 0;
else
memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
- return *this;
}
/// Set the given bit to 0 whose position is given as "bitPosition".
/// @brief Set a given bit to 0.
- APInt &clear(unsigned bitPosition);
+ void clearBit(unsigned bitPosition);
/// @brief Toggle every bit to its opposite value.
- APInt &flip() {
- if (isSingleWord()) {
+ void flipAllBits() {
+ if (isSingleWord())
VAL ^= -1ULL;
- return clearUnusedBits();
+ else {
+ for (unsigned i = 0; i < getNumWords(); ++i)
+ pVal[i] ^= -1ULL;
}
- for (unsigned i = 0; i < getNumWords(); ++i)
- pVal[i] ^= -1ULL;
- return clearUnusedBits();
+ clearUnusedBits();
}
/// Toggle a given bit to its opposite value whose position is given
/// as "bitPosition".
/// @brief Toggles a given bit to its opposite value.
- APInt& flip(unsigned bitPosition);
+ void flipBit(unsigned bitPosition);
/// @}
/// @name Value Characterization Functions
@@ -1189,6 +1193,12 @@ public:
/// @brief Count the number of leading one bits.
unsigned countLeadingOnes() const;
+ /// Computes the number of leading bits of this APInt that are equal to its
+ /// sign bit.
+ unsigned getNumSignBits() const {
+ return isNegative() ? countLeadingOnes() : countLeadingZeros();
+ }
+
/// countTrailingZeros - This function is an APInt version of the
/// countTrailingZeros_{32,64} functions in MathExtras.h. It counts
/// the number of zeros from the least significant bit to the first set bit.
@@ -1293,37 +1303,27 @@ public:
}
/// The conversion does not do a translation from double to integer, it just
- /// re-interprets the bits of the double. Note that it is valid to do this on
- /// any bit width but bits from V may get truncated.
+ /// re-interprets the bits of the double.
/// @brief Converts a double to APInt bits.
- APInt& doubleToBits(double V) {
+ static APInt doubleToBits(double V) {
union {
uint64_t I;
double D;
} T;
T.D = V;
- if (isSingleWord())
- VAL = T.I;
- else
- pVal[0] = T.I;
- return clearUnusedBits();
+ return APInt(sizeof T * CHAR_BIT, T.I);
}
/// The conversion does not do a translation from float to integer, it just
- /// re-interprets the bits of the float. Note that it is valid to do this on
- /// any bit width but bits from V may get truncated.
+ /// re-interprets the bits of the float.
/// @brief Converts a float to APInt bits.
- APInt& floatToBits(float V) {
+ static APInt floatToBits(float V) {
union {
unsigned I;
float F;
} T;
T.F = V;
- if (isSingleWord())
- VAL = T.I;
- else
- pVal[0] = T.I;
- return clearUnusedBits();
+ return APInt(sizeof T * CHAR_BIT, T.I);
}
/// @}
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index 1c9931c30f..54a7b601d1 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -68,20 +68,22 @@ public:
}
using APInt::toString;
- APSInt& extend(uint32_t width) {
+ APSInt trunc(uint32_t width) const {
+ return APSInt(APInt::trunc(width), IsUnsigned);
+ }
+
+ APSInt extend(uint32_t width) const {
if (IsUnsigned)
- zext(width);
+ return APSInt(zext(width), IsUnsigned);
else
- sext(width);
- return *this;
+ return APSInt(sext(width), IsUnsigned);
}
- APSInt& extOrTrunc(uint32_t width) {
+ APSInt extOrTrunc(uint32_t width) const {
if (IsUnsigned)
- zextOrTrunc(width);
+ return APSInt(zextOrTrunc(width), IsUnsigned);
else
- sextOrTrunc(width);
- return *this;
+ return APSInt(sextOrTrunc(width), IsUnsigned);
}
const APSInt &operator%=(const APSInt &RHS) {
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
new file mode 100644
index 0000000000..ebddb1287e
--- /dev/null
+++ b/include/llvm/ADT/ArrayRef.h
@@ -0,0 +1,137 @@
+//===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ARRAYREF_H
+#define LLVM_ADT_ARRAYREF_H
+
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+namespace llvm {
+ class APInt;
+
+ /// ArrayRef - Represent a constant reference to an array (0 or more elements
+ /// consecutively in memory), i.e. a start pointer and a length. It allows
+ /// various APIs to take consecutive elements easily and conveniently.
+ ///
+ /// This class does not own the underlying data, it is expected to be used in
+ /// situations where the data resides in some other buffer, whose lifetime
+ /// extends past that of the StringRef. For this reason, it is not in general
+ /// safe to store a ArrayRef.
+ ///
+ /// This is intended to be trivially copyable, so it should be passed by
+ /// value.
+ template<typename T>
+ class ArrayRef {
+ public:
+ typedef const T *iterator;
+ typedef const T *const_iterator;
+ typedef size_t size_type;
+
+ private:
+ /// The start of the array, in an external buffer.
+ const T *Data;
+
+ /// The number of elements.
+ size_t Length;
+
+ public:
+ /// @name Constructors
+ /// @{
+
+ /// Construct an empty ArrayRef.
+ /*implicit*/ ArrayRef() : Data(0), Length(0) {}
+
+ /// Construct an ArrayRef from a single element.
+ /*implicit*/ ArrayRef(const T &OneElt)
+ : Data(&OneElt), Length(1) {}
+
+ /// Construct an ArrayRef from a pointer and length.
+ /*implicit*/ ArrayRef(const T *data, size_t length)
+ : Data(data), Length(length) {}
+
+ /// Construct an ArrayRef from a SmallVector.
+ /*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec)
+ : Data(Vec.data()), Length(Vec.size()) {}
+
+ /// Construct an ArrayRef from a std::vector.
+ /*implicit*/ ArrayRef(const std::vector<T> &Vec)
+ : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
+
+ /// Construct an ArrayRef from a C array.
+ template <size_t N>
+ /*implicit*/ ArrayRef(const T (&Arr)[N])
+ : Data(Arr), Length(N) {}
+
+ /// @}
+ /// @name Simple Operations
+ /// @{
+
+ iterator begin() const { return Data; }
+ iterator end() const { return Data + Length; }
+
+ /// empty - Check if the array is empty.
+ bool empty() const { return Length == 0; }
+
+ const T *data() const { return Data; }
+
+ /// size - Get the array size.
+ size_t size() const { return Length; }
+
+ /// front - Get the first element.
+ const T &front() const {
+ assert(!empty());
+ return Data[0];
+ }
+
+ /// back - Get the last element.
+ const T &back() const {
+ assert(!empty());
+ return Data[Length-1];
+ }
+
+ /// slice(n) - Chop off the first N elements of the array.
+ ArrayRef<T> slice(unsigned N) {
+ assert(N <= size() && "Invalid specifier");
+ return ArrayRef<T>(data()+N, size()-N);
+ }
+
+ /// slice(n, m) - Chop off the first N elements of the array, and keep M
+ /// elements in the array.
+ ArrayRef<T> slice(unsigned N, unsigned M) {
+ assert(N+M <= size() && "Invalid specifier");
+ return ArrayRef<T>(data()+N, M);
+ }
+
+ /// @}
+ /// @name Operator Overloads
+ /// @{
+ const T &operator[](size_t Index) const {
+ assert(Index < Length && "Invalid index!");
+ return Data[Index];
+ }
+
+ /// @}
+ /// @name Expensive Operations
+ /// @{
+ std::vector<T> vec() const {
+ return std::vector<T>(Data, Data+Length);
+ }
+
+ /// @}
+ };
+
+ // ArrayRefs can be treated like a POD type.
+ template <typename T> struct isPodLike;
+ template <typename T> struct isPodLike<ArrayRef<T> > {
+ static const bool value = true;
+ };
+}
+
+#endif
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index 1940fd3900..ac1cf0c79a 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -18,6 +18,7 @@
#include <algorithm>
#include <cassert>
#include <climits>
+#include <cstdlib>
#include <cstring>
namespace llvm {
@@ -77,7 +78,7 @@ public:
/// bits are initialized to the specified value.
explicit BitVector(unsigned s, bool t = false) : Size(s) {
Capacity = NumBitWords(s);
- Bits = new BitWord[Capacity];
+ Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
init_words(Bits, Capacity, t);
if (t)
clear_unused_bits();
@@ -92,12 +93,12 @@ public:
}
Capacity = NumBitWords(RHS.size());
- Bits = new BitWord[Capacity];
- std::copy(RHS.Bits, &RHS.Bits[Capacity], Bits);
+ Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
+ std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
}
~BitVector() {
- delete[] Bits;
+ std::free(Bits);
}
/// empty - Tests whether there are no bits in this bitvector.
@@ -341,18 +342,18 @@ public:
unsigned RHSWords = NumBitWords(Size);
if (Size <= Capacity * BITWORD_SIZE) {
if (Size)
- std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits);
+ std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord));
clear_unused_bits();
return *this;
}
// Grow the bitvector to have enough elements.
Capacity = RHSWords;
- BitWord *NewBits = new BitWord[Capacity];
- std::copy(RHS.Bits, &RHS.Bits[RHSWords], NewBits);
+ BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
+ std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
// Destroy the old bits.
- delete[] Bits;
+ std::free(Bits);
Bits = NewBits;
return *this;
@@ -390,17 +391,8 @@ private:
}
void grow(unsigned NewSize) {
- unsigned OldCapacity = Capacity;
- Capacity = NumBitWords(NewSize);
- BitWord *NewBits = new BitWord[Capacity];
-
- // Copy the old bits over.
- if (OldCapacity != 0)
- std::copy(Bits, &Bits[OldCapacity], NewBits);
-
- // Destroy the old bits.
- delete[] Bits;
- Bits = NewBits;
+ Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
+ Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
clear_unused_bits();
}
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 06a1575da4..dd341c6a75 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -18,6 +18,7 @@
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/type_traits.h"
#include "llvm/ADT/DenseMapInfo.h"
+#include <algorithm>
#include <iterator>
#include <new>
#include <utility>
@@ -52,13 +53,13 @@ public:
CopyFrom(other);
}
- explicit DenseMap(unsigned NumInitBuckets = 64) {
+ explicit DenseMap(unsigned NumInitBuckets = 0) {
init(NumInitBuckets);
}
template<typename InputIt>
DenseMap(const InputIt &I, const InputIt &E) {
- init(64);
+ init(NextPowerOf2(std::distance(I, E)));
insert(I, E);
}
@@ -97,7 +98,10 @@ public:
unsigned size() const { return NumEntries; }
/// Grow the densemap so that it has at least Size buckets. Does not shrink
- void resize(size_t Size) { grow(Size); }
+ void resize(size_t Size) {
+ if (Size > NumBuckets)
+ grow(Size);
+ }
void clear() {
if (NumEntries == 0 && NumTombstones == 0) return;
@@ -251,19 +255,25 @@ private:
#endif
operator delete(Buckets);
}
- Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) *
- other.NumBuckets));
+
+ NumBuckets = other.NumBuckets;
+
+ if (NumBuckets == 0) {
+ Buckets = 0;
+ return;
+ }
+
+ Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
if (isPodLike<KeyInfoT>::value && isPodLike<ValueInfoT>::value)
- memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT));
+ memcpy(Buckets, other.Buckets, NumBuckets * sizeof(BucketT));
else
- for (size_t i = 0; i < other.NumBuckets; ++i) {
+ for (size_t i = 0; i < NumBuckets; ++i) {
new (&Buckets[i].first) KeyT(other.Buckets[i].first);
if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) &&
!KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey()))
new (&Buckets[i].second) ValueT(other.Buckets[i].second);
}
- NumBuckets = other.NumBuckets;
}
BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
@@ -312,6 +322,11 @@ private:
unsigned ProbeAmt = 1;
BucketT *BucketsPtr = Buckets;
+ if (NumBuckets == 0) {
+ FoundBucket = 0;
+ return false;
+ }
+
// FoundTombstone - Keep track of whether we find a tombstone while probing.
BucketT *FoundTombstone = 0;
const KeyT EmptyKey = getEmptyKey();
@@ -353,6 +368,12 @@ private:
NumEntries = 0;
NumTombstones = 0;
NumBuckets = InitBuckets;
+
+ if (InitBuckets == 0) {
+ Buckets = 0;
+ return;
+ }
+
assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 &&
"# initial buckets must be a power of two!");
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets));
@@ -366,6 +387,9 @@ private:
unsigned OldNumBuckets = NumBuckets;
BucketT *OldBuckets = Buckets;
+ if (NumBuckets < 64)
+ NumBuckets = 64;
+
// Double the number of buckets.
while (NumBuckets < AtLeast)
NumBuckets <<= 1;
@@ -385,7 +409,7 @@ private:
// Insert the key/value into the new table.
BucketT *DestBucket;
bool FoundVal = LookupBucketFor(B->first, DestBucket);
- FoundVal = FoundVal; // silence warning.
+ (void)FoundVal; // silence warning.
assert(!FoundVal && "Key already in new map?");
DestBucket->first = B->first;
new (&DestBucket->second) ValueT(B->second);
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
index 00bcf64a2f..67321f5398 100644
--- a/include/llvm/ADT/DenseSet.h
+++ b/include/llvm/ADT/DenseSet.h
@@ -33,6 +33,9 @@ public:
bool empty() const { return TheMap.empty(); }
unsigned size() const { return TheMap.size(); }
+ /// Grow the denseset so that it has at least Size buckets. Does not shrink
+ void resize(size_t Size) { TheMap.resize(Size); }
+
void clear() {
TheMap.clear();
}
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
index b9e5cbdf8c..dd13a2c020 100644
--- a/include/llvm/ADT/DepthFirstIterator.h
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -143,8 +143,7 @@ public:
static inline _Self end(const GraphT& G, SetType &S) { return _Self(S); }
inline bool operator==(const _Self& x) const {
- return VisitStack.size() == x.VisitStack.size() &&
- VisitStack == x.VisitStack;
+ return VisitStack == x.VisitStack;
}
inline bool operator!=(const _Self& x) const { return !operator==(x); }
diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h
index 85910f8939..ec981cd8db 100644
--- a/include/llvm/ADT/EquivalenceClasses.h
+++ b/include/llvm/ADT/EquivalenceClasses.h
@@ -15,7 +15,7 @@
#ifndef LLVM_ADT_EQUIVALENCECLASSES_H
#define LLVM_ADT_EQUIVALENCECLASSES_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <set>
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
index 662b5e2735..879dbd05e1 100644
--- a/include/llvm/ADT/FoldingSet.h
+++ b/include/llvm/ADT/FoldingSet.h
@@ -16,7 +16,7 @@
#ifndef LLVM_ADT_FOLDINGSET_H
#define LLVM_ADT_FOLDINGSET_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
diff --git a/include/llvm/ADT/ImmutableIntervalMap.h b/include/llvm/ADT/ImmutableIntervalMap.h
index 968ce15277..0d8fcf3433 100644
--- a/include/llvm/ADT/ImmutableIntervalMap.h
+++ b/include/llvm/ADT/ImmutableIntervalMap.h
@@ -94,7 +94,7 @@ public:
: ImutAVLFactory<ImutInfo>(Alloc) {}
TreeTy *Add(TreeTy *T, value_type_ref V) {
- T = Add_internal(V,T);
+ T = add_internal(V,T);
this->MarkImmutable(T);
return T;
}
@@ -103,20 +103,20 @@ public:
if (!T)
return NULL;
- key_type_ref CurrentKey = ImutInfo::KeyOfValue(this->Value(T));
+ key_type_ref CurrentKey = ImutInfo::KeyOfValue(this->getValue(T));
if (ImutInfo::isContainedIn(K, CurrentKey))
return T;
else if (ImutInfo::isLess(K, CurrentKey))
- return Find(this->Left(T), K);
+ return Find(this->getLeft(T), K);
else
- return Find(this->Right(T), K);
+ return Find(this->getRight(T), K);
}
private:
- TreeTy *Add_internal(value_type_ref V, TreeTy *T) {
+ TreeTy *add_internal(value_type_ref V, TreeTy *T) {
key_type_ref K = ImutInfo::KeyOfValue(V);
- T = RemoveAllOverlaps(T, K);
+ T = removeAllOverlaps(T, K);
if (this->isEmpty(T))
return this->CreateNode(NULL, V, NULL);
@@ -125,38 +125,38 @@ private:
key_type_ref KCurrent = ImutInfo::KeyOfValue(this->Value(T));
if (ImutInfo::isLess(K, KCurrent))
- return this->Balance(Add_internal(V, this->Left(T)), this->Value(T),
+ return this->Balance(add_internal(V, this->Left(T)), this->Value(T),
this->Right(T));
else
return this->Balance(this->Left(T), this->Value(T),
- Add_internal(V, this->Right(T)));
+ add_internal(V, this->Right(T)));
}
// Remove all overlaps from T.
- TreeTy *RemoveAllOverlaps(TreeTy *T, key_type_ref K) {
+ TreeTy *removeAllOverlaps(TreeTy *T, key_type_ref K) {
bool Changed;
do {
Changed = false;
- T = RemoveOverlap(T, K, Changed);
- this->MarkImmutable(T);
+ T = removeOverlap(T, K, Changed);
+ this->markImmutable(T);
} while (Changed);
return T;
}
// Remove one overlap from T.
- TreeTy *RemoveOverlap(TreeTy *T, key_type_ref K, bool &Changed) {
+ TreeTy *removeOverlap(TreeTy *T, key_type_ref K, bool &Changed) {
if (!T)
return NULL;
Interval CurrentK = ImutInfo::KeyOfValue(this->Value(T));
// If current key does not overlap the inserted key.
if (CurrentK.getStart() > K.getEnd())
- return this->Balance(RemoveOverlap(this->Left(T), K, Changed),
+ return this->Balance(removeOverlap(this->Left(T), K, Changed),
this->Value(T), this->Right(T));
else if (CurrentK.getEnd() < K.getStart())
return this->Balance(this->Left(T), this->Value(T),
- RemoveOverlap(this->Right(T), K, Changed));
+ removeOverlap(this->Right(T), K, Changed));
// Current key overlaps with the inserted key.
// Remove the current key.
@@ -167,18 +167,18 @@ private:
if (CurrentK.getStart() < K.getStart()) {
if (CurrentK.getEnd() <= K.getEnd()) {
Interval NewK(CurrentK.getStart(), K.getStart()-1);
- return Add_internal(std::make_pair(NewK, OldData), T);
+ return add_internal(std::make_pair(NewK, OldData), T);
} else {
Interval NewK1(CurrentK.getStart(), K.getStart()-1);
- T = Add_internal(std::make_pair(NewK1, OldData), T);
+ T = add_internal(std::make_pair(NewK1, OldData), T);
Interval NewK2(K.getEnd()+1, CurrentK.getEnd());
- return Add_internal(std::make_pair(NewK2, OldData), T);
+ return add_internal(std::make_pair(NewK2, OldData), T);
}
} else {
if (CurrentK.getEnd() > K.getEnd()) {
Interval NewK(K.getEnd()+1, CurrentK.getEnd());
- return Add_internal(std::make_pair(NewK, OldData), T);
+ return add_internal(std::make_pair(NewK, OldData), T);
} else
return T;
}
@@ -209,22 +209,22 @@ public:
public:
Factory(BumpPtrAllocator& Alloc) : F(Alloc) {}
- ImmutableIntervalMap GetEmptyMap() {
- return ImmutableIntervalMap(F.GetEmptyTree());
+ ImmutableIntervalMap getEmptyMap() {
+ return ImmutableIntervalMap(F.getEmptyTree());
}
- ImmutableIntervalMap Add(ImmutableIntervalMap Old,
+ ImmutableIntervalMap add(ImmutableIntervalMap Old,
key_type_ref K, data_type_ref D) {
- TreeTy *T = F.Add(Old.Root, std::make_pair<key_type, data_type>(K, D));
- return ImmutableIntervalMap(F.GetCanonicalTree(T));
+ TreeTy *T = F.add(Old.Root, std::pair<key_type, data_type>(K, D));
+ return ImmutableIntervalMap(F.getCanonicalTree(T));
}
- ImmutableIntervalMap Remove(ImmutableIntervalMap Old, key_type_ref K) {
- TreeTy *T = F.Remove(Old.Root, K);
- return ImmutableIntervalMap(F.GetCanonicalTree(T));
+ ImmutableIntervalMap remove(ImmutableIntervalMap Old, key_type_ref K) {
+ TreeTy *T = F.remove(Old.Root, K);
+ return ImmutableIntervalMap(F.getCanonicalTree(T));
}
- data_type *Lookup(ImmutableIntervalMap M, key_type_ref K) {
+ data_type *lookup(ImmutableIntervalMap M, key_type_ref K) {
TreeTy *T = F.Find(M.getRoot(), K);
if (T)
return &T->getValue().second;
diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h
index 7757c08770..714355b951 100644
--- a/include/llvm/ADT/ImmutableList.h
+++ b/include/llvm/ADT/ImmutableList.h
@@ -16,7 +16,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
@@ -156,7 +156,7 @@ public:
if (ownsAllocator()) delete &getAllocator();
}
- ImmutableList<T> Concat(const T& Head, ImmutableList<T> Tail) {
+ ImmutableList<T> concat(const T& Head, ImmutableList<T> Tail) {
// Profile the new list to see if it already exists in our cache.
FoldingSetNodeID ID;
void* InsertPos;
@@ -178,16 +178,16 @@ public:
return L;
}
- ImmutableList<T> Add(const T& D, ImmutableList<T> L) {
- return Concat(D, L);
+ ImmutableList<T> add(const T& D, ImmutableList<T> L) {
+ return concat(D, L);
}
- ImmutableList<T> GetEmptyList() const {
+ ImmutableList<T> getEmptyList() const {
return ImmutableList<T>(0);
}
- ImmutableList<T> Create(const T& X) {
- return Concat(X, GetEmptyList());
+ ImmutableList<T> create(const T& X) {
+ return Concat(X, getEmptyList());
}
};
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
index 8af128ef3b..d6cce7ccfa 100644
--- a/include/llvm/ADT/ImmutableMap.h
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -76,7 +76,23 @@ public:
/// should use a Factory object to create maps instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
- explicit ImmutableMap(const TreeTy* R) : Root(const_cast<TreeTy*>(R)) {}
+ explicit ImmutableMap(const TreeTy* R) : Root(const_cast<TreeTy*>(R)) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableMap(const ImmutableMap &X) : Root(X.Root) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableMap &operator=(const ImmutableMap &X) {
+ if (Root != X.Root) {
+ if (X.Root) { X.Root->retain(); }
+ if (Root) { Root->release(); }
+ Root = X.Root;
+ }
+ return *this;
+ }
+ ~ImmutableMap() {
+ if (Root) { Root->release(); }
+ }
class Factory {
typename TreeTy::Factory F;
@@ -89,16 +105,16 @@ public:
Factory(BumpPtrAllocator& Alloc, bool canonicalize = true)
: F(Alloc), Canonicalize(canonicalize) {}
- ImmutableMap GetEmptyMap() { return ImmutableMap(F.GetEmptyTree()); }
+ ImmutableMap getEmptyMap() { return ImmutableMap(F.getEmptyTree()); }
- ImmutableMap Add(ImmutableMap Old, key_type_ref K, data_type_ref D) {
- TreeTy *T = F.Add(Old.Root, std::make_pair<key_type,data_type>(K,D));
- return ImmutableMap(Canonicalize ? F.GetCanonicalTree(T): T);
+ ImmutableMap add(ImmutableMap Old, key_type_ref K, data_type_ref D) {
+ TreeTy *T = F.add(Old.Root, std::pair<key_type,data_type>(K,D));
+ return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
}
- ImmutableMap Remove(ImmutableMap Old, key_type_ref K) {
- TreeTy *T = F.Remove(Old.Root,K);
- return ImmutableMap(Canonicalize ? F.GetCanonicalTree(T): T);
+ ImmutableMap remove(ImmutableMap Old, key_type_ref K) {
+ TreeTy *T = F.remove(Old.Root,K);
+ return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
}
private:
@@ -110,15 +126,30 @@ public:
return Root ? Root->contains(K) : false;
}
- bool operator==(ImmutableMap RHS) const {
+ bool operator==(const ImmutableMap &RHS) const {
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
}
- bool operator!=(ImmutableMap RHS) const {
+ bool operator!=(const ImmutableMap &RHS) const {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
- TreeTy* getRoot() const { return Root; }
+ TreeTy *getRoot() const {
+ if (Root) { Root->retain(); }
+ return Root;
+ }
+
+ TreeTy *getRootWithoutRetain() const {
+ return Root;
+ }
+
+ void manualRetain() {
+ if (Root) Root->retain();
+ }
+
+ void manualRelease() {
+ if (Root) Root->release();
+ }
bool isEmpty() const { return !Root; }
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
index 70c3caf2a0..3ca910ce94 100644
--- a/include/llvm/ADT/ImmutableSet.h
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -15,10 +15,13 @@
#define LLVM_ADT_IMSET_H
#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <functional>
+#include <vector>
+#include <stdio.h>
namespace llvm {
@@ -32,7 +35,7 @@ template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
template <typename ImutInfo> class ImutAVLTreeGenericIterator;
template <typename ImutInfo >
-class ImutAVLTree : public FoldingSetNode {
+class ImutAVLTree {
public:
typedef typename ImutInfo::key_type_ref key_type_ref;
typedef typename ImutInfo::value_type value_type;
@@ -43,7 +46,6 @@ public:
friend class ImutIntervalAVLFactory<ImutInfo>;
friend class ImutAVLTreeGenericIterator<ImutInfo>;
- friend class FoldingSet<ImutAVLTree>;
typedef ImutAVLTreeInOrderIterator<ImutInfo> iterator;
@@ -51,29 +53,27 @@ public:
// Public Interface.
//===----------------------------------------------------===//
- /// getLeft - Returns a pointer to the left subtree. This value
+ /// Return a pointer to the left subtree. This value
/// is NULL if there is no left subtree.
- ImutAVLTree *getLeft() const { return Left; }
+ ImutAVLTree *getLeft() const { return left; }
- /// getRight - Returns a pointer to the right subtree. This value is
+ /// Return a pointer to the right subtree. This value is
/// NULL if there is no right subtree.
- ImutAVLTree *getRight() const { return Right; }
+ ImutAVLTree *getRight() const { return right; }
/// getHeight - Returns the height of the tree. A tree with no subtrees
/// has a height of 1.
- unsigned getHeight() const { return Height; }
+ unsigned getHeight() const { return height; }
/// getValue - Returns the data value associated with the tree node.
- const value_type& getValue() const { return Value; }
+ const value_type& getValue() const { return value; }
/// find - Finds the subtree associated with the specified key value.
/// This method returns NULL if no matching subtree is found.
ImutAVLTree* find(key_type_ref K) {
ImutAVLTree *T = this;
-
while (T) {
key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue());
-
if (ImutInfo::isEqual(K,CurrentKey))
return T;
else if (ImutInfo::isLess(K,CurrentKey))
@@ -81,7 +81,6 @@ public:
else
T = T->getRight();
}
-
return NULL;
}
@@ -90,7 +89,7 @@ public:
ImutAVLTree* getMaxElement() {
ImutAVLTree *T = this;
ImutAVLTree *Right = T->getRight();
- while (Right) { T = Right; Right = T->getRight(); }
+ while (Right) { T = right; right = T->getRight(); }
return T;
}
@@ -98,10 +97,10 @@ public:
/// both leaves and non-leaf nodes.
unsigned size() const {
unsigned n = 1;
-
- if (const ImutAVLTree* L = getLeft()) n += L->size();
- if (const ImutAVLTree* R = getRight()) n += R->size();
-
+ if (const ImutAVLTree* L = getLeft())
+ n += L->size();
+ if (const ImutAVLTree* R = getRight())
+ n += R->size();
return n;
}
@@ -114,7 +113,7 @@ public:
/// inorder traversal.
iterator end() const { return iterator(); }
- bool ElementEqual(value_type_ref V) const {
+ bool isElementEqual(value_type_ref V) const {
// Compare the keys.
if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(getValue()),
ImutInfo::KeyOfValue(V)))
@@ -128,8 +127,8 @@ public:
return true;
}
- bool ElementEqual(const ImutAVLTree* RHS) const {
- return ElementEqual(RHS->getValue());
+ bool isElementEqual(const ImutAVLTree* RHS) const {
+ return isElementEqual(RHS->getValue());
}
/// isEqual - Compares two trees for structural equality and returns true
@@ -144,12 +143,12 @@ public:
while (LItr != LEnd && RItr != REnd) {
if (*LItr == *RItr) {
- LItr.SkipSubTree();
- RItr.SkipSubTree();
+ LItr.skipSubTree();
+ RItr.skipSubTree();
continue;
}
- if (!LItr->ElementEqual(*RItr))
+ if (!LItr->isElementEqual(*RItr))
return false;
++LItr;
@@ -173,22 +172,24 @@ public:
/// Nodes are visited using an inorder traversal.
template <typename Callback>
void foreach(Callback& C) {
- if (ImutAVLTree* L = getLeft()) L->foreach(C);
+ if (ImutAVLTree* L = getLeft())
+ L->foreach(C);
- C(Value);
+ C(value);
- if (ImutAVLTree* R = getRight()) R->foreach(C);
+ if (ImutAVLTree* R = getRight())
+ R->foreach(C);
}
- /// verify - A utility method that checks that the balancing and
+ /// validateTree - A utility method that checks that the balancing and
/// ordering invariants of the tree are satisifed. It is a recursive
/// method that returns the height of the tree, which is then consumed
- /// by the enclosing verify call. External callers should ignore the
+ /// by the enclosing validateTree call. External callers should ignore the
/// return value. An invalid tree will cause an assertion to fire in
/// a debug build.
- unsigned verify() const {
- unsigned HL = getLeft() ? getLeft()->verify() : 0;
- unsigned HR = getRight() ? getRight()->verify() : 0;
+ unsigned validateTree() const {
+ unsigned HL = getLeft() ? getLeft()->validateTree() : 0;
+ unsigned HR = getRight() ? getRight()->validateTree() : 0;
(void) HL;
(void) HR;
@@ -198,37 +199,39 @@ public:
assert((HL > HR ? HL-HR : HR-HL) <= 2
&& "Balancing invariant violated");
- assert(!getLeft()
- || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
- ImutInfo::KeyOfValue(getValue()))
- && "Value in left child is not less that current value");
+ assert((!getLeft() ||
+ ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
+ ImutInfo::KeyOfValue(getValue()))) &&
+ "Value in left child is not less that current value");
- assert(!getRight()
- || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
- ImutInfo::KeyOfValue(getRight()->getValue()))
- && "Current value is not less that value of right child");
+ assert(!(getRight() ||
+ ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
+ ImutInfo::KeyOfValue(getRight()->getValue()))) &&
+ "Current value is not less that value of right child");
return getHeight();
}
- /// Profile - Profiling for ImutAVLTree.
- void Profile(llvm::FoldingSetNodeID& ID) {
- ID.AddInteger(ComputeDigest());
- }
-
//===----------------------------------------------------===//
- // Internal Values.
+ // Internal values.
//===----------------------------------------------------===//
private:
- ImutAVLTree* Left;
- ImutAVLTree* Right;
- unsigned Height : 28;
- unsigned Mutable : 1;
- unsigned CachedDigest : 1;
- value_type Value;
- uint32_t Digest;
+ Factory *factory;
+ ImutAVLTree *left;
+ ImutAVLTree *right;
+ ImutAVLTree *prev;
+ ImutAVLTree *next;
+
+ unsigned height : 28;
+ unsigned IsMutable : 1;
+ unsigned IsDigestCached : 1;
+ unsigned IsCanonicalized : 1;
+
+ value_type value;
+ uint32_t digest;
+ uint32_t refCount;
//===----------------------------------------------------===//
// Internal methods (node manipulation; used by Factory).
@@ -237,10 +240,15 @@ private:
private:
/// ImutAVLTree - Internal constructor that is only called by
/// ImutAVLFactory.
- ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v,
+ ImutAVLTree(Factory *f, ImutAVLTree* l, ImutAVLTree* r, value_type_ref v,
unsigned height)
- : Left(l), Right(r), Height(height), Mutable(true), CachedDigest(false),
- Value(v), Digest(0) {}
+ : factory(f), left(l), right(r), prev(0), next(0), height(height),
+ IsMutable(true), IsDigestCached(false), IsCanonicalized(0),
+ value(v), digest(0), refCount(0)
+ {
+ if (left) left->retain();
+ if (right) right->retain();
+ }
/// isMutable - Returns true if the left and right subtree references
/// (as well as height) can be changed. If this method returns false,
@@ -248,11 +256,11 @@ private:
/// object should always have this method return true. Further, if this
/// method returns false for an instance of ImutAVLTree, all subtrees
/// will also have this method return false. The converse is not true.
- bool isMutable() const { return Mutable; }
+ bool isMutable() const { return IsMutable; }
/// hasCachedDigest - Returns true if the digest for this tree is cached.
/// This can only be true if the tree is immutable.
- bool hasCachedDigest() const { return CachedDigest; }
+ bool hasCachedDigest() const { return IsDigestCached; }
//===----------------------------------------------------===//
// Mutating operations. A tree root can be manipulated as
@@ -265,51 +273,32 @@ private:
// immutable.
//===----------------------------------------------------===//
- /// MarkImmutable - Clears the mutable flag for a tree. After this happens,
+ /// markImmutable - Clears the mutable flag for a tree. After this happens,
/// it is an error to call setLeft(), setRight(), and setHeight().
- void MarkImmutable() {
+ void markImmutable() {
assert(isMutable() && "Mutable flag already removed.");
- Mutable = false;
+ IsMutable = false;
}
- /// MarkedCachedDigest - Clears the NoCachedDigest flag for a tree.
- void MarkedCachedDigest() {
+ /// markedCachedDigest - Clears the NoCachedDigest flag for a tree.
+ void markedCachedDigest() {
assert(!hasCachedDigest() && "NoCachedDigest flag already removed.");
- CachedDigest = true;
- }
-
- /// setLeft - Changes the reference of the left subtree. Used internally
- /// by ImutAVLFactory.
- void setLeft(ImutAVLTree* NewLeft) {
- assert(isMutable() &&
- "Only a mutable tree can have its left subtree changed.");
- Left = NewLeft;
- CachedDigest = false;
- }
-
- /// setRight - Changes the reference of the right subtree. Used internally
- /// by ImutAVLFactory.
- void setRight(ImutAVLTree* NewRight) {
- assert(isMutable() &&
- "Only a mutable tree can have its right subtree changed.");
-
- Right = NewRight;
- CachedDigest = false;
+ IsDigestCached = true;
}
/// setHeight - Changes the height of the tree. Used internally by
/// ImutAVLFactory.
void setHeight(unsigned h) {
assert(isMutable() && "Only a mutable tree can have its height changed.");
- Height = h;
+ height = h;
}
static inline
- uint32_t ComputeDigest(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
+ uint32_t computeDigest(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
uint32_t digest = 0;
if (L)
- digest += L->ComputeDigest();
+ digest += L->computeDigest();
// Compute digest of stored data.
FoldingSetNodeID ID;
@@ -317,22 +306,54 @@ private:
digest += ID.ComputeHash();
if (R)
- digest += R->ComputeDigest();
+ digest += R->computeDigest();
return digest;
}
- inline uint32_t ComputeDigest() {
+ inline uint32_t computeDigest() {
// Check the lowest bit to determine if digest has actually been
// pre-computed.
if (hasCachedDigest())
- return Digest;
+ return digest;
- uint32_t X = ComputeDigest(getLeft(), getRight(), getValue());
- Digest = X;
- MarkedCachedDigest();
+ uint32_t X = computeDigest(getLeft(), getRight(), getValue());
+ digest = X;
+ markedCachedDigest();
return X;
}
+
+ //===----------------------------------------------------===//
+ // Reference count operations.
+ //===----------------------------------------------------===//
+
+public:
+ void retain() { ++refCount; }
+ void release() {
+ assert(refCount > 0);
+ if (--refCount == 0)
+ destroy();
+ }
+ void destroy() {
+ if (left)
+ left->release();
+ if (right)
+ right->release();
+ if (IsCanonicalized) {
+ if (next)
+ next->prev = prev;
+
+ if (prev)
+ prev->next = next;
+ else
+ factory->Cache[computeDigest()] = next;
+ }
+
+ // We need to clear the mutability bit in case we are
+ // destroying the node as part of a sweep in ImutAVLFactory::recoverNodes().
+ IsMutable = false;
+ factory->freeNodes.push_back(this);
+ }
};
//===----------------------------------------------------------------------===//
@@ -341,14 +362,17 @@ private:
template <typename ImutInfo >
class ImutAVLFactory {
+ friend class ImutAVLTree<ImutInfo>;
typedef ImutAVLTree<ImutInfo> TreeTy;
typedef typename TreeTy::value_type_ref value_type_ref;
typedef typename TreeTy::key_type_ref key_type_ref;
- typedef FoldingSet<TreeTy> CacheTy;
+ typedef DenseMap<unsigned, TreeTy*> CacheTy;
CacheTy Cache;
uintptr_t Allocator;
+ std::vector<TreeTy*> createdNodes;
+ std::vector<TreeTy*> freeNodes;
bool ownsAllocator() const {
return Allocator & 0x1 ? false : true;
@@ -373,55 +397,56 @@ public:
if (ownsAllocator()) delete &getAllocator();
}
- TreeTy* Add(TreeTy* T, value_type_ref V) {
- T = Add_internal(V,T);
- MarkImmutable(T);
+ TreeTy* add(TreeTy* T, value_type_ref V) {
+ T = add_internal(V,T);
+ markImmutable(T);
+ recoverNodes();
return T;
}
- TreeTy* Remove(TreeTy* T, key_type_ref V) {
- T = Remove_internal(V,T);
- MarkImmutable(T);
+ TreeTy* remove(TreeTy* T, key_type_ref V) {
+ T = remove_internal(V,T);
+ markImmutable(T);
+ recoverNodes();
return T;
}
- TreeTy* GetEmptyTree() const { return NULL; }
+ TreeTy* getEmptyTree() const { return NULL; }
+protected:
+
//===--------------------------------------------------===//
// A bunch of quick helper functions used for reasoning
// about the properties of trees and their children.
// These have succinct names so that the balancing code
// is as terse (and readable) as possible.
//===--------------------------------------------------===//
-protected:
- bool isEmpty(TreeTy* T) const { return !T; }
- unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; }
- TreeTy* Left(TreeTy* T) const { return T->getLeft(); }
- TreeTy* Right(TreeTy* T) const { return T->getRight(); }
- value_type_ref Value(TreeTy* T) const { return T->Value; }
+ bool isEmpty(TreeTy* T) const { return !T; }
+ unsigned getHeight(TreeTy* T) const { return T ? T->getHeight() : 0; }
+ TreeTy* getLeft(TreeTy* T) const { return T->getLeft(); }
+ TreeTy* getRight(TreeTy* T) const { return T->getRight(); }
+ value_type_ref getValue(TreeTy* T) const { return T->value; }
- unsigned IncrementHeight(TreeTy* L, TreeTy* R) const {
- unsigned hl = Height(L);
- unsigned hr = Height(R);
+ unsigned incrementHeight(TreeTy* L, TreeTy* R) const {
+ unsigned hl = getHeight(L);
+ unsigned hr = getHeight(R);
return (hl > hr ? hl : hr) + 1;
}
- static bool CompareTreeWithSection(TreeTy* T,
+ static bool compareTreeWithSection(TreeTy* T,
typename TreeTy::iterator& TI,
typename TreeTy::iterator& TE) {
-
typename TreeTy::iterator I = T->begin(), E = T->end();
-
- for ( ; I!=E ; ++I, ++TI)
- if (TI == TE || !I->ElementEqual(*TI))
+ for ( ; I!=E ; ++I, ++TI) {
+ if (TI == TE || !I->isElementEqual(*TI))
return false;
-
+ }
return true;
}
//===--------------------------------------------------===//
- // "CreateNode" is used to generate new tree roots that link
+ // "createNode" is used to generate new tree roots that link
// to other trees. The functon may also simply move links
// in an existing root if that root is still marked mutable.
// This is necessary because otherwise our balancing code
@@ -430,181 +455,188 @@ protected:
// returned to the caller.
//===--------------------------------------------------===//
- TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) {
+ TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
BumpPtrAllocator& A = getAllocator();
- TreeTy* T = (TreeTy*) A.Allocate<TreeTy>();
- new (T) TreeTy(L, R, V, IncrementHeight(L,R));
+ TreeTy* T;
+ if (!freeNodes.empty()) {
+ T = freeNodes.back();
+ freeNodes.pop_back();
+ assert(T != L);
+ assert(T != R);
+ }
+ else {
+ T = (TreeTy*) A.Allocate<TreeTy>();
+ }
+ new (T) TreeTy(this, L, R, V, incrementHeight(L,R));
+ createdNodes.push_back(T);
return T;
}
- TreeTy* CreateNode(TreeTy* L, TreeTy* OldTree, TreeTy* R) {
- assert(!isEmpty(OldTree));
+ TreeTy* createNode(TreeTy* newLeft, TreeTy* oldTree, TreeTy* newRight) {
+ return createNode(newLeft, getValue(oldTree), newRight);
+ }
- if (OldTree->isMutable()) {
- OldTree->setLeft(L);
- OldTree->setRight(R);
- OldTree->setHeight(IncrementHeight(L, R));
- return OldTree;
+ void recoverNodes() {
+ for (unsigned i = 0, n = createdNodes.size(); i < n; ++i) {
+ TreeTy *N = createdNodes[i];
+ if (N->isMutable() && N->refCount == 0)
+ N->destroy();
}
- else
- return CreateNode(L, Value(OldTree), R);
+ createdNodes.clear();
}
- /// Balance - Used by Add_internal and Remove_internal to
+ /// balanceTree - Used by add_internal and remove_internal to
/// balance a newly created tree.
- TreeTy* Balance(TreeTy* L, value_type_ref V, TreeTy* R) {
-
- unsigned hl = Height(L);
- unsigned hr = Height(R);
+ TreeTy* balanceTree(TreeTy* L, value_type_ref V, TreeTy* R) {
+ unsigned hl = getHeight(L);
+ unsigned hr = getHeight(R);
if (hl > hr + 2) {
assert(!isEmpty(L) && "Left tree cannot be empty to have a height >= 2");
- TreeTy* LL = Left(L);
- TreeTy* LR = Right(L);
+ TreeTy *LL = getLeft(L);
+ TreeTy *LR = getRight(L);
- if (Height(LL) >= Height(LR))
- return CreateNode(LL, L, CreateNode(LR,V,R));
+ if (getHeight(LL) >= getHeight(LR))
+ return createNode(LL, L, createNode(LR,V,R));
assert(!isEmpty(LR) && "LR cannot be empty because it has a height >= 1");
- TreeTy* LRL = Left(LR);
- TreeTy* LRR = Right(LR);
+ TreeTy *LRL = getLeft(LR);
+ TreeTy *LRR = getRight(LR);
- return CreateNode(CreateNode(LL,L,LRL), LR, CreateNode(LRR,V,R));
+ return createNode(createNode(LL,L,LRL), LR, createNode(LRR,V,R));
}
else if (hr > hl + 2) {
assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2");
- TreeTy* RL = Left(R);
- TreeTy* RR = Right(R);
+ TreeTy *RL = getLeft(R);
+ TreeTy *RR = getRight(R);
- if (Height(RR) >= Height(RL))
- return CreateNode(CreateNode(L,V,RL), R, RR);
+ if (getHeight(RR) >= getHeight(RL))
+ return createNode(createNode(L,V,RL), R, RR);
assert(!isEmpty(RL) && "RL cannot be empty because it has a height >= 1");
- TreeTy* RLL = Left(RL);
- TreeTy* RLR = Right(RL);
+ TreeTy *RLL = getLeft(RL);
+ TreeTy *RLR = getRight(RL);
- return CreateNode(CreateNode(L,V,RLL), RL, CreateNode(RLR,R,RR));
+ return createNode(createNode(L,V,RLL), RL, createNode(RLR,R,RR));
}
else
- return CreateNode(L,V,R);
+ return createNode(L,V,R);
}
- /// Add_internal - Creates a new tree that includes the specified
+ /// add_internal - Creates a new tree that includes the specified
/// data and the data from the original tree. If the original tree
/// already contained the data item, the original tree is returned.
- TreeTy* Add_internal(value_type_ref V, TreeTy* T) {
+ TreeTy* add_internal(value_type_ref V, TreeTy* T) {
if (isEmpty(T))
- return CreateNode(T, V, T);
-
+ return createNode(T, V, T);
assert(!T->isMutable());
key_type_ref K = ImutInfo::KeyOfValue(V);
- key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
+ key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T));
if (ImutInfo::isEqual(K,KCurrent))
- return CreateNode(Left(T), V, Right(T));
+ return createNode(getLeft(T), V, getRight(T));
else if (ImutInfo::isLess(K,KCurrent))
- return Balance(Add_internal(V,Left(T)), Value(T), Right(T));
+ return balanceTree(add_internal(V, getLeft(T)), getValue(T), getRight(T));
else
- return Balance(Left(T), Value(T), Add_internal(V,Right(T)));
+ return balanceTree(getLeft(T), getValue(T), add_internal(V, getRight(T)));
}
- /// Remove_internal - Creates a new tree that includes all the data
+ /// remove_internal - Creates a new tree that includes all the data
/// from the original tree except the specified data. If the
/// specified data did not exist in the original tree, the original
/// tree is returned.
- TreeTy* Remove_internal(key_type_ref K, TreeTy* T) {
+ TreeTy* remove_internal(key_type_ref K, TreeTy* T) {
if (isEmpty(T))
return T;
assert(!T->isMutable());
- key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
+ key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T));
- if (ImutInfo::isEqual(K,KCurrent))
- return CombineLeftRightTrees(Left(T),Right(T));
- else if (ImutInfo::isLess(K,KCurrent))
- return Balance(Remove_internal(K,Left(T)), Value(T), Right(T));
- else
- return Balance(Left(T), Value(T), Remove_internal(K,Right(T)));
+ if (ImutInfo::isEqual(K,KCurrent)) {
+ return combineTrees(getLeft(T), getRight(T));
+ } else if (ImutInfo::isLess(K,KCurrent)) {
+ return balanceTree(remove_internal(K, getLeft(T)),
+ getValue(T), getRight(T));
+ } else {
+ return balanceTree(getLeft(T), getValue(T),
+ remove_internal(K, getRight(T)));
+ }
}
- TreeTy* CombineLeftRightTrees(TreeTy* L, TreeTy* R) {
- if (isEmpty(L)) return R;
- if (isEmpty(R)) return L;
-
+ TreeTy* combineTrees(TreeTy* L, TreeTy* R) {
+ if (isEmpty(L))
+ return R;
+ if (isEmpty(R))
+ return L;
TreeTy* OldNode;
- TreeTy* NewRight = RemoveMinBinding(R,OldNode);
- return Balance(L,Value(OldNode),NewRight);
+ TreeTy* newRight = removeMinBinding(R,OldNode);
+ return balanceTree(L, getValue(OldNode), newRight);
}
- TreeTy* RemoveMinBinding(TreeTy* T, TreeTy*& NodeRemoved) {
+ TreeTy* removeMinBinding(TreeTy* T, TreeTy*& Noderemoved) {
assert(!isEmpty(T));
-
- if (isEmpty(Left(T))) {
- NodeRemoved = T;
- return Right(T);
+ if (isEmpty(getLeft(T))) {
+ Noderemoved = T;
+ return getRight(T);
}
-
- return Balance(RemoveMinBinding(Left(T),NodeRemoved),Value(T),Right(T));
+ return balanceTree(removeMinBinding(getLeft(T), Noderemoved),
+ getValue(T), getRight(T));
}
- /// MarkImmutable - Clears the mutable bits of a root and all of its
+ /// markImmutable - Clears the mutable bits of a root and all of its
/// descendants.
- void MarkImmutable(TreeTy* T) {
+ void markImmutable(TreeTy* T) {
if (!T || !T->isMutable())
return;
-
- T->MarkImmutable();
- MarkImmutable(Left(T));
- MarkImmutable(Right(T));
+ T->markImmutable();
+ markImmutable(getLeft(T));
+ markImmutable(getRight(T));
}
public:
- TreeTy *GetCanonicalTree(TreeTy *TNew) {
+ TreeTy *getCanonicalTree(TreeTy *TNew) {
if (!TNew)
- return NULL;
-
- // Search the FoldingSet bucket for a Tree with the same digest.
- FoldingSetNodeID ID;
- unsigned digest = TNew->ComputeDigest();
- ID.AddInteger(digest);
- unsigned hash = ID.ComputeHash();
-
- typename CacheTy::bucket_iterator I = Cache.bucket_begin(hash);
- typename CacheTy::bucket_iterator E = Cache.bucket_end(hash);
-
- for (; I != E; ++I) {
- TreeTy *T = &*I;
-
- if (T->ComputeDigest() != digest)
- continue;
-
- // We found a collision. Perform a comparison of Contents('T')
- // with Contents('TNew')
- typename TreeTy::iterator TI = T->begin(), TE = T->end();
-
- if (!CompareTreeWithSection(TNew, TI, TE))
- continue;
-
- if (TI != TE)
- continue; // T has more contents than TNew.
-
- // Trees did match! Return 'T'.
- return T;
+ return 0;
+
+ if (TNew->IsCanonicalized)
+ return TNew;
+
+ // Search the hashtable for another tree with the same digest, and
+ // if find a collision compare those trees by their contents.
+ unsigned digest = TNew->computeDigest();
+ TreeTy *&entry = Cache[digest];
+ do {
+ if (!entry)
+ break;
+ for (TreeTy *T = entry ; T != 0; T = T->next) {
+ // Compare the Contents('T') with Contents('TNew')
+ typename TreeTy::iterator TI = T->begin(), TE = T->end();
+ if (!compareTreeWithSection(TNew, TI, TE))
+ continue;
+ if (TI != TE)
+ continue; // T has more contents than TNew.
+ // Trees did match! Return 'T'.
+ if (TNew->refCount == 0)
+ TNew->destroy();
+ return T;
+ }
+ entry->prev = TNew;
+ TNew->next = entry;
}
+ while (false);
- // 'TNew' is the only tree of its kind. Return it.
- Cache.InsertNode(TNew, (void*) &*Cache.bucket_end(hash));
+ entry = TNew;
+ TNew->IsCanonicalized = true;
return TNew;
}
};
-
//===----------------------------------------------------------------------===//
// Immutable AVL-Tree Iterators.
//===----------------------------------------------------------------------===//
@@ -635,19 +667,17 @@ public:
}
- bool AtEnd() const { return stack.empty(); }
+ bool atEnd() const { return stack.empty(); }
- bool AtBeginning() const {
+ bool atBeginning() const {
return stack.size() == 1 && getVisitState() == VisitedNone;
}
- void SkipToParent() {
+ void skipToParent() {
assert(!stack.empty());
stack.pop_back();
-
if (stack.empty())
return;
-
switch (getVisitState()) {
case VisitedNone:
stack.back() |= VisitedLeft;
@@ -663,11 +693,9 @@ public:
inline bool operator==(const _Self& x) const {
if (stack.size() != x.stack.size())
return false;
-
for (unsigned i = 0 ; i < stack.size(); i++)
if (stack[i] != x.stack[i])
return false;
-
return true;
}
@@ -675,70 +703,52 @@ public:
_Self& operator++() {
assert(!stack.empty());
-
TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
assert(Current);
-
switch (getVisitState()) {
case VisitedNone:
if (TreeTy* L = Current->getLeft())
stack.push_back(reinterpret_cast<uintptr_t>(L));
else
stack.back() |= VisitedLeft;
-
break;
-
case VisitedLeft:
if (TreeTy* R = Current->getRight())
stack.push_back(reinterpret_cast<uintptr_t>(R));
else
stack.back() |= VisitedRight;
-
break;
-
case VisitedRight:
- SkipToParent();
+ skipToParent();
break;
-
default:
assert(false && "Unreachable.");
}
-
return *this;
}
_Self& operator--() {
assert(!stack.empty());
-
TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
assert(Current);
-
switch (getVisitState()) {
case VisitedNone:
stack.pop_back();
break;
-
case VisitedLeft:
stack.back() &= ~Flags; // Set state to "VisitedNone."
-
if (TreeTy* L = Current->getLeft())
stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
-
break;
-
case VisitedRight:
stack.back() &= ~Flags;
stack.back() |= VisitedLeft;
-
if (TreeTy* R = Current->getRight())
stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
-
break;
-
default:
assert(false && "Unreachable.");
}
-
return *this;
}
};
@@ -769,7 +779,7 @@ public:
inline _Self& operator++() {
do ++InternalItr;
- while (!InternalItr.AtEnd() &&
+ while (!InternalItr.atEnd() &&
InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
return *this;
@@ -777,16 +787,16 @@ public:
inline _Self& operator--() {
do --InternalItr;
- while (!InternalItr.AtBeginning() &&
+ while (!InternalItr.atBeginning() &&
InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
return *this;
}
- inline void SkipSubTree() {
- InternalItr.SkipToParent();
+ inline void skipSubTree() {
+ InternalItr.skipToParent();
- while (!InternalItr.AtEnd() &&
+ while (!InternalItr.atEnd() &&
InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
++InternalItr;
}
@@ -927,7 +937,23 @@ public:
/// should use a Factory object to create sets instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
- explicit ImmutableSet(TreeTy* R) : Root(R) {}
+ explicit ImmutableSet(TreeTy* R) : Root(R) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableSet(const ImmutableSet &X) : Root(X.Root) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableSet &operator=(const ImmutableSet &X) {
+ if (Root != X.Root) {
+ if (X.Root) { X.Root->retain(); }
+ if (Root) { Root->release(); }
+ Root = X.Root;
+ }
+ return *this;
+ }
+ ~ImmutableSet() {
+ if (Root) { Root->release(); }
+ }
class Factory {
typename TreeTy::Factory F;
@@ -940,33 +966,33 @@ public:
Factory(BumpPtrAllocator& Alloc, bool canonicalize = true)
: F(Alloc), Canonicalize(canonicalize) {}
- /// GetEmptySet - Returns an immutable set that contains no elements.
- ImmutableSet GetEmptySet() {
- return ImmutableSet(F.GetEmptyTree());
+ /// getEmptySet - Returns an immutable set that contains no elements.
+ ImmutableSet getEmptySet() {
+ return ImmutableSet(F.getEmptyTree());
}
- /// Add - Creates a new immutable set that contains all of the values
+ /// add - Creates a new immutable set that contains all of the values
/// of the original set with the addition of the specified value. If
/// the original set already included the value, then the original set is
/// returned and no memory is allocated. The time and space complexity
/// of this operation is logarithmic in the size of the original set.
/// The memory allocated to represent the set is released when the
/// factory object that created the set is destroyed.
- ImmutableSet Add(ImmutableSet Old, value_type_ref V) {
- TreeTy *NewT = F.Add(Old.Root, V);
- return ImmutableSet(Canonicalize ? F.GetCanonicalTree(NewT) : NewT);
+ ImmutableSet add(ImmutableSet Old, value_type_ref V) {
+ TreeTy *NewT = F.add(Old.Root, V);
+ return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
}
- /// Remove - Creates a new immutable set that contains all of the values
+ /// remove - Creates a new immutable set that contains all of the values
/// of the original set with the exception of the specified value. If
/// the original set did not contain the value, the original set is
/// returned and no memory is allocated. The time and space complexity
/// of this operation is logarithmic in the size of the original set.
/// The memory allocated to represent the set is released when the
/// factory object that created the set is destroyed.
- ImmutableSet Remove(ImmutableSet Old, value_type_ref V) {
- TreeTy *NewT = F.Remove(Old.Root, V);
- return ImmutableSet(Canonicalize ? F.GetCanonicalTree(NewT) : NewT);
+ ImmutableSet remove(ImmutableSet Old, value_type_ref V) {
+ TreeTy *NewT = F.remove(Old.Root, V);
+ return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
}
BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
@@ -978,20 +1004,21 @@ public:
friend class Factory;
- /// contains - Returns true if the set contains the specified value.
+ /// Returns true if the set contains the specified value.
bool contains(value_type_ref V) const {
return Root ? Root->contains(V) : false;
}
- bool operator==(ImmutableSet RHS) const {
+ bool operator==(const ImmutableSet &RHS) const {
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
}
- bool operator!=(ImmutableSet RHS) const {
+ bool operator!=(const ImmutableSet &RHS) const {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
TreeTy *getRoot() {
+ if (Root) { Root->retain(); }
return Root;
}
@@ -1049,7 +1076,7 @@ public:
// For testing.
//===--------------------------------------------------===//
- void verify() const { if (Root) Root->verify(); }
+ void validateTree() const { if (Root) Root->validateTree(); }
};
} // end namespace llvm
diff --git a/include/llvm/ADT/InMemoryStruct.h b/include/llvm/ADT/InMemoryStruct.h
new file mode 100644
index 0000000000..a56084501a
--- /dev/null
+++ b/include/llvm/ADT/InMemoryStruct.h
@@ -0,0 +1,77 @@
+//===- InMemoryStruct.h - Indirect Struct Access Smart Pointer --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INMEMORYSTRUCT_H
+#define LLVM_ADT_INMEMORYSTRUCT_H
+
+#include <cassert>
+
+namespace llvm {
+
+/// \brief Helper object for abstracting access to an in-memory structure which
+/// may require some kind of temporary storage.
+///
+/// This class is designed to be used for accessing file data structures which
+/// in the common case can be accessed from a direct pointer to a memory mapped
+/// object, but which in some cases may require indirect access to a temporary
+/// structure (which, for example, may have undergone endianness translation).
+template<typename T>
+class InMemoryStruct {
+ typedef T value_type;
+ typedef value_type &reference;
+ typedef value_type *pointer;
+ typedef const value_type &const_reference;
+ typedef const value_type *const_pointer;
+
+ /// \brief The smart pointer target.
+ value_type *Target;
+
+ /// \brief A temporary object which can be used as a target of the smart
+ /// pointer.
+ value_type Contents;
+
+private:
+
+public:
+ InMemoryStruct() : Target(0) {}
+ InMemoryStruct(reference Value) : Target(&Contents), Contents(Value) {}
+ InMemoryStruct(pointer Value) : Target(Value) {}
+ InMemoryStruct(const InMemoryStruct<T> &Value) { *this = Value; }
+
+ void operator=(const InMemoryStruct<T> &Value) {
+ if (Value.Target != &Value.Contents) {
+ Target = Value.Target;
+ } else {
+ Target = &Contents;
+ Contents = Value.Contents;
+ }
+ }
+
+ const_reference operator*() const {
+ assert(Target && "Cannot dereference null pointer");
+ return *Target;
+ }
+ reference operator*() {
+ assert(Target && "Cannot dereference null pointer");
+ return *Target;
+ }
+
+ const_pointer operator->() const {
+ return Target;
+ }
+ pointer operator->() {
+ return Target;
+ }
+
+ operator bool() const { return Target != 0; }
+};
+
+}
+
+#endif
diff --git a/include/llvm/ADT/IndexedMap.h b/include/llvm/ADT/IndexedMap.h
index 89f0dfa64e..87126ea491 100644
--- a/include/llvm/ADT/IndexedMap.h
+++ b/include/llvm/ADT/IndexedMap.h
@@ -55,6 +55,14 @@ namespace llvm {
return storage_[toIndex_(n)];
}
+ void reserve(typename StorageT::size_type s) {
+ storage_.reserve(s);
+ }
+
+ void resize(typename StorageT::size_type s) {
+ storage_.resize(s, nullVal_);
+ }
+
void clear() {
storage_.clear();
}
@@ -62,7 +70,11 @@ namespace llvm {
void grow(IndexT n) {
unsigned NewSize = toIndex_(n) + 1;
if (NewSize > storage_.size())
- storage_.resize(NewSize, nullVal_);
+ resize(NewSize);
+ }
+
+ bool inBounds(IndexT n) const {
+ return toIndex_(n) < storage_.size();
}
typename StorageT::size_type size() const {
diff --git a/include/llvm/ADT/IntEqClasses.h b/include/llvm/ADT/IntEqClasses.h
new file mode 100644
index 0000000000..8e75c48e37
--- /dev/null
+++ b/include/llvm/ADT/IntEqClasses.h
@@ -0,0 +1,88 @@
+//===-- llvm/ADT/IntEqClasses.h - Equiv. Classes of Integers ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Equivalence classes for small integers. This is a mapping of the integers
+// 0 .. N-1 into M equivalence classes numbered 0 .. M-1.
+//
+// Initially each integer has its own equivalence class. Classes are joined by
+// passing a representative member of each class to join().
+//
+// Once the classes are built, compress() will number them 0 .. M-1 and prevent
+// further changes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INTEQCLASSES_H
+#define LLVM_ADT_INTEQCLASSES_H
+
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class IntEqClasses {
+ /// EC - When uncompressed, map each integer to a smaller member of its
+ /// equivalence class. The class leader is the smallest member and maps to
+ /// itself.
+ ///
+ /// When compressed, EC[i] is the equivalence class of i.
+ SmallVector<unsigned, 8> EC;
+
+ /// NumClasses - The number of equivalence classes when compressed, or 0 when
+ /// uncompressed.
+ unsigned NumClasses;
+
+public:
+ /// IntEqClasses - Create an equivalence class mapping for 0 .. N-1.
+ IntEqClasses(unsigned N = 0) : NumClasses(0) { grow(N); }
+
+ /// grow - Increase capacity to hold 0 .. N-1, putting new integers in unique
+ /// equivalence classes.
+ /// This requires an uncompressed map.
+ void grow(unsigned N);
+
+ /// clear - Clear all classes so that grow() will assign a unique class to
+ /// every integer.
+ void clear() {
+ EC.clear();
+ NumClasses = 0;
+ }
+
+ /// join - Join the equivalence classes of a and b. After joining classes,
+ /// findLeader(a) == findLeader(b).
+ /// This requires an uncompressed map.
+ void join(unsigned a, unsigned b);
+
+ /// findLeader - Compute the leader of a's equivalence class. This is the
+ /// smallest member of the class.
+ /// This requires an uncompressed map.
+ unsigned findLeader(unsigned a) const;
+
+ /// compress - Compress equivalence classes by numbering them 0 .. M.
+ /// This makes the equivalence class map immutable.
+ void compress();
+
+ /// getNumClasses - Return the number of equivalence classes after compress()
+ /// was called.
+ unsigned getNumClasses() const { return NumClasses; }
+
+ /// operator[] - Return a's equivalence class number, 0 .. getNumClasses()-1.
+ /// This requires a compressed map.
+ unsigned operator[](unsigned a) const {
+ assert(NumClasses && "operator[] called before compress()");
+ return EC[a];
+ }
+
+ /// uncompress - Change back to the uncompressed representation that allows
+ /// editing.
+ void uncompress();
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h
new file mode 100644
index 0000000000..79f24d31c0
--- /dev/null
+++ b/include/llvm/ADT/IntervalMap.h
@@ -0,0 +1,2139 @@
+//===- llvm/ADT/IntervalMap.h - A sorted interval map -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a coalescing interval map for small objects.
+//
+// KeyT objects are mapped to ValT objects. Intervals of keys that map to the
+// same value are represented in a compressed form.
+//
+// Iterators provide ordered access to the compressed intervals rather than the
+// individual keys, and insert and erase operations use key intervals as well.
+//
+// Like SmallVector, IntervalMap will store the first N intervals in the map
+// object itself without any allocations. When space is exhausted it switches to
+// a B+-tree representation with very small overhead for small key and value
+// objects.
+//
+// A Traits class specifies how keys are compared. It also allows IntervalMap to
+// work with both closed and half-open intervals.
+//
+// Keys and values are not stored next to each other in a std::pair, so we don't
+// provide such a value_type. Dereferencing iterators only returns the mapped
+// value. The interval bounds are accessible through the start() and stop()
+// iterator methods.
+//
+// IntervalMap is optimized for small key and value objects, 4 or 8 bytes each
+// is the optimal size. For large objects use std::map instead.
+//
+//===----------------------------------------------------------------------===//
+//
+// Synopsis:
+//
+// template <typename KeyT, typename ValT, unsigned N, typename Traits>
+// class IntervalMap {
+// public:
+// typedef KeyT key_type;
+// typedef ValT mapped_type;
+// typedef RecyclingAllocator<...> Allocator;
+// class iterator;
+// class const_iterator;
+//
+// explicit IntervalMap(Allocator&);
+// ~IntervalMap():
+//
+// bool empty() const;
+// KeyT start() const;
+// KeyT stop() const;
+// ValT lookup(KeyT x, Value NotFound = Value()) const;
+//
+// const_iterator begin() const;
+// const_iterator end() const;
+// iterator begin();
+// iterator end();
+// const_iterator find(KeyT x) const;
+// iterator find(KeyT x);
+//
+// void insert(KeyT a, KeyT b, ValT y);
+// void clear();
+// };
+//
+// template <typename KeyT, typename ValT, unsigned N, typename Traits>
+// class IntervalMap::const_iterator :
+// public std::iterator<std::bidirectional_iterator_tag, ValT> {
+// public:
+// bool operator==(const const_iterator &) const;
+// bool operator!=(const const_iterator &) const;
+// bool valid() const;
+//
+// const KeyT &start() const;
+// const KeyT &stop() const;
+// const ValT &value() const;
+// const ValT &operator*() const;
+// const ValT *operator->() const;
+//
+// const_iterator &operator++();
+// const_iterator &operator++(int);
+// const_iterator &operator--();
+// const_iterator &operator--(int);
+// void goToBegin();
+// void goToEnd();
+// void find(KeyT x);
+// void advanceTo(KeyT x);
+// };
+//
+// template <typename KeyT, typename ValT, unsigned N, typename Traits>
+// class IntervalMap::iterator : public const_iterator {
+// public:
+// void insert(KeyT a, KeyT b, Value y);
+// void erase();
+// };
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INTERVALMAP_H
+#define LLVM_ADT_INTERVALMAP_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/RecyclingAllocator.h"
+#include <iterator>
+
+namespace llvm {
+
+
+//===----------------------------------------------------------------------===//
+//--- Key traits ---//
+//===----------------------------------------------------------------------===//
+//
+// The IntervalMap works with closed or half-open intervals.
+// Adjacent intervals that map to the same value are coalesced.
+//
+// The IntervalMapInfo traits class is used to determine if a key is contained
+// in an interval, and if two intervals are adjacent so they can be coalesced.
+// The provided implementation works for closed integer intervals, other keys
+// probably need a specialized version.
+//
+// The point x is contained in [a;b] when !startLess(x, a) && !stopLess(b, x).
+//
+// It is assumed that (a;b] half-open intervals are not used, only [a;b) is
+// allowed. This is so that stopLess(a, b) can be used to determine if two
+// intervals overlap.
+//
+//===----------------------------------------------------------------------===//
+
+template <typename T>
+struct IntervalMapInfo {
+
+ /// startLess - Return true if x is not in [a;b].
+ /// This is x < a both for closed intervals and for [a;b) half-open intervals.
+ static inline bool startLess(const T &x, const T &a) {
+ return x < a;
+ }
+
+ /// stopLess - Return true if x is not in [a;b].
+ /// This is b < x for a closed interval, b <= x for [a;b) half-open intervals.
+ static inline bool stopLess(const T &b, const T &x) {
+ return b < x;
+ }
+
+ /// adjacent - Return true when the intervals [x;a] and [b;y] can coalesce.
+ /// This is a+1 == b for closed intervals, a == b for half-open intervals.
+ static inline bool adjacent(const T &a, const T &b) {
+ return a+1 == b;
+ }
+
+};
+
+/// IntervalMapImpl - Namespace used for IntervalMap implementation details.
+/// It should be considered private to the implementation.
+namespace IntervalMapImpl {
+
+// Forward declarations.
+template <typename, typename, unsigned, typename> class LeafNode;
+template <typename, typename, unsigned, typename> class BranchNode;
+
+typedef std::pair<unsigned,unsigned> IdxPair;
+
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::NodeBase ---//
+//===----------------------------------------------------------------------===//
+//
+// Both leaf and branch nodes store vectors of pairs.
+// Leaves store ((KeyT, KeyT), ValT) pairs, branches use (NodeRef, KeyT).
+//
+// Keys and values are stored in separate arrays to avoid padding caused by
+// different object alignments. This also helps improve locality of reference
+// when searching the keys.
+//
+// The nodes don't know how many elements they contain - that information is
+// stored elsewhere. Omitting the size field prevents padding and allows a node
+// to fill the allocated cache lines completely.
+//
+// These are typical key and value sizes, the node branching factor (N), and
+// wasted space when nodes are sized to fit in three cache lines (192 bytes):
+//
+// T1 T2 N Waste Used by
+// 4 4 24 0 Branch<4> (32-bit pointers)
+// 8 4 16 0 Leaf<4,4>, Branch<4>
+// 8 8 12 0 Leaf<4,8>, Branch<8>
+// 16 4 9 12 Leaf<8,4>
+// 16 8 8 0 Leaf<8,8>
+//
+//===----------------------------------------------------------------------===//
+
+template <typename T1, typename T2, unsigned N>
+class NodeBase {
+public:
+ enum { Capacity = N };
+
+ T1 first[N];
+ T2 second[N];
+
+ /// copy - Copy elements from another node.
+ /// @param Other Node elements are copied from.
+ /// @param i Beginning of the source range in other.
+ /// @param j Beginning of the destination range in this.
+ /// @param Count Number of elements to copy.
+ template <unsigned M>
+ void copy(const NodeBase<T1, T2, M> &Other, unsigned i,
+ unsigned j, unsigned Count) {
+ assert(i + Count <= M && "Invalid source range");
+ assert(j + Count <= N && "Invalid dest range");
+ for (unsigned e = i + Count; i != e; ++i, ++j) {
+ first[j] = Other.first[i];
+ second[j] = Other.second[i];
+ }
+ }
+
+ /// moveLeft - Move elements to the left.
+ /// @param i Beginning of the source range.
+ /// @param j Beginning of the destination range.
+ /// @param Count Number of elements to copy.
+ void moveLeft(unsigned i, unsigned j, unsigned Count) {
+ assert(j <= i && "Use moveRight shift elements right");
+ copy(*this, i, j, Count);
+ }
+
+ /// moveRight - Move elements to the right.
+ /// @param i Beginning of the source range.
+ /// @param j Beginning of the destination range.
+ /// @param Count Number of elements to copy.
+ void moveRight(unsigned i, unsigned j, unsigned Count) {
+ assert(i <= j && "Use moveLeft shift elements left");
+ assert(j + Count <= N && "Invalid range");
+ while (Count--) {
+ first[j + Count] = first[i + Count];
+ second[j + Count] = second[i + Count];
+ }
+ }
+
+ /// erase - Erase elements [i;j).
+ /// @param i Beginning of the range to erase.
+ /// @param j End of the range. (Exclusive).
+ /// @param Size Number of elements in node.
+ void erase(unsigned i, unsigned j, unsigned Size) {
+ moveLeft(j, i, Size - j);
+ }
+
+ /// erase - Erase element at i.
+ /// @param i Index of element to erase.
+ /// @param Size Number of elements in node.
+ void erase(unsigned i, unsigned Size) {
+ erase(i, i+1, Size);
+ }
+
+ /// shift - Shift elements [i;size) 1 position to the right.
+ /// @param i Beginning of the range to move.
+ /// @param Size Number of elements in node.
+ void shift(unsigned i, unsigned Size) {
+ moveRight(i, i + 1, Size - i);
+ }
+
+ /// transferToLeftSib - Transfer elements to a left sibling node.
+ /// @param Size Number of elements in this.
+ /// @param Sib Left sibling node.
+ /// @param SSize Number of elements in sib.
+ /// @param Count Number of elements to transfer.
+ void transferToLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize,
+ unsigned Count) {
+ Sib.copy(*this, 0, SSize, Count);
+ erase(0, Count, Size);
+ }
+
+ /// transferToRightSib - Transfer elements to a right sibling node.
+ /// @param Size Number of elements in this.
+ /// @param Sib Right sibling node.
+ /// @param SSize Number of elements in sib.
+ /// @param Count Number of elements to transfer.
+ void transferToRightSib(unsigned Size, NodeBase &Sib, unsigned SSize,
+ unsigned Count) {
+ Sib.moveRight(0, Count, SSize);
+ Sib.copy(*this, Size-Count, 0, Count);
+ }
+
+ /// adjustFromLeftSib - Adjust the number if elements in this node by moving
+ /// elements to or from a left sibling node.
+ /// @param Size Number of elements in this.
+ /// @param Sib Right sibling node.
+ /// @param SSize Number of elements in sib.
+ /// @param Add The number of elements to add to this node, possibly < 0.
+ /// @return Number of elements added to this node, possibly negative.
+ int adjustFromLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, int Add) {
+ if (Add > 0) {
+ // We want to grow, copy from sib.
+ unsigned Count = std::min(std::min(unsigned(Add), SSize), N - Size);
+ Sib.transferToRightSib(SSize, *this, Size, Count);
+ return Count;
+ } else {
+ // We want to shrink, copy to sib.
+ unsigned Count = std::min(std::min(unsigned(-Add), Size), N - SSize);
+ transferToLeftSib(Size, Sib, SSize, Count);
+ return -Count;
+ }
+ }
+};
+
+/// IntervalMapImpl::adjustSiblingSizes - Move elements between sibling nodes.
+/// @param Node Array of pointers to sibling nodes.
+/// @param Nodes Number of nodes.
+/// @param CurSize Array of current node sizes, will be overwritten.
+/// @param NewSize Array of desired node sizes.
+template <typename NodeT>
+void adjustSiblingSizes(NodeT *Node[], unsigned Nodes,
+ unsigned CurSize[], const unsigned NewSize[]) {
+ // Move elements right.
+ for (int n = Nodes - 1; n; --n) {
+ if (CurSize[n] == NewSize[n])
+ continue;
+ for (int m = n - 1; m != -1; --m) {
+ int d = Node[n]->adjustFromLeftSib(CurSize[n], *Node[m], CurSize[m],
+ NewSize[n] - CurSize[n]);
+ CurSize[m] -= d;
+ CurSize[n] += d;
+ // Keep going if the current node was exhausted.
+ if (CurSize[n] >= NewSize[n])
+ break;
+ }
+ }
+
+ if (Nodes == 0)
+ return;
+
+ // Move elements left.
+ for (unsigned n = 0; n != Nodes - 1; ++n) {
+ if (CurSize[n] == NewSize[n])
+ continue;
+ for (unsigned m = n + 1; m != Nodes; ++m) {
+ int d = Node[m]->adjustFromLeftSib(CurSize[m], *Node[n], CurSize[n],
+ CurSize[n] - NewSize[n]);
+ CurSize[m] += d;
+ CurSize[n] -= d;
+ // Keep going if the current node was exhausted.
+ if (CurSize[n] >= NewSize[n])
+ break;
+ }
+ }
+
+#ifndef NDEBUG
+ for (unsigned n = 0; n != Nodes; n++)
+ assert(CurSize[n] == NewSize[n] && "Insufficient element shuffle");
+#endif
+}
+
+/// IntervalMapImpl::distribute - Compute a new distribution of node elements
+/// after an overflow or underflow. Reserve space for a new element at Position,
+/// and compute the node that will hold Position after redistributing node
+/// elements.
+///
+/// It is required that
+///
+/// Elements == sum(CurSize), and
+/// Elements + Grow <= Nodes * Capacity.
+///
+/// NewSize[] will be filled in such that:
+///
+/// sum(NewSize) == Elements, and
+/// NewSize[i] <= Capacity.
+///
+/// The returned index is the node where Position will go, so:
+///
+/// sum(NewSize[0..idx-1]) <= Position
+/// sum(NewSize[0..idx]) >= Position
+///
+/// The last equality, sum(NewSize[0..idx]) == Position, can only happen when
+/// Grow is set and NewSize[idx] == Capacity-1. The index points to the node
+/// before the one holding the Position'th element where there is room for an
+/// insertion.
+///
+/// @param Nodes The number of nodes.
+/// @param Elements Total elements in all nodes.
+/// @param Capacity The capacity of each node.
+/// @param CurSize Array[Nodes] of current node sizes, or NULL.
+/// @param NewSize Array[Nodes] to receive the new node sizes.
+/// @param Position Insert position.
+/// @param Grow Reserve space for a new element at Position.
+/// @return (node, offset) for Position.
+IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity,
+ const unsigned *CurSize, unsigned NewSize[],
+ unsigned Position, bool Grow);
+
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::NodeSizer ---//
+//===----------------------------------------------------------------------===//
+//
+// Compute node sizes from key and value types.
+//
+// The branching factors are chosen to make nodes fit in three cache lines.
+// This may not be possible if keys or values are very large. Such large objects
+// are handled correctly, but a std::map would probably give better performance.
+//
+//===----------------------------------------------------------------------===//
+
+enum {
+ // Cache line size. Most architectures have 32 or 64 byte cache lines.
+ // We use 64 bytes here because it provides good branching factors.
+ Log2CacheLine = 6,
+ CacheLineBytes = 1 << Log2CacheLine,
+ DesiredNodeBytes = 3 * CacheLineBytes
+};
+
+template <typename KeyT, typename ValT>
+struct NodeSizer {
+ enum {
+ // Compute the leaf node branching factor that makes a node fit in three
+ // cache lines. The branching factor must be at least 3, or some B+-tree
+ // balancing algorithms won't work.
+ // LeafSize can't be larger than CacheLineBytes. This is required by the
+ // PointerIntPair used by NodeRef.
+ DesiredLeafSize = DesiredNodeBytes /
+ static_cast<unsigned>(2*sizeof(KeyT)+sizeof(ValT)),
+ MinLeafSize = 3,
+ LeafSize = DesiredLeafSize > MinLeafSize ? DesiredLeafSize : MinLeafSize
+ };
+
+ typedef NodeBase<std::pair<KeyT, KeyT>, ValT, LeafSize> LeafBase;
+
+ enum {
+ // Now that we have the leaf branching factor, compute the actual allocation
+ // unit size by rounding up to a whole number of cache lines.
+ AllocBytes = (sizeof(LeafBase) + CacheLineBytes-1) & ~(CacheLineBytes-1),
+
+ // Determine the branching factor for branch nodes.
+ BranchSize = AllocBytes /
+ static_cast<unsigned>(sizeof(KeyT) + sizeof(void*))
+ };
+
+ /// Allocator - The recycling allocator used for both branch and leaf nodes.
+ /// This typedef is very likely to be identical for all IntervalMaps with
+ /// reasonably sized entries, so the same allocator can be shared among
+ /// different kinds of maps.
+ typedef RecyclingAllocator<BumpPtrAllocator, char,
+ AllocBytes, CacheLineBytes> Allocator;
+
+};
+
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::NodeRef ---//
+//===----------------------------------------------------------------------===//
+//
+// B+-tree nodes can be leaves or branches, so we need a polymorphic node
+// pointer that can point to both kinds.
+//
+// All nodes are cache line aligned and the low 6 bits of a node pointer are
+// always 0. These bits are used to store the number of elements in the
+// referenced node. Besides saving space, placing node sizes in the parents
+// allow tree balancing algorithms to run without faulting cache lines for nodes
+// that may not need to be modified.
+//
+// A NodeRef doesn't know whether it references a leaf node or a branch node.
+// It is the responsibility of the caller to use the correct types.
+//
+// Nodes are never supposed to be empty, and it is invalid to store a node size
+// of 0 in a NodeRef. The valid range of sizes is 1-64.
+//
+//===----------------------------------------------------------------------===//
+
+class NodeRef {
+ struct CacheAlignedPointerTraits {
+ static inline void *getAsVoidPointer(void *P) { return P; }
+ static inline void *getFromVoidPointer(void *P) { return P; }
+ enum { NumLowBitsAvailable = Log2CacheLine };
+ };
+ PointerIntPair<void*, Log2CacheLine, unsigned, CacheAlignedPointerTraits> pip;
+
+public:
+ /// NodeRef - Create a null ref.
+ NodeRef() {}
+
+ /// operator bool - Detect a null ref.
+ operator bool() const { return pip.getOpaqueValue(); }
+
+ /// NodeRef - Create a reference to the node p with n elements.
+ template <typename NodeT>
+ NodeRef(NodeT *p, unsigned n) : pip(p, n - 1) {
+ assert(n <= NodeT::Capacity && "Size too big for node");
+ }
+
+ /// size - Return the number of elements in the referenced node.
+ unsigned size() const { return pip.getInt() + 1; }
+
+ /// setSize - Update the node size.
+ void setSize(unsigned n) { pip.setInt(n - 1); }
+
+ /// subtree - Access the i'th subtree reference in a branch node.
+ /// This depends on branch nodes storing the NodeRef array as their first
+ /// member.
+ NodeRef &subtree(unsigned i) const {
+ return reinterpret_cast<NodeRef*>(pip.getPointer())[i];
+ }
+
+ /// get - Dereference as a NodeT reference.
+ template <typename NodeT>
+ NodeT &get() const {
+ return *reinterpret_cast<NodeT*>(pip.getPointer());
+ }
+
+ bool operator==(const NodeRef &RHS) const {
+ if (pip == RHS.pip)
+ return true;
+ assert(pip.getPointer() != RHS.pip.getPointer() && "Inconsistent NodeRefs");
+ return false;
+ }
+
+ bool operator!=(const NodeRef &RHS) const {
+ return !operator==(RHS);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::LeafNode ---//
+//===----------------------------------------------------------------------===//
+//
+// Leaf nodes store up to N disjoint intervals with corresponding values.
+//
+// The intervals are kept sorted and fully coalesced so there are no adjacent
+// intervals mapping to the same value.
+//
+// These constraints are always satisfied:
+//
+// - Traits::stopLess(start(i), stop(i)) - Non-empty, sane intervals.
+//
+// - Traits::stopLess(stop(i), start(i + 1) - Sorted.
+//
+// - value(i) != value(i + 1) || !Traits::adjacent(stop(i), start(i + 1))
+// - Fully coalesced.
+//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class LeafNode : public NodeBase<std::pair<KeyT, KeyT>, ValT, N> {
+public:
+ const KeyT &start(unsigned i) const { return this->first[i].first; }
+ const KeyT &stop(unsigned i) const { return this->first[i].second; }
+ const ValT &value(unsigned i) const { return this->second[i]; }
+
+ KeyT &start(unsigned i) { return this->first[i].first; }
+ KeyT &stop(unsigned i) { return this->first[i].second; }
+ ValT &value(unsigned i) { return this->second[i]; }
+
+ /// findFrom - Find the first interval after i that may contain x.
+ /// @param i Starting index for the search.
+ /// @param Size Number of elements in node.
+ /// @param x Key to search for.
+ /// @return First index with !stopLess(key[i].stop, x), or size.
+ /// This is the first interval that can possibly contain x.
+ unsigned findFrom(unsigned i, unsigned Size, KeyT x) const {
+ assert(i <= Size && Size <= N && "Bad indices");
+ assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+ "Index is past the needed point");
+ while (i != Size && Traits::stopLess(stop(i), x)) ++i;
+ return i;
+ }
+
+ /// safeFind - Find an interval that is known to exist. This is the same as
+ /// findFrom except is it assumed that x is at least within range of the last
+ /// interval.
+ /// @param i Starting index for the search.
+ /// @param x Key to search for.
+ /// @return First index with !stopLess(key[i].stop, x), never size.
+ /// This is the first interval that can possibly contain x.
+ unsigned safeFind(unsigned i, KeyT x) const {
+ assert(i < N && "Bad index");
+ assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+ "Index is past the needed point");
+ while (Traits::stopLess(stop(i), x)) ++i;
+ assert(i < N && "Unsafe intervals");
+ return i;
+ }
+
+ /// safeLookup - Lookup mapped value for a safe key.
+ /// It is assumed that x is within range of the last entry.
+ /// @param x Key to search for.
+ /// @param NotFound Value to return if x is not in any interval.
+ /// @return The mapped value at x or NotFound.
+ ValT safeLookup(KeyT x, ValT NotFound) const {
+ unsigned i = safeFind(0, x);
+ return Traits::startLess(x, start(i)) ? NotFound : value(i);
+ }
+
+ unsigned insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y);
+};
+
+/// insertFrom - Add mapping of [a;b] to y if possible, coalescing as much as
+/// possible. This may cause the node to grow by 1, or it may cause the node
+/// to shrink because of coalescing.
+/// @param i Starting index = insertFrom(0, size, a)
+/// @param Size Number of elements in node.
+/// @param a Interval start.
+/// @param b Interval stop.
+/// @param y Value be mapped.
+/// @return (insert position, new size), or (i, Capacity+1) on overflow.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+unsigned LeafNode<KeyT, ValT, N, Traits>::
+insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y) {
+ unsigned i = Pos;
+ assert(i <= Size && Size <= N && "Invalid index");
+ assert(!Traits::stopLess(b, a) && "Invalid interval");
+
+ // Verify the findFrom invariant.
+ assert((i == 0 || Traits::stopLess(stop(i - 1), a)));
+ assert((i == Size || !Traits::stopLess(stop(i), a)));
+ assert((i == Size || Traits::stopLess(b, start(i))) && "Overlapping insert");
+
+ // Coalesce with previous interval.
+ if (i && value(i - 1) == y && Traits::adjacent(stop(i - 1), a)) {
+ Pos = i - 1;
+ // Also coalesce with next interval?
+ if (i != Size && value(i) == y && Traits::adjacent(b, start(i))) {
+ stop(i - 1) = stop(i);
+ this->erase(i, Size);
+ return Size - 1;
+ }
+ stop(i - 1) = b;
+ return Size;
+ }
+
+ // Detect overflow.
+ if (i == N)
+ return N + 1;
+
+ // Add new interval at end.
+ if (i == Size) {
+ start(i) = a;
+ stop(i) = b;
+ value(i) = y;
+ return Size + 1;
+ }
+
+ // Try to coalesce with following interval.
+ if (value(i) == y && Traits::adjacent(b, start(i))) {
+ start(i) = a;
+ return Size;
+ }
+
+ // We must insert before i. Detect overflow.
+ if (Size == N)
+ return N + 1;
+
+ // Insert before i.
+ this->shift(i, Size);
+ start(i) = a;
+ stop(i) = b;
+ value(i) = y;
+ return Size + 1;
+}
+
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::BranchNode ---//
+//===----------------------------------------------------------------------===//
+//
+// A branch node stores references to 1--N subtrees all of the same height.
+//
+// The key array in a branch node holds the rightmost stop key of each subtree.
+// It is redundant to store the last stop key since it can be found in the
+// parent node, but doing so makes tree balancing a lot simpler.
+//
+// It is unusual for a branch node to only have one subtree, but it can happen
+// in the root node if it is smaller than the normal nodes.
+//
+// When all of the leaf nodes from all the subtrees are concatenated, they must
+// satisfy the same constraints as a single leaf node. They must be sorted,
+// sane, and fully coalesced.
+//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class BranchNode : public NodeBase<NodeRef, KeyT, N> {
+public:
+ const KeyT &stop(unsigned i) const { return this->second[i]; }
+ const NodeRef &subtree(unsigned i) const { return this->first[i]; }
+
+ KeyT &stop(unsigned i) { return this->second[i]; }
+ NodeRef &subtree(unsigned i) { return this->first[i]; }
+
+ /// findFrom - Find the first subtree after i that may contain x.
+ /// @param i Starting index for the search.
+ /// @param Size Number of elements in node.
+ /// @param x Key to search for.
+ /// @return First index with !stopLess(key[i], x), or size.
+ /// This is the first subtree that can possibly contain x.
+ unsigned findFrom(unsigned i, unsigned Size, KeyT x) const {
+ assert(i <= Size && Size <= N && "Bad indices");
+ assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+ "Index to findFrom is past the needed point");
+ while (i != Size && Traits::stopLess(stop(i), x)) ++i;
+ return i;
+ }
+
+ /// safeFind - Find a subtree that is known to exist. This is the same as
+ /// findFrom except is it assumed that x is in range.
+ /// @param i Starting index for the search.
+ /// @param x Key to search for.
+ /// @return First index with !stopLess(key[i], x), never size.
+ /// This is the first subtree that can possibly contain x.
+ unsigned safeFind(unsigned i, KeyT x) const {
+ assert(i < N && "Bad index");
+ assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+ "Index is past the needed point");
+ while (Traits::stopLess(stop(i), x)) ++i;
+ assert(i < N && "Unsafe intervals");
+ return i;
+ }
+
+ /// safeLookup - Get the subtree containing x, Assuming that x is in range.
+ /// @param x Key to search for.
+ /// @return Subtree containing x
+ NodeRef safeLookup(KeyT x) const {
+ return subtree(safeFind(0, x));
+ }
+
+ /// insert - Insert a new (subtree, stop) pair.
+ /// @param i Insert position, following entries will be shifted.
+ /// @param Size Number of elements in node.
+ /// @param Node Subtree to insert.
+ /// @param Stop Last key in subtree.
+ void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop) {
+ assert(Size < N && "branch node overflow");
+ assert(i <= Size && "Bad insert position");
+ this->shift(i, Size);
+ subtree(i) = Node;
+ stop(i) = Stop;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::Path ---//
+//===----------------------------------------------------------------------===//
+//
+// A Path is used by iterators to represent a position in a B+-tree, and the
+// path to get there from the root.
+//
+// The Path class also constains the tree navigation code that doesn't have to
+// be templatized.
+//
+//===----------------------------------------------------------------------===//
+
+class Path {
+ /// Entry - Each step in the path is a node pointer and an offset into that
+ /// node.
+ struct Entry {
+ void *node;
+ unsigned size;
+ unsigned offset;
+
+ Entry(void *Node, unsigned Size, unsigned Offset)
+ : node(Node), size(Size), offset(Offset) {}
+
+ Entry(NodeRef Node, unsigned Offset)
+ : node(&Node.subtree(0)), size(Node.size()), offset(Offset) {}
+
+ NodeRef &subtree(unsigned i) const {
+ return reinterpret_cast<NodeRef*>(node)[i];
+ }
+ };
+
+ /// path - The path entries, path[0] is the root node, path.back() is a leaf.
+ SmallVector<Entry, 4> path;
+
+public:
+ // Node accessors.
+ template <typename NodeT> NodeT &node(unsigned Level) const {
+ return *reinterpret_cast<NodeT*>(path[Level].node);
+ }
+ unsigned size(unsigned Level) const { return path[Level].size; }
+ unsigned offset(unsigned Level) const { return path[Level].offset; }
+ unsigned &offset(unsigned Level) { return path[Level].offset; }
+
+ // Leaf accessors.
+ template <typename NodeT> NodeT &leaf() const {
+ return *reinterpret_cast<NodeT*>(path.back().node);
+ }
+ unsigned leafSize() const { return path.back().size; }
+ unsigned leafOffset() const { return path.back().offset; }
+ unsigned &leafOffset() { return path.back().offset; }
+
+ /// valid - Return true if path is at a valid node, not at end().
+ bool valid() const {
+ return !path.empty() && path.front().offset < path.front().size;
+ }
+
+ /// height - Return the height of the tree corresponding to this path.
+ /// This matches map->height in a full path.
+ unsigned height() const { return path.size() - 1; }
+
+ /// subtree - Get the subtree referenced from Level. When the path is
+ /// consistent, node(Level + 1) == subtree(Level).
+ /// @param Level 0..height-1. The leaves have no subtrees.
+ NodeRef &subtree(unsigned Level) const {
+ return path[Level].subtree(path[Level].offset);
+ }
+
+ /// reset - Reset cached information about node(Level) from subtree(Level -1).
+ /// @param Level 1..height. THe node to update after parent node changed.
+ void reset(unsigned Level) {
+ path[Level] = Entry(subtree(Level - 1), offset(Level));
+ }
+
+ /// push - Add entry to path.
+ /// @param Node Node to add, should be subtree(path.size()-1).
+ /// @param Offset Offset into Node.
+ void push(NodeRef Node, unsigned Offset) {
+ path.push_back(Entry(Node, Offset));
+ }
+
+ /// pop - Remove the last path entry.
+ void pop() {
+ path.pop_back();
+ }
+
+ /// setSize - Set the size of a node both in the path and in the tree.
+ /// @param Level 0..height. Note that setting the root size won't change
+ /// map->rootSize.
+ /// @param Size New node size.
+ void setSize(unsigned Level, unsigned Size) {
+ path[Level].size = Size;
+ if (Level)
+ subtree(Level - 1).setSize(Size);
+ }
+
+ /// setRoot - Clear the path and set a new root node.
+ /// @param Node New root node.
+ /// @param Size New root size.
+ /// @param Offset Offset into root node.
+ void setRoot(void *Node, unsigned Size, unsigned Offset) {
+ path.clear();
+ path.push_back(Entry(Node, Size, Offset));
+ }
+
+ /// replaceRoot - Replace the current root node with two new entries after the
+ /// tree height has increased.
+ /// @param Root The new root node.
+ /// @param Size Number of entries in the new root.
+ /// @param Offsets Offsets into the root and first branch nodes.
+ void replaceRoot(void *Root, unsigned Size, IdxPair Offsets);
+
+ /// getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
+ /// @param Level Get the sibling to node(Level).
+ /// @return Left sibling, or NodeRef().
+ NodeRef getLeftSibling(unsigned Level) const;
+
+ /// moveLeft - Move path to the left sibling at Level. Leave nodes below Level
+ /// unaltered.
+ /// @param Level Move node(Level).
+ void moveLeft(unsigned Level);
+
+ /// fillLeft - Grow path to Height by taking leftmost branches.
+ /// @param Height The target height.
+ void fillLeft(unsigned Height) {
+ while (height() < Height)
+ push(subtree(height()), 0);
+ }
+
+ /// getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
+ /// @param Level Get the sinbling to node(Level).
+ /// @return Left sibling, or NodeRef().
+ NodeRef getRightSibling(unsigned Level) const;
+
+ /// moveRight - Move path to the left sibling at Level. Leave nodes below
+ /// Level unaltered.
+ /// @param Level Move node(Level).
+ void moveRight(unsigned Level);
+
+ /// atBegin - Return true if path is at begin().
+ bool atBegin() const {
+ for (unsigned i = 0, e = path.size(); i != e; ++i)
+ if (path[i].offset != 0)
+ return false;
+ return true;
+ }
+
+ /// atLastEntry - Return true if the path is at the last entry of the node at
+ /// Level.
+ /// @param Level Node to examine.
+ bool atLastEntry(unsigned Level) const {
+ return path[Level].offset == path[Level].size - 1;
+ }
+
+ /// legalizeForInsert - Prepare the path for an insertion at Level. When the
+ /// path is at end(), node(Level) may not be a legal node. legalizeForInsert
+ /// ensures that node(Level) is real by moving back to the last node at Level,
+ /// and setting offset(Level) to size(Level) if required.
+ /// @param Level The level where an insertion is about to take place.
+ void legalizeForInsert(unsigned Level) {
+ if (valid())
+ return;
+ moveLeft(Level);
+ ++path[Level].offset;
+ }
+};
+
+} // namespace IntervalMapImpl
+
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMap ----//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT,
+ unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
+ typename Traits = IntervalMapInfo<KeyT> >
+class IntervalMap {
+ typedef IntervalMapImpl::NodeSizer<KeyT, ValT> Sizer;
+ typedef IntervalMapImpl::LeafNode<KeyT, ValT, Sizer::LeafSize, Traits> Leaf;
+ typedef IntervalMapImpl::BranchNode<KeyT, ValT, Sizer::BranchSize, Traits>
+ Branch;
+ typedef IntervalMapImpl::LeafNode<KeyT, ValT, N, Traits> RootLeaf;
+ typedef IntervalMapImpl::IdxPair IdxPair;
+
+ // The RootLeaf capacity is given as a template parameter. We must compute the
+ // corresponding RootBranch capacity.
+ enum {
+ DesiredRootBranchCap = (sizeof(RootLeaf) - sizeof(KeyT)) /
+ (sizeof(KeyT) + sizeof(IntervalMapImpl::NodeRef)),
+ RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1
+ };
+
+ typedef IntervalMapImpl::BranchNode<KeyT, ValT, RootBranchCap, Traits>
+ RootBranch;
+
+ // When branched, we store a global start key as well as the branch node.
+ struct RootBranchData {
+ KeyT start;
+ RootBranch node;
+ };
+
+ enum {
+ RootDataSize = sizeof(RootBranchData) > sizeof(RootLeaf) ?
+ sizeof(RootBranchData) : sizeof(RootLeaf)
+ };
+
+public:
+ typedef typename Sizer::Allocator Allocator;
+ typedef KeyT KeyType;
+ typedef ValT ValueType;
+ typedef Traits KeyTraits;
+
+private:
+ // The root data is either a RootLeaf or a RootBranchData instance.
+ // We can't put them in a union since C++03 doesn't allow non-trivial
+ // constructors in unions.
+ // Instead, we use a char array with pointer alignment. The alignment is
+ // ensured by the allocator member in the class, but still verified in the
+ // constructor. We don't support keys or values that are more aligned than a
+ // pointer.
+ char data[RootDataSize];
+
+ // Tree height.
+ // 0: Leaves in root.
+ // 1: Root points to leaf.
+ // 2: root->branch->leaf ...
+ unsigned height;
+
+ // Number of entries in the root node.
+ unsigned rootSize;
+
+ // Allocator used for creating external nodes.
+ Allocator &allocator;
+
+ /// dataAs - Represent data as a node type without breaking aliasing rules.
+ template <typename T>
+ T &dataAs() const {
+ union {
+ const char *d;
+ T *t;
+ } u;
+ u.d = data;
+ return *u.t;
+ }
+
+ const RootLeaf &rootLeaf() const {
+ assert(!branched() && "Cannot acces leaf data in branched root");
+ return dataAs<RootLeaf>();
+ }
+ RootLeaf &rootLeaf() {
+ assert(!branched() && "Cannot acces leaf data in branched root");
+ return dataAs<RootLeaf>();
+ }
+ RootBranchData &rootBranchData() const {
+ assert(branched() && "Cannot access branch data in non-branched root");
+ return dataAs<RootBranchData>();
+ }
+ RootBranchData &rootBranchData() {
+ assert(branched() && "Cannot access branch data in non-branched root");
+ return dataAs<RootBranchData>();
+ }
+ const RootBranch &rootBranch() const { return rootBranchData().node; }
+ RootBranch &rootBranch() { return rootBranchData().node; }
+ KeyT rootBranchStart() const { return rootBranchData().start; }
+ KeyT &rootBranchStart() { return rootBranchData().start; }
+
+ template <typename NodeT> NodeT *newNode() {
+ return new(allocator.template Allocate<NodeT>()) NodeT();
+ }
+
+ template <typename NodeT> void deleteNode(NodeT *P) {
+ P->~NodeT();
+ allocator.Deallocate(P);
+ }
+
+ IdxPair branchRoot(unsigned Position);
+ IdxPair splitRoot(unsigned Position);
+
+ void switchRootToBranch() {
+ rootLeaf().~RootLeaf();
+ height = 1;
+ new (&rootBranchData()) RootBranchData();
+ }
+
+ void switchRootToLeaf() {
+ rootBranchData().~RootBranchData();
+ height = 0;
+ new(&rootLeaf()) RootLeaf();
+ }
+
+ bool branched() const { return height > 0; }
+
+ ValT treeSafeLookup(KeyT x, ValT NotFound) const;
+ void visitNodes(void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
+ unsigned Level));
+ void deleteNode(IntervalMapImpl::NodeRef Node, unsigned Level);
+
+public:
+ explicit IntervalMap(Allocator &a) : height(0), rootSize(0), allocator(a) {
+ assert((uintptr_t(data) & (alignOf<RootLeaf>() - 1)) == 0 &&
+ "Insufficient alignment");
+ new(&rootLeaf()) RootLeaf();
+ }
+
+ ~IntervalMap() {
+ clear();
+ rootLeaf().~RootLeaf();
+ }
+
+ /// empty - Return true when no intervals are mapped.
+ bool empty() const {
+ return rootSize == 0;
+ }
+
+ /// start - Return the smallest mapped key in a non-empty map.
+ KeyT start() const {
+ assert(!empty() && "Empty IntervalMap has no start");
+ return !branched() ? rootLeaf().start(0) : rootBranchStart();
+ }
+
+ /// stop - Return the largest mapped key in a non-empty map.
+ KeyT stop() const {
+ assert(!empty() && "Empty IntervalMap has no stop");
+ return !branched() ? rootLeaf().stop(rootSize - 1) :
+ rootBranch().stop(rootSize - 1);
+ }
+
+ /// lookup - Return the mapped value at x or NotFound.
+ ValT lookup(KeyT x, ValT NotFound = ValT()) const {
+ if (empty() || Traits::startLess(x, start()) || Traits::stopLess(stop(), x))
+ return NotFound;
+ return branched() ? treeSafeLookup(x, NotFound) :
+ rootLeaf().safeLookup(x, NotFound);
+ }
+
+ /// insert - Add a mapping of [a;b] to y, coalesce with adjacent intervals.
+ /// It is assumed that no key in the interval is mapped to another value, but
+ /// overlapping intervals already mapped to y will be coalesced.
+ void insert(KeyT a, KeyT b, ValT y) {
+ if (branched() || rootSize == RootLeaf::Capacity)
+ return find(a).insert(a, b, y);
+
+ // Easy insert into root leaf.
+ unsigned p = rootLeaf().findFrom(0, rootSize, a);
+ rootSize = rootLeaf().insertFrom(p, rootSize, a, b, y);
+ }
+
+ /// clear - Remove all entries.
+ void clear();
+
+ class const_iterator;
+ class iterator;
+ friend class const_iterator;
+ friend class iterator;
+
+ const_iterator begin() const {
+ const_iterator I(*this);
+ I.goToBegin();
+ return I;
+ }
+
+ iterator begin() {
+ iterator I(*this);
+ I.goToBegin();
+ return I;
+ }
+
+ const_iterator end() const {
+ const_iterator I(*this);
+ I.goToEnd();
+ return I;
+ }
+
+ iterator end() {
+ iterator I(*this);
+ I.goToEnd();
+ return I;
+ }
+
+ /// find - Return an iterator pointing to the first interval ending at or
+ /// after x, or end().
+ const_iterator find(KeyT x) const {
+ const_iterator I(*this);
+ I.find(x);
+ return I;
+ }
+
+ iterator find(KeyT x) {
+ iterator I(*this);
+ I.find(x);
+ return I;
+ }
+};
+
+/// treeSafeLookup - Return the mapped value at x or NotFound, assuming a
+/// branched root.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+ValT IntervalMap<KeyT, ValT, N, Traits>::
+treeSafeLookup(KeyT x, ValT NotFound) const {
+ assert(branched() && "treeLookup assumes a branched root");
+
+ IntervalMapImpl::NodeRef NR = rootBranch().safeLookup(x);
+ for (unsigned h = height-1; h; --h)
+ NR = NR.get<Branch>().safeLookup(x);
+ return NR.get<Leaf>().safeLookup(x, NotFound);
+}
+
+
+// branchRoot - Switch from a leaf root to a branched root.
+// Return the new (root offset, node offset) corresponding to Position.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+IntervalMapImpl::IdxPair IntervalMap<KeyT, ValT, N, Traits>::
+branchRoot(unsigned Position) {
+ using namespace IntervalMapImpl;
+ // How many external leaf nodes to hold RootLeaf+1?
+ const unsigned Nodes = RootLeaf::Capacity / Leaf::Capacity + 1;
+
+ // Compute element distribution among new nodes.
+ unsigned size[Nodes];
+ IdxPair NewOffset(0, Position);
+
+ // Is is very common for the root node to be smaller than external nodes.
+ if (Nodes == 1)
+ size[0] = rootSize;
+ else
+ NewOffset = distribute(Nodes, rootSize, Leaf::Capacity, NULL, size,
+ Position, true);
+
+ // Allocate new nodes.
+ unsigned pos = 0;
+ NodeRef node[Nodes];
+ for (unsigned n = 0; n != Nodes; ++n) {
+ Leaf *L = newNode<Leaf>();
+ L->copy(rootLeaf(), pos, 0, size[n]);
+ node[n] = NodeRef(L, size[n]);
+ pos += size[n];
+ }
+
+ // Destroy the old leaf node, construct branch node instead.
+ switchRootToBranch();
+ for (unsigned n = 0; n != Nodes; ++n) {
+ rootBranch().stop(n) = node[n].template get<Leaf>().stop(size[n]-1);
+ rootBranch().subtree(n) = node[n];
+ }
+ rootBranchStart() = node[0].template get<Leaf>().start(0);
+ rootSize = Nodes;
+ return NewOffset;
+}
+
+// splitRoot - Split the current BranchRoot into multiple Branch nodes.
+// Return the new (root offset, node offset) corresponding to Position.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+IntervalMapImpl::IdxPair IntervalMap<KeyT, ValT, N, Traits>::
+splitRoot(unsigned Position) {
+ using namespace IntervalMapImpl;
+ // How many external leaf nodes to hold RootBranch+1?
+ const unsigned Nodes = RootBranch::Capacity / Branch::Capacity + 1;
+
+ // Compute element distribution among new nodes.
+ unsigned Size[Nodes];
+ IdxPair NewOffset(0, Position);
+
+ // Is is very common for the root node to be smaller than external nodes.
+ if (Nodes == 1)
+ Size[0] = rootSize;
+ else
+ NewOffset = distribute(Nodes, rootSize, Leaf::Capacity, NULL, Size,
+ Position, true);
+
+ // Allocate new nodes.
+ unsigned Pos = 0;
+ NodeRef Node[Nodes];
+ for (unsigned n = 0; n != Nodes; ++n) {
+ Branch *B = newNode<Branch>();
+ B->copy(rootBranch(), Pos, 0, Size[n]);
+ Node[n] = NodeRef(B, Size[n]);
+ Pos += Size[n];
+ }
+
+ for (unsigned n = 0; n != Nodes; ++n) {
+ rootBranch().stop(n) = Node[n].template get<Branch>().stop(Size[n]-1);
+ rootBranch().subtree(n) = Node[n];
+ }
+ rootSize = Nodes;
+ ++height;
+ return NewOffset;
+}
+
+/// visitNodes - Visit each external node.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+visitNodes(void (IntervalMap::*f)(IntervalMapImpl::NodeRef, unsigned Height)) {
+ if (!branched())
+ return;
+ SmallVector<IntervalMapImpl::NodeRef, 4> Refs, NextRefs;
+
+ // Collect level 0 nodes from the root.
+ for (unsigned i = 0; i != rootSize; ++i)
+ Refs.push_back(rootBranch().subtree(i));
+
+ // Visit all branch nodes.
+ for (unsigned h = height - 1; h; --h) {
+ for (unsigned i = 0, e = Refs.size(); i != e; ++i) {
+ for (unsigned j = 0, s = Refs[i].size(); j != s; ++j)
+ NextRefs.push_back(Refs[i].subtree(j));
+ (this->*f)(Refs[i], h);
+ }
+ Refs.clear();
+ Refs.swap(NextRefs);
+ }
+
+ // Visit all leaf nodes.
+ for (unsigned i = 0, e = Refs.size(); i != e; ++i)
+ (this->*f)(Refs[i], 0);
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+deleteNode(IntervalMapImpl::NodeRef Node, unsigned Level) {
+ if (Level)
+ deleteNode(&Node.get<Branch>());
+ else
+ deleteNode(&Node.get<Leaf>());
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+clear() {
+ if (branched()) {
+ visitNodes(&IntervalMap::deleteNode);
+ switchRootToLeaf();
+ }
+ rootSize = 0;
+}
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMap::const_iterator ----//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class IntervalMap<KeyT, ValT, N, Traits>::const_iterator :
+ public std::iterator<std::bidirectional_iterator_tag, ValT> {
+protected:
+ friend class IntervalMap;
+
+ // The map referred to.
+ IntervalMap *map;
+
+ // We store a full path from the root to the current position.
+ // The path may be partially filled, but never between iterator calls.
+ IntervalMapImpl::Path path;
+
+ explicit const_iterator(const IntervalMap &map) :
+ map(const_cast<IntervalMap*>(&map)) {}
+
+ bool branched() const {
+ assert(map && "Invalid iterator");
+ return map->branched();
+ }
+
+ void setRoot(unsigned Offset) {
+ if (branched())
+ path.setRoot(&map->rootBranch(), map->rootSize, Offset);
+ else
+ path.setRoot(&map->rootLeaf(), map->rootSize, Offset);
+ }
+
+ void pathFillFind(KeyT x);
+ void treeFind(KeyT x);
+ void treeAdvanceTo(KeyT x);
+
+ /// unsafeStart - Writable access to start() for iterator.
+ KeyT &unsafeStart() const {
+ assert(valid() && "Cannot access invalid iterator");
+ return branched() ? path.leaf<Leaf>().start(path.leafOffset()) :
+ path.leaf<RootLeaf>().start(path.leafOffset());
+ }
+
+ /// unsafeStop - Writable access to stop() for iterator.
+ KeyT &unsafeStop() const {
+ assert(valid() && "Cannot access invalid iterator");
+ return branched() ? path.leaf<Leaf>().stop(path.leafOffset()) :
+ path.leaf<RootLeaf>().stop(path.leafOffset());
+ }
+
+ /// unsafeValue - Writable access to value() for iterator.
+ ValT &unsafeValue() const {
+ assert(valid() && "Cannot access invalid iterator");
+ return branched() ? path.leaf<Leaf>().value(path.leafOffset()) :
+ path.leaf<RootLeaf>().value(path.leafOffset());
+ }
+
+public:
+ /// const_iterator - Create an iterator that isn't pointing anywhere.
+ const_iterator() : map(0) {}
+
+ /// valid - Return true if the current position is valid, false for end().
+ bool valid() const { return path.valid(); }
+
+ /// start - Return the beginning of the current interval.
+ const KeyT &start() const { return unsafeStart(); }
+
+ /// stop - Return the end of the current interval.
+ const KeyT &stop() const { return unsafeStop(); }
+
+ /// value - Return the mapped value at the current interval.
+ const ValT &value() const { return unsafeValue(); }
+
+ const ValT &operator*() const { return value(); }
+
+ bool operator==(const const_iterator &RHS) const {
+ assert(map == RHS.map && "Cannot compare iterators from different maps");
+ if (!valid())
+ return !RHS.valid();
+ if (path.leafOffset() != RHS.path.leafOffset())
+ return false;
+ return &path.template leaf<Leaf>() == &RHS.path.template leaf<Leaf>();
+ }
+
+ bool operator!=(const const_iterator &RHS) const {
+ return !operator==(RHS);
+ }
+
+ /// goToBegin - Move to the first interval in map.
+ void goToBegin() {
+ setRoot(0);
+ if (branched())
+ path.fillLeft(map->height);
+ }
+
+ /// goToEnd - Move beyond the last interval in map.
+ void goToEnd() {
+ setRoot(map->rootSize);
+ }
+
+ /// preincrement - move to the next interval.
+ const_iterator &operator++() {
+ assert(valid() && "Cannot increment end()");
+ if (++path.leafOffset() == path.leafSize() && branched())
+ path.moveRight(map->height);
+ return *this;
+ }
+
+ /// postincrement - Dont do that!
+ const_iterator operator++(int) {
+ const_iterator tmp = *this;
+ operator++();
+ return tmp;
+ }
+
+ /// predecrement - move to the previous interval.
+ const_iterator &operator--() {
+ if (path.leafOffset() && (valid() || !branched()))
+ --path.leafOffset();
+ else
+ path.moveLeft(map->height);
+ return *this;
+ }
+
+ /// postdecrement - Dont do that!
+ const_iterator operator--(int) {
+ const_iterator tmp = *this;
+ operator--();
+ return tmp;
+ }
+
+ /// find - Move to the first interval with stop >= x, or end().
+ /// This is a full search from the root, the current position is ignored.
+ void find(KeyT x) {
+ if (branched())
+ treeFind(x);
+ else
+ setRoot(map->rootLeaf().findFrom(0, map->rootSize, x));
+ }
+
+ /// advanceTo - Move to the first interval with stop >= x, or end().
+ /// The search is started from the current position, and no earlier positions
+ /// can be found. This is much faster than find() for small moves.
+ void advanceTo(KeyT x) {
+ if (!valid())
+ return;
+ if (branched())
+ treeAdvanceTo(x);
+ else
+ path.leafOffset() =
+ map->rootLeaf().findFrom(path.leafOffset(), map->rootSize, x);
+ }
+
+};
+
+/// pathFillFind - Complete path by searching for x.
+/// @param x Key to search for.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+const_iterator::pathFillFind(KeyT x) {
+ IntervalMapImpl::NodeRef NR = path.subtree(path.height());
+ for (unsigned i = map->height - path.height() - 1; i; --i) {
+ unsigned p = NR.get<Branch>().safeFind(0, x);
+ path.push(NR, p);
+ NR = NR.subtree(p);
+ }
+ path.push(NR, NR.get<Leaf>().safeFind(0, x));
+}
+
+/// treeFind - Find in a branched tree.
+/// @param x Key to search for.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+const_iterator::treeFind(KeyT x) {
+ setRoot(map->rootBranch().findFrom(0, map->rootSize, x));
+ if (valid())
+ pathFillFind(x);
+}
+
+/// treeAdvanceTo - Find position after the current one.
+/// @param x Key to search for.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+const_iterator::treeAdvanceTo(KeyT x) {
+ // Can we stay on the same leaf node?
+ if (!Traits::stopLess(path.leaf<Leaf>().stop(path.leafSize() - 1), x)) {
+ path.leafOffset() = path.leaf<Leaf>().safeFind(path.leafOffset(), x);
+ return;
+ }
+
+ // Drop the current leaf.
+ path.pop();
+
+ // Search towards the root for a usable subtree.
+ if (path.height()) {
+ for (unsigned l = path.height() - 1; l; --l) {
+ if (!Traits::stopLess(path.node<Branch>(l).stop(path.offset(l)), x)) {
+ // The branch node at l+1 is usable
+ path.offset(l + 1) =
+ path.node<Branch>(l + 1).safeFind(path.offset(l + 1), x);
+ return pathFillFind(x);
+ }
+ path.pop();
+ }
+ // Is the level-1 Branch usable?
+ if (!Traits::stopLess(map->rootBranch().stop(path.offset(0)), x)) {
+ path.offset(1) = path.node<Branch>(1).safeFind(path.offset(1), x);
+ return pathFillFind(x);
+ }
+ }
+
+ // We reached the root.
+ setRoot(map->rootBranch().findFrom(path.offset(0), map->rootSize, x));
+ if (valid())
+ pathFillFind(x);
+}
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMap::iterator ----//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class IntervalMap<KeyT, ValT, N, Traits>::iterator : public const_iterator {
+ friend class IntervalMap;
+ typedef IntervalMapImpl::IdxPair IdxPair;
+
+ explicit iterator(IntervalMap &map) : const_iterator(map) {}
+
+ void setNodeStop(unsigned Level, KeyT Stop);
+ bool insertNode(unsigned Level, IntervalMapImpl::NodeRef Node, KeyT Stop);
+ template <typename NodeT> bool overflow(unsigned Level);
+ void treeInsert(KeyT a, KeyT b, ValT y);
+ void eraseNode(unsigned Level);
+ void treeErase(bool UpdateRoot = true);
+ bool canCoalesceLeft(KeyT Start, ValT x);
+ bool canCoalesceRight(KeyT Stop, ValT x);
+
+public:
+ /// iterator - Create null iterator.
+ iterator() {}
+
+ /// setStart - Move the start of the current interval.
+ /// This may cause coalescing with the previous interval.
+ /// @param a New start key, must not overlap the previous interval.
+ void setStart(KeyT a);
+
+ /// setStop - Move the end of the current interval.
+ /// This may cause coalescing with the following interval.
+ /// @param b New stop key, must not overlap the following interval.
+ void setStop(KeyT b);
+
+ /// setValue - Change the mapped value of the current interval.
+ /// This may cause coalescing with the previous and following intervals.
+ /// @param x New value.
+ void setValue(ValT x);
+
+ /// setStartUnchecked - Move the start of the current interval without
+ /// checking for coalescing or overlaps.
+ /// This should only be used when it is known that coalescing is not required.
+ /// @param a New start key.
+ void setStartUnchecked(KeyT a) { this->unsafeStart() = a; }
+
+ /// setStopUnchecked - Move the end of the current interval without checking
+ /// for coalescing or overlaps.
+ /// This should only be used when it is known that coalescing is not required.
+ /// @param b New stop key.
+ void setStopUnchecked(KeyT b) {
+ this->unsafeStop() = b;
+ // Update keys in branch nodes as well.
+ if (this->path.atLastEntry(this->path.height()))
+ setNodeStop(this->path.height(), b);
+ }
+
+ /// setValueUnchecked - Change the mapped value of the current interval
+ /// without checking for coalescing.
+ /// @param x New value.
+ void setValueUnchecked(ValT x) { this->unsafeValue() = x; }
+
+ /// insert - Insert mapping [a;b] -> y before the current position.
+ void insert(KeyT a, KeyT b, ValT y);
+
+ /// erase - Erase the current interval.
+ void erase();
+
+ iterator &operator++() {
+ const_iterator::operator++();
+ return *this;
+ }
+
+ iterator operator++(int) {
+ iterator tmp = *this;
+ operator++();
+ return tmp;
+ }
+
+ iterator &operator--() {
+ const_iterator::operator--();
+ return *this;
+ }
+
+ iterator operator--(int) {
+ iterator tmp = *this;
+ operator--();
+ return tmp;
+ }
+
+};
+
+/// canCoalesceLeft - Can the current interval coalesce to the left after
+/// changing start or value?
+/// @param Start New start of current interval.
+/// @param Value New value for current interval.
+/// @return True when updating the current interval would enable coalescing.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::canCoalesceLeft(KeyT Start, ValT Value) {
+ using namespace IntervalMapImpl;
+ Path &P = this->path;
+ if (!this->branched()) {
+ unsigned i = P.leafOffset();
+ RootLeaf &Node = P.leaf<RootLeaf>();
+ return i && Node.value(i-1) == Value &&
+ Traits::adjacent(Node.stop(i-1), Start);
+ }
+ // Branched.
+ if (unsigned i = P.leafOffset()) {
+ Leaf &Node = P.leaf<Leaf>();
+ return Node.value(i-1) == Value && Traits::adjacent(Node.stop(i-1), Start);
+ } else if (NodeRef NR = P.getLeftSibling(P.height())) {
+ unsigned i = NR.size() - 1;
+ Leaf &Node = NR.get<Leaf>();
+ return Node.value(i) == Value && Traits::adjacent(Node.stop(i), Start);
+ }
+ return false;
+}
+
+/// canCoalesceRight - Can the current interval coalesce to the right after
+/// changing stop or value?
+/// @param Stop New stop of current interval.
+/// @param Value New value for current interval.
+/// @return True when updating the current interval would enable coalescing.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::canCoalesceRight(KeyT Stop, ValT Value) {
+ using namespace IntervalMapImpl;
+ Path &P = this->path;
+ unsigned i = P.leafOffset() + 1;
+ if (!this->branched()) {
+ if (i >= P.leafSize())
+ return false;
+ RootLeaf &Node = P.leaf<RootLeaf>();
+ return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
+ }
+ // Branched.
+ if (i < P.leafSize()) {
+ Leaf &Node = P.leaf<Leaf>();
+ return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
+ } else if (NodeRef NR = P.getRightSibling(P.height())) {
+ Leaf &Node = NR.get<Leaf>();
+ return Node.value(0) == Value && Traits::adjacent(Stop, Node.start(0));
+ }
+ return false;
+}
+
+/// setNodeStop - Update the stop key of the current node at level and above.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setNodeStop(unsigned Level, KeyT Stop) {
+ // There are no references to the root node, so nothing to update.
+ if (!Level)
+ return;
+ IntervalMapImpl::Path &P = this->path;
+ // Update nodes pointing to the current node.
+ while (--Level) {
+ P.node<Branch>(Level).stop(P.offset(Level)) = Stop;
+ if (!P.atLastEntry(Level))
+ return;
+ }
+ // Update root separately since it has a different layout.
+ P.node<RootBranch>(Level).stop(P.offset(Level)) = Stop;
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setStart(KeyT a) {
+ assert(Traits::stopLess(a, this->stop()) && "Cannot move start beyond stop");
+ KeyT &CurStart = this->unsafeStart();
+ if (!Traits::startLess(a, CurStart) || !canCoalesceLeft(a, this->value())) {
+ CurStart = a;
+ return;
+ }
+ // Coalesce with the interval to the left.
+ --*this;
+ a = this->start();
+ erase();
+ setStartUnchecked(a);
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setStop(KeyT b) {
+ assert(Traits::stopLess(this->start(), b) && "Cannot move stop beyond start");
+ if (Traits::startLess(b, this->stop()) ||
+ !canCoalesceRight(b, this->value())) {
+ setStopUnchecked(b);
+ return;
+ }
+ // Coalesce with interval to the right.
+ KeyT a = this->start();
+ erase();
+ setStartUnchecked(a);
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setValue(ValT x) {
+ setValueUnchecked(x);
+ if (canCoalesceRight(this->stop(), x)) {
+ KeyT a = this->start();
+ erase();
+ setStartUnchecked(a);
+ }
+ if (canCoalesceLeft(this->start(), x)) {
+ --*this;
+ KeyT a = this->start();
+ erase();
+ setStartUnchecked(a);
+ }
+}
+
+/// insertNode - insert a node before the current path at level.
+/// Leave the current path pointing at the new node.
+/// @param Level path index of the node to be inserted.
+/// @param Node The node to be inserted.
+/// @param Stop The last index in the new node.
+/// @return True if the tree height was increased.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::insertNode(unsigned Level, IntervalMapImpl::NodeRef Node, KeyT Stop) {
+ assert(Level && "Cannot insert next to the root");
+ bool SplitRoot = false;
+ IntervalMap &IM = *this->map;
+ IntervalMapImpl::Path &P = this->path;
+
+ if (Level == 1) {
+ // Insert into the root branch node.
+ if (IM.rootSize < RootBranch::Capacity) {
+ IM.rootBranch().insert(P.offset(0), IM.rootSize, Node, Stop);
+ P.setSize(0, ++IM.rootSize);
+ P.reset(Level);
+ return SplitRoot;
+ }
+
+ // We need to split the root while keeping our position.
+ SplitRoot = true;
+ IdxPair Offset = IM.splitRoot(P.offset(0));
+ P.replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
+
+ // Fall through to insert at the new higher level.
+ ++Level;
+ }
+
+ // When inserting before end(), make sure we have a valid path.
+ P.legalizeForInsert(--Level);
+
+ // Insert into the branch node at Level-1.
+ if (P.size(Level) == Branch::Capacity) {
+ // Branch node is full, handle handle the overflow.
+ assert(!SplitRoot && "Cannot overflow after splitting the root");
+ SplitRoot = overflow<Branch>(Level);
+ Level += SplitRoot;
+ }
+ P.node<Branch>(Level).insert(P.offset(Level), P.size(Level), Node, Stop);
+ P.setSize(Level, P.size(Level) + 1);
+ if (P.atLastEntry(Level))
+ setNodeStop(Level, Stop);
+ P.reset(Level + 1);
+ return SplitRoot;
+}
+
+// insert
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::insert(KeyT a, KeyT b, ValT y) {
+ if (this->branched())
+ return treeInsert(a, b, y);
+ IntervalMap &IM = *this->map;
+ IntervalMapImpl::Path &P = this->path;
+
+ // Try simple root leaf insert.
+ unsigned Size = IM.rootLeaf().insertFrom(P.leafOffset(), IM.rootSize, a, b, y);
+
+ // Was the root node insert successful?
+ if (Size <= RootLeaf::Capacity) {
+ P.setSize(0, IM.rootSize = Size);
+ return;
+ }
+
+ // Root leaf node is full, we must branch.
+ IdxPair Offset = IM.branchRoot(P.leafOffset());
+ P.replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
+
+ // Now it fits in the new leaf.
+ treeInsert(a, b, y);
+}
+
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::treeInsert(KeyT a, KeyT b, ValT y) {
+ using namespace IntervalMapImpl;
+ Path &P = this->path;
+
+ if (!P.valid())
+ P.legalizeForInsert(this->map->height);
+
+ // Check if this insertion will extend the node to the left.
+ if (P.leafOffset() == 0 && Traits::startLess(a, P.leaf<Leaf>().start(0))) {
+ // Node is growing to the left, will it affect a left sibling node?
+ if (NodeRef Sib = P.getLeftSibling(P.height())) {
+ Leaf &SibLeaf = Sib.get<Leaf>();
+ unsigned SibOfs = Sib.size() - 1;
+ if (SibLeaf.value(SibOfs) == y &&
+ Traits::adjacent(SibLeaf.stop(SibOfs), a)) {
+ // This insertion will coalesce with the last entry in SibLeaf. We can
+ // handle it in two ways:
+ // 1. Extend SibLeaf.stop to b and be done, or
+ // 2. Extend a to SibLeaf, erase the SibLeaf entry and continue.
+ // We prefer 1., but need 2 when coalescing to the right as well.
+ Leaf &CurLeaf = P.leaf<Leaf>();
+ P.moveLeft(P.height());
+ if (Traits::stopLess(b, CurLeaf.start(0)) &&
+ (y != CurLeaf.value(0) || !Traits::adjacent(b, CurLeaf.start(0)))) {
+ // Easy, just extend SibLeaf and we're done.
+ setNodeStop(P.height(), SibLeaf.stop(SibOfs) = b);
+ return;
+ } else {
+ // We have both left and right coalescing. Erase the old SibLeaf entry
+ // and continue inserting the larger interval.
+ a = SibLeaf.start(SibOfs);
+ treeErase(/* UpdateRoot= */false);
+ }
+ }
+ } else {
+ // No left sibling means we are at begin(). Update cached bound.
+ this->map->rootBranchStart() = a;
+ }
+ }
+
+ // When we are inserting at the end of a leaf node, we must update stops.
+ unsigned Size = P.leafSize();
+ bool Grow = P.leafOffset() == Size;
+ Size = P.leaf<Leaf>().insertFrom(P.leafOffset(), Size, a, b, y);
+
+ // Leaf insertion unsuccessful? Overflow and try again.
+ if (Size > Leaf::Capacity) {
+ overflow<Leaf>(P.height());
+ Grow = P.leafOffset() == P.leafSize();
+ Size = P.leaf<Leaf>().insertFrom(P.leafOffset(), P.leafSize(), a, b, y);
+ assert(Size <= Leaf::Capacity && "overflow() didn't make room");
+ }
+
+ // Inserted, update offset and leaf size.
+ P.setSize(P.height(), Size);
+
+ // Insert was the last node entry, update stops.
+ if (Grow)
+ setNodeStop(P.height(), b);
+}
+
+/// erase - erase the current interval and move to the next position.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::erase() {
+ IntervalMap &IM = *this->map;
+ IntervalMapImpl::Path &P = this->path;
+ assert(P.valid() && "Cannot erase end()");
+ if (this->branched())
+ return treeErase();
+ IM.rootLeaf().erase(P.leafOffset(), IM.rootSize);
+ P.setSize(0, --IM.rootSize);
+}
+
+/// treeErase - erase() for a branched tree.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::treeErase(bool UpdateRoot) {
+ IntervalMap &IM = *this->map;
+ IntervalMapImpl::Path &P = this->path;
+ Leaf &Node = P.leaf<Leaf>();
+
+ // Nodes are not allowed to become empty.
+ if (P.leafSize() == 1) {
+ IM.deleteNode(&Node);
+ eraseNode(IM.height);
+ // Update rootBranchStart if we erased begin().
+ if (UpdateRoot && IM.branched() && P.valid() && P.atBegin())
+ IM.rootBranchStart() = P.leaf<Leaf>().start(0);
+ return;
+ }
+
+ // Erase current entry.
+ Node.erase(P.leafOffset(), P.leafSize());
+ unsigned NewSize = P.leafSize() - 1;
+ P.setSize(IM.height, NewSize);
+ // When we erase the last entry, update stop and move to a legal position.
+ if (P.leafOffset() == NewSize) {
+ setNodeStop(IM.height, Node.stop(NewSize - 1));
+ P.moveRight(IM.height);
+ } else if (UpdateRoot && P.atBegin())
+ IM.rootBranchStart() = P.leaf<Leaf>().start(0);
+}
+
+/// eraseNode - Erase the current node at Level from its parent and move path to
+/// the first entry of the next sibling node.
+/// The node must be deallocated by the caller.
+/// @param Level 1..height, the root node cannot be erased.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::eraseNode(unsigned Level) {
+ assert(Level && "Cannot erase root node");
+ IntervalMap &IM = *this->map;
+ IntervalMapImpl::Path &P = this->path;
+
+ if (--Level == 0) {
+ IM.rootBranch().erase(P.offset(0), IM.rootSize);
+ P.setSize(0, --IM.rootSize);
+ // If this cleared the root, switch to height=0.
+ if (IM.empty()) {
+ IM.switchRootToLeaf();
+ this->setRoot(0);
+ return;
+ }
+ } else {
+ // Remove node ref from branch node at Level.
+ Branch &Parent = P.node<Branch>(Level);
+ if (P.size(Level) == 1) {
+ // Branch node became empty, remove it recursively.
+ IM.deleteNode(&Parent);
+ eraseNode(Level);
+ } else {
+ // Branch node won't become empty.
+ Parent.erase(P.offset(Level), P.size(Level));
+ unsigned NewSize = P.size(Level) - 1;
+ P.setSize(Level, NewSize);
+ // If we removed the last branch, update stop and move to a legal pos.
+ if (P.offset(Level) == NewSize) {
+ setNodeStop(Level, Parent.stop(NewSize - 1));
+ P.moveRight(Level);
+ }
+ }
+ }
+ // Update path cache for the new right sibling position.
+ if (P.valid()) {
+ P.reset(Level + 1);
+ P.offset(Level + 1) = 0;
+ }
+}
+
+/// overflow - Distribute entries of the current node evenly among
+/// its siblings and ensure that the current node is not full.
+/// This may require allocating a new node.
+/// @param NodeT The type of node at Level (Leaf or Branch).
+/// @param Level path index of the overflowing node.
+/// @return True when the tree height was changed.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+template <typename NodeT>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::overflow(unsigned Level) {
+ using namespace IntervalMapImpl;
+ Path &P = this->path;
+ unsigned CurSize[4];
+ NodeT *Node[4];
+ unsigned Nodes = 0;
+ unsigned Elements = 0;
+ unsigned Offset = P.offset(Level);
+
+ // Do we have a left sibling?
+ NodeRef LeftSib = P.getLeftSibling(Level);
+ if (LeftSib) {
+ Offset += Elements = CurSize[Nodes] = LeftSib.size();
+ Node[Nodes++] = &LeftSib.get<NodeT>();
+ }
+
+ // Current node.
+ Elements += CurSize[Nodes] = P.size(Level);
+ Node[Nodes++] = &P.node<NodeT>(Level);
+
+ // Do we have a right sibling?
+ NodeRef RightSib = P.getRightSibling(Level);
+ if (RightSib) {
+ Elements += CurSize[Nodes] = RightSib.size();
+ Node[Nodes++] = &RightSib.get<NodeT>();
+ }
+
+ // Do we need to allocate a new node?
+ unsigned NewNode = 0;
+ if (Elements + 1 > Nodes * NodeT::Capacity) {
+ // Insert NewNode at the penultimate position, or after a single node.
+ NewNode = Nodes == 1 ? 1 : Nodes - 1;
+ CurSize[Nodes] = CurSize[NewNode];
+ Node[Nodes] = Node[NewNode];
+ CurSize[NewNode] = 0;
+ Node[NewNode] = this->map->newNode<NodeT>();
+ ++Nodes;
+ }
+
+ // Compute the new element distribution.
+ unsigned NewSize[4];
+ IdxPair NewOffset = distribute(Nodes, Elements, NodeT::Capacity,
+ CurSize, NewSize, Offset, true);
+ adjustSiblingSizes(Node, Nodes, CurSize, NewSize);
+
+ // Move current location to the leftmost node.
+ if (LeftSib)
+ P.moveLeft(Level);
+
+ // Elements have been rearranged, now update node sizes and stops.
+ bool SplitRoot = false;
+ unsigned Pos = 0;
+ for (;;) {
+ KeyT Stop = Node[Pos]->stop(NewSize[Pos]-1);
+ if (NewNode && Pos == NewNode) {
+ SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop);
+ Level += SplitRoot;
+ } else {
+ P.setSize(Level, NewSize[Pos]);
+ setNodeStop(Level, Stop);
+ }
+ if (Pos + 1 == Nodes)
+ break;
+ P.moveRight(Level);
+ ++Pos;
+ }
+
+ // Where was I? Find NewOffset.
+ while(Pos != NewOffset.first) {
+ P.moveLeft(Level);
+ --Pos;
+ }
+ P.offset(Level) = NewOffset.second;
+ return SplitRoot;
+}
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapOverlaps ----//
+//===----------------------------------------------------------------------===//
+
+/// IntervalMapOverlaps - Iterate over the overlaps of mapped intervals in two
+/// IntervalMaps. The maps may be different, but the KeyT and Traits types
+/// should be the same.
+///
+/// Typical uses:
+///
+/// 1. Test for overlap:
+/// bool overlap = IntervalMapOverlaps(a, b).valid();
+///
+/// 2. Enumerate overlaps:
+/// for (IntervalMapOverlaps I(a, b); I.valid() ; ++I) { ... }
+///
+template <typename MapA, typename MapB>
+class IntervalMapOverlaps {
+ typedef typename MapA::KeyType KeyType;
+ typedef typename MapA::KeyTraits Traits;
+ typename MapA::const_iterator posA;
+ typename MapB::const_iterator posB;
+
+ /// advance - Move posA and posB forward until reaching an overlap, or until
+ /// either meets end.
+ /// Don't move the iterators if they are already overlapping.
+ void advance() {
+ if (!valid())
+ return;
+
+ if (Traits::stopLess(posA.stop(), posB.start())) {
+ // A ends before B begins. Catch up.
+ posA.advanceTo(posB.start());
+ if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
+ return;
+ } else if (Traits::stopLess(posB.stop(), posA.start())) {
+ // B ends before A begins. Catch up.
+ posB.advanceTo(posA.start());
+ if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
+ return;
+ } else
+ // Already overlapping.
+ return;
+
+ for (;;) {
+ // Make a.end > b.start.
+ posA.advanceTo(posB.start());
+ if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
+ return;
+ // Make b.end > a.start.
+ posB.advanceTo(posA.start());
+ if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
+ return;
+ }
+ }
+
+public:
+ /// IntervalMapOverlaps - Create an iterator for the overlaps of a and b.
+ IntervalMapOverlaps(const MapA &a, const MapB &b)
+ : posA(b.empty() ? a.end() : a.find(b.start())),
+ posB(posA.valid() ? b.find(posA.start()) : b.end()) { advance(); }
+
+ /// valid - Return true if iterator is at an overlap.
+ bool valid() const {
+ return posA.valid() && posB.valid();
+ }
+
+ /// a - access the left hand side in the overlap.
+ const typename MapA::const_iterator &a() const { return posA; }
+
+ /// b - access the right hand side in the overlap.
+ const typename MapB::const_iterator &b() const { return posB; }
+
+ /// start - Beginning of the overlapping interval.
+ KeyType start() const {
+ KeyType ak = a().start();
+ KeyType bk = b().start();
+ return Traits::startLess(ak, bk) ? bk : ak;
+ }
+
+ /// stop - End of the overlapping interval.
+ KeyType stop() const {
+ KeyType ak = a().stop();
+ KeyType bk = b().stop();
+ return Traits::startLess(ak, bk) ? ak : bk;
+ }
+
+ /// skipA - Move to the next overlap that doesn't involve a().
+ void skipA() {
+ ++posA;
+ advance();
+ }
+
+ /// skipB - Move to the next overlap that doesn't involve b().
+ void skipB() {
+ ++posB;
+ advance();
+ }
+
+ /// Preincrement - Move to the next overlap.
+ IntervalMapOverlaps &operator++() {
+ // Bump the iterator that ends first. The other one may have more overlaps.
+ if (Traits::startLess(posB.stop(), posA.stop()))
+ skipB();
+ else
+ skipA();
+ return *this;
+ }
+
+ /// advanceTo - Move to the first overlapping interval with
+ /// stopLess(x, stop()).
+ void advanceTo(KeyType x) {
+ if (!valid())
+ return;
+ // Make sure advanceTo sees monotonic keys.
+ if (Traits::stopLess(posA.stop(), x))
+ posA.advanceTo(x);
+ if (Traits::stopLess(posB.stop(), x))
+ posB.advanceTo(x);
+ advance();
+ }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h
index 34e54a07a0..ee8b69f3d1 100644
--- a/include/llvm/ADT/Optional.h
+++ b/include/llvm/ADT/Optional.h
@@ -61,6 +61,60 @@ template <typename T>
struct simplify_type<Optional<T> >
: public simplify_type<const Optional<T> > {};
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator==(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator!=(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator<(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator<=(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator>=(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator>(const Optional<T> &X, const Optional<U> &Y);
+
} // end llvm namespace
#endif
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h
index 64f4a7cee4..85dbba2b4a 100644
--- a/include/llvm/ADT/PointerIntPair.h
+++ b/include/llvm/ADT/PointerIntPair.h
@@ -91,6 +91,13 @@ public:
Value |= IntVal << IntShift; // Set new integer.
}
+ PointerTy const *getAddrOfPointer() const {
+ assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
+ "Can only return the address if IntBits is cleared and "
+ "PtrTraits doesn't change the pointer");
+ return reinterpret_cast<PointerTy const *>(&Value);
+ }
+
void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h
index 3a514b5626..61de042b0f 100644
--- a/include/llvm/ADT/PointerUnion.h
+++ b/include/llvm/ADT/PointerUnion.h
@@ -107,6 +107,18 @@ namespace llvm {
if (is<T>()) return get<T>();
return T();
}
+
+ /// \brief If the union is set to the first pointer type we can get an
+ /// address pointing to it.
+ template <typename T>
+ PT1 const *getAddrOf() const {
+ assert(is<PT1>() && "Val is not the first pointer");
+ assert(get<PT1>() == Val.getPointer() &&
+ "Can't get the address because PointerLikeTypeTraits changes the ptr");
+ T const *can_only_get_address_of_first_pointer_type
+ = reinterpret_cast<PT1 const *>(Val.getAddrOfPointer());
+ return can_only_get_address_of_first_pointer_type;
+ }
/// Assignment operators - Allow assigning into this union from either
/// pointer type, setting the discriminator to remember what it came from.
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
index 47e5b2bd4a..e3b499488d 100644
--- a/include/llvm/ADT/PostOrderIterator.h
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -56,8 +56,7 @@ class po_iterator : public std::iterator<std::forward_iterator_tag,
void traverseChild() {
while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
NodeType *BB = *VisitStack.back().second++;
- if (!this->Visited.count(BB)) { // If the block is not visited...
- this->Visited.insert(BB);
+ if (this->Visited.insert(BB)) { // If the block is not visited...
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
}
}
@@ -72,8 +71,7 @@ class po_iterator : public std::iterator<std::forward_iterator_tag,
inline po_iterator(NodeType *BB, SetType &S) :
po_iterator_storage<SetType, ExtStorage>(S) {
- if(!S.count(BB)) {
- this->Visited.insert(BB);
+ if (this->Visited.insert(BB)) {
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
traverseChild();
}
diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h
index c49d599cf3..3e93cfe914 100644
--- a/include/llvm/ADT/SCCIterator.h
+++ b/include/llvm/ADT/SCCIterator.h
@@ -60,7 +60,7 @@ class scc_iterator
// First element is basic block pointer, second is the 'next child' to visit
std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
- // MinVistNumStack - Stack holding the "min" values for each node in the DFS.
+ // 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;
diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h
index c96ad19707..a6803ee0ed 100644
--- a/include/llvm/ADT/ScopedHashTable.h
+++ b/include/llvm/ADT/ScopedHashTable.h
@@ -31,25 +31,23 @@
#ifndef LLVM_ADT_SCOPEDHASHTABLE_H
#define LLVM_ADT_SCOPEDHASHTABLE_H
-#include <cassert>
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
namespace llvm {
-template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
+template <typename K, typename V, typename KInfo = DenseMapInfo<K>,
+ typename AllocatorTy = MallocAllocator>
class ScopedHashTable;
-template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
+template <typename K, typename V>
class ScopedHashTableVal {
ScopedHashTableVal *NextInScope;
ScopedHashTableVal *NextForKey;
K Key;
V Val;
+ ScopedHashTableVal(const K &key, const V &val) : Key(key), Val(val) {}
public:
- ScopedHashTableVal(ScopedHashTableVal *nextInScope,
- ScopedHashTableVal *nextForKey, const K &key, const V &val)
- : NextInScope(nextInScope), NextForKey(nextForKey), Key(key), Val(val) {
- }
const K &getKey() const { return Key; }
const V &getValue() const { return Val; }
@@ -57,33 +55,56 @@ public:
ScopedHashTableVal *getNextForKey() { return NextForKey; }
const ScopedHashTableVal *getNextForKey() const { return NextForKey; }
-public:
ScopedHashTableVal *getNextInScope() { return NextInScope; }
+
+ template <typename AllocatorTy>
+ static ScopedHashTableVal *Create(ScopedHashTableVal *nextInScope,
+ ScopedHashTableVal *nextForKey,
+ const K &key, const V &val,
+ AllocatorTy &Allocator) {
+ ScopedHashTableVal *New = Allocator.template Allocate<ScopedHashTableVal>();
+ // Set up the value.
+ new (New) ScopedHashTableVal(key, val);
+ New->NextInScope = nextInScope;
+ New->NextForKey = nextForKey;
+ return New;
+ }
+
+ template <typename AllocatorTy>
+ void Destroy(AllocatorTy &Allocator) {
+ // Free memory referenced by the item.
+ this->~ScopedHashTableVal();
+ Allocator.Deallocate(this);
+ }
};
-template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
+template <typename K, typename V, typename KInfo = DenseMapInfo<K>,
+ typename AllocatorTy = MallocAllocator>
class ScopedHashTableScope {
/// HT - The hashtable that we are active for.
- ScopedHashTable<K, V, KInfo> &HT;
+ ScopedHashTable<K, V, KInfo, AllocatorTy> &HT;
/// PrevScope - This is the scope that we are shadowing in HT.
ScopedHashTableScope *PrevScope;
/// LastValInScope - This is the last value that was inserted for this scope
/// or null if none have been inserted yet.
- ScopedHashTableVal<K, V, KInfo> *LastValInScope;
+ ScopedHashTableVal<K, V> *LastValInScope;
void operator=(ScopedHashTableScope&); // DO NOT IMPLEMENT
ScopedHashTableScope(ScopedHashTableScope&); // DO NOT IMPLEMENT
public:
- ScopedHashTableScope(ScopedHashTable<K, V, KInfo> &HT);
+ ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT);
~ScopedHashTableScope();
+ ScopedHashTableScope *getParentScope() { return PrevScope; }
+ const ScopedHashTableScope *getParentScope() const { return PrevScope; }
+
private:
- friend class ScopedHashTable<K, V, KInfo>;
- ScopedHashTableVal<K, V, KInfo> *getLastValInScope() {
+ friend class ScopedHashTable<K, V, KInfo, AllocatorTy>;
+ ScopedHashTableVal<K, V> *getLastValInScope() {
return LastValInScope;
}
- void setLastValInScope(ScopedHashTableVal<K, V, KInfo> *Val) {
+ void setLastValInScope(ScopedHashTableVal<K, V> *Val) {
LastValInScope = Val;
}
};
@@ -91,9 +112,9 @@ private:
template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
class ScopedHashTableIterator {
- ScopedHashTableVal<K, V, KInfo> *Node;
+ ScopedHashTableVal<K, V> *Node;
public:
- ScopedHashTableIterator(ScopedHashTableVal<K, V, KInfo> *node) : Node(node) {}
+ ScopedHashTableIterator(ScopedHashTableVal<K, V> *node) : Node(node) {}
V &operator*() const {
assert(Node && "Dereference end()");
@@ -121,26 +142,42 @@ public:
};
-template <typename K, typename V, typename KInfo>
+template <typename K, typename V, typename KInfo, typename AllocatorTy>
class ScopedHashTable {
- DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo> TopLevelMap;
- ScopedHashTableScope<K, V, KInfo> *CurScope;
+public:
+ /// ScopeTy - This is a helpful typedef that allows clients to get easy access
+ /// to the name of the scope for this hash table.
+ typedef ScopedHashTableScope<K, V, KInfo, AllocatorTy> ScopeTy;
+private:
+ typedef ScopedHashTableVal<K, V> ValTy;
+ DenseMap<K, ValTy*, KInfo> TopLevelMap;
+ ScopeTy *CurScope;
+
+ AllocatorTy Allocator;
+
ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED
void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED
- friend class ScopedHashTableScope<K, V, KInfo>;
+ friend class ScopedHashTableScope<K, V, KInfo, AllocatorTy>;
public:
ScopedHashTable() : CurScope(0) {}
+ ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {}
~ScopedHashTable() {
assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!");
}
+
+
+ /// Access to the allocator.
+ typedef typename ReferenceAdder<AllocatorTy>::result AllocatorRefTy;
+ typedef typename ReferenceAdder<const AllocatorTy>::result AllocatorCRefTy;
+ AllocatorRefTy getAllocator() { return Allocator; }
+ AllocatorCRefTy getAllocator() const { return Allocator; }
bool count(const K &Key) const {
return TopLevelMap.count(Key);
}
V lookup(const K &Key) {
- typename DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo>::iterator
- I = TopLevelMap.find(Key);
+ typename DenseMap<K, ValTy*, KInfo>::iterator I = TopLevelMap.find(Key);
if (I != TopLevelMap.end())
return I->second->getValue();
@@ -148,13 +185,7 @@ public:
}
void insert(const K &Key, const V &Val) {
- assert(CurScope && "No scope active!");
-
- ScopedHashTableVal<K, V, KInfo> *&KeyEntry = TopLevelMap[Key];
-
- KeyEntry= new ScopedHashTableVal<K, V, KInfo>(CurScope->getLastValInScope(),
- KeyEntry, Key, Val);
- CurScope->setLastValInScope(KeyEntry);
+ insertIntoScope(CurScope, Key, Val);
}
typedef ScopedHashTableIterator<K, V, KInfo> iterator;
@@ -162,38 +193,52 @@ public:
iterator end() { return iterator(0); }
iterator begin(const K &Key) {
- typename DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo>::iterator I =
+ typename DenseMap<K, ValTy*, KInfo>::iterator I =
TopLevelMap.find(Key);
if (I == TopLevelMap.end()) return end();
return iterator(I->second);
}
+
+ ScopeTy *getCurScope() { return CurScope; }
+ const ScopeTy *getCurScope() const { return CurScope; }
+
+ /// insertIntoScope - This inserts the specified key/value at the specified
+ /// (possibly not the current) scope. While it is ok to insert into a scope
+ /// that isn't the current one, it isn't ok to insert *underneath* an existing
+ /// value of the specified key.
+ void insertIntoScope(ScopeTy *S, const K &Key, const V &Val) {
+ assert(S && "No scope active!");
+ ScopedHashTableVal<K, V> *&KeyEntry = TopLevelMap[Key];
+ KeyEntry = ValTy::Create(S->getLastValInScope(), KeyEntry, Key, Val,
+ Allocator);
+ S->setLastValInScope(KeyEntry);
+ }
};
/// ScopedHashTableScope ctor - Install this as the current scope for the hash
/// table.
-template <typename K, typename V, typename KInfo>
-ScopedHashTableScope<K, V, KInfo>::
- ScopedHashTableScope(ScopedHashTable<K, V, KInfo> &ht) : HT(ht) {
+template <typename K, typename V, typename KInfo, typename Allocator>
+ScopedHashTableScope<K, V, KInfo, Allocator>::
+ ScopedHashTableScope(ScopedHashTable<K, V, KInfo, Allocator> &ht) : HT(ht) {
PrevScope = HT.CurScope;
HT.CurScope = this;
LastValInScope = 0;
}
-template <typename K, typename V, typename KInfo>
-ScopedHashTableScope<K, V, KInfo>::~ScopedHashTableScope() {
+template <typename K, typename V, typename KInfo, typename Allocator>
+ScopedHashTableScope<K, V, KInfo, Allocator>::~ScopedHashTableScope() {
assert(HT.CurScope == this && "Scope imbalance!");
HT.CurScope = PrevScope;
// Pop and delete all values corresponding to this scope.
- while (ScopedHashTableVal<K, V, KInfo> *ThisEntry = LastValInScope) {
+ while (ScopedHashTableVal<K, V> *ThisEntry = LastValInScope) {
// Pop this value out of the TopLevelMap.
if (ThisEntry->getNextForKey() == 0) {
assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry &&
"Scope imbalance!");
HT.TopLevelMap.erase(ThisEntry->getKey());
} else {
- ScopedHashTableVal<K, V, KInfo> *&KeyEntry =
- HT.TopLevelMap[ThisEntry->getKey()];
+ ScopedHashTableVal<K, V> *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()];
assert(KeyEntry == ThisEntry && "Scope imbalance!");
KeyEntry = ThisEntry->getNextForKey();
}
@@ -202,7 +247,7 @@ ScopedHashTableScope<K, V, KInfo>::~ScopedHashTableScope() {
LastValInScope = ThisEntry->getNextInScope();
// Delete this entry.
- delete ThisEntry;
+ ThisEntry->Destroy(HT.getAllocator());
}
}
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index 424bdba5a2..ff32ba87a2 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -16,9 +16,10 @@
#define LLVM_ADT_SMALLPTRSET_H
#include <cassert>
+#include <cstddef>
#include <cstring>
#include <iterator>
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
namespace llvm {
@@ -56,7 +57,7 @@ protected:
/// it, so that the end iterator actually points to valid memory.
unsigned CurArraySize;
- // If small, this is # elts allocated consequtively
+ // If small, this is # elts allocated consecutively
unsigned NumElements;
unsigned NumTombstones;
diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h
index 05bd8a42c6..da26416482 100644
--- a/include/llvm/ADT/SmallString.h
+++ b/include/llvm/ADT/SmallString.h
@@ -27,6 +27,9 @@ public:
// Default ctor - Initialize to empty.
SmallString() {}
+ // Initialize from a StringRef.
+ SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
+
// Initialize with a range.
template<typename ItTy>
SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
@@ -38,15 +41,16 @@ public:
// Extra methods.
StringRef str() const { return StringRef(this->begin(), this->size()); }
- // Implicit conversion to StringRef.
- operator StringRef() const { return str(); }
-
- const char *c_str() {
+ // TODO: Make this const, if it's safe...
+ const char* c_str() {
this->push_back(0);
this->pop_back();
return this->data();
}
+ // Implicit conversion to StringRef.
+ operator StringRef() const { return str(); }
+
// Extra operators.
const SmallString &operator=(StringRef RHS) {
this->clear();
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 10ae049ff9..8b0a13d6ed 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -20,6 +20,7 @@
#include <cstddef>
#include <cstdlib>
#include <cstring>
+#include <iterator>
#include <memory>
#ifdef _MSC_VER
@@ -88,7 +89,7 @@ protected:
}
/// grow_pod - This is an implementation of the grow() method which only works
- /// on POD-like datatypes and is out of line to reduce code duplication.
+ /// on POD-like data types and is out of line to reduce code duplication.
void grow_pod(size_t MinSizeInBytes, size_t TSize);
public:
@@ -263,7 +264,7 @@ public:
template <typename T>
class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
-
+
SmallVectorImpl(const SmallVectorImpl&); // DISABLED.
public:
typedef typename SuperClass::iterator iterator;
@@ -340,7 +341,6 @@ public:
return Result;
}
-
void swap(SmallVectorImpl &RHS);
/// append - Add the specified range to the end of the SmallVector.
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
index 0862981887..d977136b2f 100644
--- a/include/llvm/ADT/SparseBitVector.h
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -17,7 +17,7 @@
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h
index 3a1319f109..fda99c6edb 100644
--- a/include/llvm/ADT/Statistic.h
+++ b/include/llvm/ADT/Statistic.h
@@ -26,7 +26,7 @@
#ifndef LLVM_ADT_STATISTIC_H
#define LLVM_ADT_STATISTIC_H
-#include "llvm/System/Atomic.h"
+#include "llvm/Support/Atomic.h"
namespace llvm {
class raw_ostream;
@@ -121,6 +121,9 @@ protected:
/// \brief Enable the collection and printing of statistics.
void EnableStatistics();
+/// \brief Check if statistics are enabled.
+bool AreStatisticsEnabled();
+
/// \brief Print statistics to the file returned by CreateInfoOutputFile().
void PrintStatistics();
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
index 3c53adee63..acbed66ef4 100644
--- a/include/llvm/ADT/StringExtras.h
+++ b/include/llvm/ADT/StringExtras.h
@@ -14,7 +14,7 @@
#ifndef LLVM_ADT_STRINGEXTRAS_H
#define LLVM_ADT_STRINGEXTRAS_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/StringRef.h"
#include <cctype>
@@ -25,10 +25,11 @@
namespace llvm {
template<typename T> class SmallVectorImpl;
-/// hexdigit - Return the (uppercase) hexadecimal character for the
+/// hexdigit - Return the hexadecimal character for the
/// given number \arg X (which should be less than 16).
-static inline char hexdigit(unsigned X) {
- return X < 10 ? '0' + X : 'A' + X - 10;
+static inline char hexdigit(unsigned X, bool LowerCase = false) {
+ const char HexChar = LowerCase ? 'a' : 'A';
+ return X < 10 ? '0' + X : HexChar + X - 10;
}
/// utohex_buffer - Emit the specified number into the buffer specified by
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index d047a42079..bad0e6f513 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -242,9 +242,6 @@ public:
};
-template <typename T> struct ReferenceAdder { typedef T& result; };
-template <typename T> struct ReferenceAdder<T&> { typedef T result; };
-
/// StringMap - This is an unconventional map that is specialized for handling
/// keys that are "strings", which are basically ranges of bytes. This does some
/// funky memory allocation and hashing things to make it extremely efficient,
@@ -265,10 +262,12 @@ public:
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
assert(RHS.empty() &&
"Copy ctor from non-empty stringmap not implemented yet!");
+ (void)RHS;
}
void operator=(const StringMap &RHS) {
assert(RHS.empty() &&
"assignment from non-empty stringmap not implemented yet!");
+ (void)RHS;
clear();
}
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index ccf8ca9a66..1766d2b9f2 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -132,7 +132,7 @@ namespace llvm {
/// numbers.
int compare_numeric(StringRef RHS) const;
- /// \brief Determine the edit distance between this string and another
+ /// \brief Determine the edit distance between this string and another
/// string.
///
/// \param Other the string to compare this string against.
@@ -256,6 +256,18 @@ namespace llvm {
/// Note: O(size() + Chars.size())
size_type find_first_not_of(StringRef Chars, size_t From = 0) const;
+ /// find_last_of - Find the last character in the string that is \arg C, or
+ /// npos if not found.
+ size_type find_last_of(char C, size_t From = npos) const {
+ return rfind(C, From);
+ }
+
+ /// find_last_of - Find the last character in the string that is in \arg C,
+ /// or npos if not found.
+ ///
+ /// Note: O(size() + Chars.size())
+ size_type find_last_of(StringRef Chars, size_t From = npos) const;
+
/// @}
/// @name Helpful Algorithms
/// @{
@@ -437,6 +449,10 @@ namespace llvm {
/// @}
+ // StringRefs can be treated like a POD type.
+ template <typename T> struct isPodLike;
+ template <> struct isPodLike<StringRef> { static const bool value = true; };
+
}
#endif
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 467652773b..e6dcc23258 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -53,7 +53,6 @@ public:
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel, psp
msp430, // MSP430: msp430
- pic16, // PIC16: pic16
ppc, // PPC: powerpc
ppc64, // PPC64: powerpc64, ppu
sparc, // Sparc: sparc
@@ -85,8 +84,7 @@ public:
FreeBSD,
Linux,
Lv2, // PS3
- MinGW32,
- MinGW64,
+ MinGW32, // i*86-pc-mingw32, *-w64-mingw32
NetBSD,
OpenBSD,
Psp,
@@ -96,7 +94,12 @@ public:
Minix
};
enum EnvironmentType {
- UnknownEnvironment
+ UnknownEnvironment,
+
+ GNU,
+ GNUEABI,
+ EABI,
+ MachO
};
private:
diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h
index b519a3e2ed..ab8d3653e3 100644
--- a/include/llvm/ADT/Twine.h
+++ b/include/llvm/ADT/Twine.h
@@ -11,7 +11,7 @@
#define LLVM_ADT_TWINE_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <string>
@@ -42,7 +42,7 @@ namespace llvm {
/// Twines support a special 'null' value, which always concatenates to form
/// itself, and renders as an empty string. This can be returned from APIs to
/// effectively nullify any concatenations performed on the result.
- ///
+ ///
/// \b Implementation \n
///
/// Given the nature of a Twine, it is not possible for the Twine's
@@ -99,7 +99,7 @@ namespace llvm {
/// A pointer to a StringRef instance.
StringRefKind,
- /// An unsigned int value reinterpreted as a pointer, to render as an
+ /// An unsigned int value reinterpreted as a pointer, to render as an
/// unsigned decimal integer.
DecUIKind,
@@ -260,32 +260,32 @@ namespace llvm {
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
- explicit Twine(unsigned Val)
+ explicit Twine(unsigned Val)
: LHS((void*)(intptr_t)Val), LHSKind(DecUIKind), RHSKind(EmptyKind) {
}
/// Construct a twine to print \arg Val as a signed decimal integer.
- explicit Twine(int Val)
+ explicit Twine(int Val)
: LHS((void*)(intptr_t)Val), LHSKind(DecIKind), RHSKind(EmptyKind) {
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
- explicit Twine(const unsigned long &Val)
+ explicit Twine(const unsigned long &Val)
: LHS(&Val), LHSKind(DecULKind), RHSKind(EmptyKind) {
}
/// Construct a twine to print \arg Val as a signed decimal integer.
- explicit Twine(const long &Val)
+ explicit Twine(const long &Val)
: LHS(&Val), LHSKind(DecLKind), RHSKind(EmptyKind) {
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
- explicit Twine(const unsigned long long &Val)
+ explicit Twine(const unsigned long long &Val)
: LHS(&Val), LHSKind(DecULLKind), RHSKind(EmptyKind) {
}
/// Construct a twine to print \arg Val as a signed decimal integer.
- explicit Twine(const long long &Val)
+ explicit Twine(const long long &Val)
: LHS(&Val), LHSKind(DecLLKind), RHSKind(EmptyKind) {
}
@@ -330,12 +330,12 @@ namespace llvm {
bool isTriviallyEmpty() const {
return isNullary();
}
-
+
/// isSingleStringRef - Return true if this twine can be dynamically
/// accessed as a single StringRef value with getSingleStringRef().
bool isSingleStringRef() const {
if (getRHSKind() != EmptyKind) return false;
-
+
switch (getLHSKind()) {
case EmptyKind:
case CStringKind:
@@ -382,6 +382,14 @@ namespace llvm {
/// SmallVector and a StringRef to the SmallVector's data is returned.
StringRef toStringRef(SmallVectorImpl<char> &Out) const;
+ /// toNullTerminatedStringRef - This returns the twine as a single null
+ /// terminated StringRef if it can be represented as such. Otherwise the
+ /// twine is written into the given SmallVector and a StringRef to the
+ /// SmallVector's data is returned.
+ ///
+ /// The returned StringRef's size does not include the null terminator.
+ StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
+
/// print - Write the concatenated string represented by this twine to the
/// stream \arg OS.
void print(raw_ostream &OS) const;
diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/ADT/ValueMap.h
index ded17fc322..d1f4e5a0da 100644
--- a/include/llvm/ADT/ValueMap.h
+++ b/include/llvm/ADT/ValueMap.h
@@ -29,7 +29,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/type_traits.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include <iterator>
diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h
index 4e3afe1711..865fcb3d8a 100644
--- a/include/llvm/ADT/ilist.h
+++ b/include/llvm/ADT/ilist.h
@@ -38,6 +38,7 @@
#ifndef LLVM_ADT_ILIST_H
#define LLVM_ADT_ILIST_H
+#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iterator>
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index 53f0eea2be..71a5982c7d 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -48,6 +48,8 @@ class VAArgInst;
class TargetData;
class Pass;
class AnalysisUsage;
+class MemTransferInst;
+class MemIntrinsic;
class AliasAnalysis {
protected:
@@ -96,18 +98,17 @@ public:
struct Location {
/// Ptr - The address of the start of the location.
const Value *Ptr;
- /// Size - The maximum size of the location, or UnknownSize if the size is
- /// not known. Note that an unknown size does not mean the pointer aliases
- /// the entire virtual address space, because there are restrictions on
- /// stepping out of one object and into another.
+ /// Size - The maximum size of the location, in address-units, or
+ /// UnknownSize if the size is not known. Note that an unknown size does
+ /// not mean the pointer aliases the entire virtual address space, because
+ /// there are restrictions on stepping out of one object and into another.
/// See http://llvm.org/docs/LangRef.html#pointeraliasing
uint64_t Size;
/// TBAATag - The metadata node which describes the TBAA type of
/// the location, or null if there is no known unique tag.
const MDNode *TBAATag;
- explicit Location(const Value *P = 0,
- uint64_t S = UnknownSize,
+ explicit Location(const Value *P = 0, uint64_t S = UnknownSize,
const MDNode *N = 0)
: Ptr(P), Size(S), TBAATag(N) {}
@@ -135,6 +136,8 @@ public:
Location getLocation(const LoadInst *LI);
Location getLocation(const StoreInst *SI);
Location getLocation(const VAArgInst *VI);
+ static Location getLocationForSource(const MemTransferInst *MTI);
+ static Location getLocationForDest(const MemIntrinsic *MI);
/// Alias analysis result - Either we know for sure that it does not alias, we
/// know for sure it must alias, or we don't know anything: The two pointers
@@ -147,8 +150,9 @@ public:
///
enum AliasResult {
NoAlias = 0, ///< No dependencies.
- MayAlias = 1, ///< Anything goes.
- MustAlias = 2 ///< Pointers are equal.
+ MayAlias, ///< Anything goes.
+ PartialAlias, ///< Pointers differ, but pointees overlap.
+ MustAlias ///< Pointers are equal.
};
/// alias - The main low level interface to the alias analysis implementation.
@@ -179,7 +183,17 @@ public:
const Value *V2, uint64_t V2Size) {
return isNoAlias(Location(V1, V1Size), Location(V2, V2Size));
}
+
+ /// isMustAlias - A convenience wrapper.
+ bool isMustAlias(const Location &LocA, const Location &LocB) {
+ return alias(LocA, LocB) == MustAlias;
+ }
+ /// isMustAlias - A convenience wrapper.
+ bool isMustAlias(const Value *V1, const Value *V2) {
+ return alias(V1, 1, V2, 1) == MustAlias;
+ }
+
/// pointsToConstantMemory - If the specified memory location is
/// known to be constant, return true. If OrLocal is true and the
/// specified memory location is known to be "local" (derived from
@@ -388,7 +402,7 @@ public:
ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
/// getModRefInfo (for stores) - A convenience wrapper.
- ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size) {
+ ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size){
return getModRefInfo(S, Location(P, Size));
}
@@ -397,7 +411,7 @@ public:
ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
/// getModRefInfo (for va_args) - A convenience wrapper.
- ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size) {
+ ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size){
return getModRefInfo(I, Location(P, Size));
}
@@ -455,6 +469,17 @@ public:
///
virtual void copyValue(Value *From, Value *To);
+ /// addEscapingUse - This method should be used whenever an escaping use is
+ /// added to a pointer value. Analysis implementations may either return
+ /// conservative responses for that value in the future, or may recompute
+ /// some or all internal state to continue providing precise responses.
+ ///
+ /// Escaping uses are considered by anything _except_ the following:
+ /// - GEPs or bitcasts of the pointer
+ /// - Loads through the pointer
+ /// - Stores through (but not of) the pointer
+ virtual void addEscapingUse(Use &U);
+
/// replaceWithNewValue - This method is the obvious combination of the two
/// above, and it provided as a helper to simplify client code.
///
diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h
index a4884edd5b..089f322e4a 100644
--- a/include/llvm/Analysis/CallGraph.h
+++ b/include/llvm/Analysis/CallGraph.h
@@ -57,7 +57,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ValueHandle.h"
-#include "llvm/System/IncludeFile.h"
+#include "llvm/Support/IncludeFile.h"
#include <map>
namespace llvm {
@@ -138,6 +138,13 @@ public:
/// not already exist.
CallGraphNode *getOrInsertFunction(const Function *F);
+ /// spliceFunction - Replace the function represented by this node by another.
+ /// This does not rescan the body of the function, so it is suitable when
+ /// splicing the body of one function to another while also updating all
+ /// callers from the old function to the new.
+ ///
+ void spliceFunction(const Function *From, const Function *To);
+
//===---------------------------------------------------------------------
// Pass infrastructure interface glue code.
//
@@ -163,8 +170,10 @@ protected:
// CallGraphNode class definition.
//
class CallGraphNode {
- AssertingVH<Function> F;
+ 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:
diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h
index e89ad9026d..75edfbbed2 100644
--- a/include/llvm/Analysis/CodeMetrics.h
+++ b/include/llvm/Analysis/CodeMetrics.h
@@ -7,15 +7,16 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements various weight measurements for a function, helping
-// the Inliner and PartialSpecialization decide whether to duplicate its
-// contents.
+// This file implements various weight measurements for code, helping
+// the Inliner and other passes decide whether to duplicate its contents.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_CODEMETRICS_H
#define LLVM_ANALYSIS_CODEMETRICS_H
+#include "llvm/ADT/DenseMap.h"
+
namespace llvm {
// CodeMetrics - Calculate size and a few similar metrics for a set of
// basic blocks.
diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h
index e2675eb2d4..f6b1f5ab99 100644
--- a/include/llvm/Analysis/ConstantFolding.h
+++ b/include/llvm/Analysis/ConstantFolding.h
@@ -7,7 +7,8 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares routines for folding instructions into constants.
+// This file declares routines for folding instructions into constants when all
+// operands are constants, for example "sub i32 1, 0" -> "1".
//
// Also, to supplement the basic VMCore ConstantExpr simplifications,
// this file declares some additional folding routines that can make use of
@@ -27,11 +28,11 @@ namespace llvm {
class Function;
class Type;
-/// ConstantFoldInstruction - Attempt to constant fold the specified
-/// instruction. If successful, the constant result is returned, if not, null
-/// is returned. Note that this function can only fail when attempting to fold
-/// instructions like loads and stores, which have no constant expression form.
-///
+/// ConstantFoldInstruction - Try to constant fold the specified instruction.
+/// If successful, the constant result is returned, if not, null is returned.
+/// Note that this fails if not all of the operands are constant. Otherwise,
+/// this function can only fail when attempting to fold instructions like loads
+/// and stores, which have no constant expression form.
Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0);
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h
index 4b8eba949b..32a17e4f09 100644
--- a/include/llvm/Analysis/DIBuilder.h
+++ b/include/llvm/Analysis/DIBuilder.h
@@ -15,11 +15,15 @@
#ifndef LLVM_ANALYSIS_DIBUILDER_H
#define LLVM_ANALYSIS_DIBUILDER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/StringRef.h"
namespace llvm {
+ class BasicBlock;
+ class Instruction;
+ class Function;
class Module;
+ class Value;
class LLVMContext;
class MDNode;
class StringRef;
@@ -27,6 +31,15 @@ namespace llvm {
class DIFile;
class DIEnumerator;
class DIType;
+ class DIArray;
+ class DIGlobalVariable;
+ class DINameSpace;
+ class DIVariable;
+ class DISubrange;
+ class DILexicalBlock;
+ class DISubprogram;
+ class DITemplateTypeParameter;
+ class DITemplateValueParameter;
class DIBuilder {
private:
@@ -34,14 +47,18 @@ namespace llvm {
LLVMContext & VMContext;
MDNode *TheCU;
+ Function *DeclareFn; // llvm.dbg.declare
+ Function *ValueFn; // llvm.dbg.value
+
DIBuilder(const DIBuilder &); // DO NOT IMPLEMENT
void operator=(const DIBuilder &); // DO NOT IMPLEMENT
public:
explicit DIBuilder(Module &M);
const MDNode *getCU() { return TheCU; }
+ enum ComplexAddrKind { OpPlus=1, OpDeref };
- /// CreateCompileUnit - A CompileUnit provides an anchor for all debugging
+ /// createCompileUnit - A CompileUnit provides an anchor for all debugging
/// information generated during this instance of compilation.
/// @param Lang Source programming language, eg. dwarf::DW_LANG_C99
/// @param File File name
@@ -55,58 +72,392 @@ namespace llvm {
/// by a tool analyzing generated debugging information.
/// @param RV This indicates runtime version for languages like
/// Objective-C.
- void CreateCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
+ void createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
StringRef Producer,
bool isOptimized, StringRef Flags, unsigned RV);
- /// CreateFile - Create a file descriptor to hold debugging information
+ /// createFile - Create a file descriptor to hold debugging information
/// for a file.
- DIFile CreateFile(StringRef Filename, StringRef Directory);
+ DIFile createFile(StringRef Filename, StringRef Directory);
- /// CreateEnumerator - Create a single enumerator value.
- DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
+ /// createEnumerator - Create a single enumerator value.
+ DIEnumerator createEnumerator(StringRef Name, uint64_t Val);
- /// CreateBasicType - Create debugging information entry for a basic
+ /// createBasicType - Create debugging information entry for a basic
/// type.
/// @param Name Type name.
/// @param SizeInBits Size of the type.
/// @param AlignInBits Type alignment.
/// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
- DIType CreateBasicType(StringRef Name, uint64_t SizeInBits,
+ DIType createBasicType(StringRef Name, uint64_t SizeInBits,
uint64_t AlignInBits, unsigned Encoding);
- /// CreateQualifiedType - Create debugging information entry for a qualified
+ /// createQualifiedType - Create debugging information entry for a qualified
/// type, e.g. 'const int'.
/// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
/// @param FromTy Base Type.
- DIType CreateQualifiedType(unsigned Tag, DIType FromTy);
+ DIType createQualifiedType(unsigned Tag, DIType FromTy);
- /// CreatePointerType - Create debugging information entry for a pointer.
- DIType CreatePointerType(DIType PointeeTy, uint64_t SizeInBits,
- uint64_t AlignInBits = 0, StringRef Name = StringRef());
+ /// createPointerType - Create debugging information entry for a pointer.
+ /// @param PointeeTy Type pointed by this pointer.
+ /// @param SizeInBits Size.
+ /// @param AlignInBits Alignment. (optional)
+ /// @param Name Pointer type name. (optional)
+ DIType createPointerType(DIType PointeeTy, uint64_t SizeInBits,
+ uint64_t AlignInBits = 0,
+ StringRef Name = StringRef());
- /// CreateReferenceType - Create debugging information entry for a reference.
- DIType CreateReferenceType(DIType RTy);
+ /// createReferenceType - Create debugging information entry for a c++
+ /// style reference.
+ DIType createReferenceType(DIType RTy);
- /// CreateTypedef - Create debugging information entry for a typedef.
- DIType CreateTypedef(DIType Ty, StringRef Name, DIFile F, unsigned LineNo);
+ /// createTypedef - Create debugging information entry for a typedef.
+ /// @param Ty Original type.
+ /// @param Name Typedef name.
+ /// @param File File where this type is defined.
+ /// @param LineNo Line number.
+ DIType createTypedef(DIType Ty, StringRef Name, DIFile File,
+ unsigned LineNo);
- /// CreateFriend - Create debugging information entry for a 'friend'.
- DIType CreateFriend(DIType Ty, DIType FriendTy);
+ /// createFriend - Create debugging information entry for a 'friend'.
+ DIType createFriend(DIType Ty, DIType FriendTy);
- /// CreateInheritance - Create debugging information entry to establish
+ /// createInheritance - Create debugging information entry to establish
/// inheritance relationship between two types.
- DIType CreateInheritance(DIType Ty, DIType BaseTy, uint64_t BaseOffset,
+ /// @param Ty Original type.
+ /// @param BaseTy Base type. Ty is inherits from base.
+ /// @param BaseOffset Base offset.
+ /// @param Flags Flags to describe inheritance attribute,
+ /// e.g. private
+ DIType createInheritance(DIType Ty, DIType BaseTy, uint64_t BaseOffset,
unsigned Flags);
- /// CreateMemberType - Create debugging information entry for a member.
- DIType CreateMemberType(DIDescriptor Context, StringRef Name, DIFile F,
- unsigned LineNumber, uint64_t SizeInBits,
+ /// createMemberType - Create debugging information entry for a member.
+ /// @param Name Member name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param OffsetInBits Member offset.
+ /// @param Flags Flags to encode member attribute, e.g. private
+ /// @param Ty Parent type.
+ DIType createMemberType(StringRef Name, DIFile File,
+ unsigned LineNo, uint64_t SizeInBits,
uint64_t AlignInBits, uint64_t OffsetInBits,
unsigned Flags, DIType Ty);
- /// CreateArtificialType - Create a new DIType with "artificial" flag set.
- DIType CreateArtificialType(DIType Ty);
+ /// createClassType - Create debugging information entry for a class.
+ /// @param Scope Scope in which this class is defined.
+ /// @param Name class name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param OffsetInBits Member offset.
+ /// @param Flags Flags to encode member attribute, e.g. private
+ /// @param Elements class members.
+ /// @param VTableHolder Debug info of the base class that contains vtable
+ /// for this type. This is used in
+ /// DW_AT_containing_type. See DWARF documentation
+ /// for more info.
+ /// @param TemplateParms Template type parameters.
+ DIType createClassType(DIDescriptor Scope, StringRef Name, DIFile File,
+ unsigned LineNumber, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, DIType DerivedFrom,
+ DIArray Elements, MDNode *VTableHolder = 0,
+ MDNode *TemplateParms = 0);
+
+ /// createStructType - Create debugging information entry for a struct.
+ /// @param Scope Scope in which this struct is defined.
+ /// @param Name Struct name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param Flags Flags to encode member attribute, e.g. private
+ /// @param Elements Struct elements.
+ /// @param RunTimeLang Optional parameter, Objective-C runtime version.
+ DIType createStructType(DIDescriptor Scope, StringRef Name, DIFile File,
+ unsigned LineNumber, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Flags,
+ DIArray Elements, unsigned RunTimeLang = 0);
+
+ /// createUnionType - Create debugging information entry for an union.
+ /// @param Scope Scope in which this union is defined.
+ /// @param Name Union name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param Flags Flags to encode member attribute, e.g. private
+ /// @param Elements Union elements.
+ /// @param RunTimeLang Optional parameter, Objective-C runtime version.
+ DIType createUnionType(DIDescriptor Scope, StringRef Name, DIFile File,
+ unsigned LineNumber, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Flags,
+ DIArray Elements, unsigned RunTimeLang = 0);
+
+ /// createTemplateTypeParameter - Create debugging information for template
+ /// type parameter.
+ /// @param Scope Scope in which this type is defined.
+ /// @param Name Type parameter name.
+ /// @param Ty Parameter type.
+ /// @param File File where this type parameter is defined.
+ /// @param LineNo Line number.
+ /// @param ColumnNo Column Number.
+ DITemplateTypeParameter
+ createTemplateTypeParameter(DIDescriptor Scope, StringRef Name, DIType Ty,
+ MDNode *File = 0, unsigned LineNo = 0,
+ unsigned ColumnNo = 0);
+
+ /// createTemplateValueParameter - Create debugging information for template
+ /// value parameter.
+ /// @param Scope Scope in which this type is defined.
+ /// @param Name Value parameter name.
+ /// @param Ty Parameter type.
+ /// @param Value Constant parameter value.
+ /// @param File File where this type parameter is defined.
+ /// @param LineNo Line number.
+ /// @param ColumnNo Column Number.
+ DITemplateValueParameter
+ createTemplateValueParameter(DIDescriptor Scope, StringRef Name, DIType Ty,
+ uint64_t Value,
+ MDNode *File = 0, unsigned LineNo = 0,
+ unsigned ColumnNo = 0);
+
+ /// createArrayType - Create debugging information entry for an array.
+ /// @param Size Array size.
+ /// @param AlignInBits Alignment.
+ /// @param Ty Element type.
+ /// @param Subscripts Subscripts.
+ DIType createArrayType(uint64_t Size, uint64_t AlignInBits,
+ DIType Ty, DIArray Subscripts);
+
+ /// createVectorType - Create debugging information entry for a vector type.
+ /// @param Size Array size.
+ /// @param AlignInBits Alignment.
+ /// @param Ty Element type.
+ /// @param Subscripts Subscripts.
+ DIType createVectorType(uint64_t Size, uint64_t AlignInBits,
+ DIType Ty, DIArray Subscripts);
+
+ /// createEnumerationType - Create debugging information entry for an
+ /// enumeration.
+ /// @param Scope Scope in which this enumeration is defined.
+ /// @param Name Union name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param Elements Enumeration elements.
+ DIType createEnumerationType(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits, DIArray Elements);
+
+ /// createSubroutineType - Create subroutine type.
+ /// @param File File in which this subroutine is defined.
+ /// @param ParamterTypes An array of subroutine parameter types. This
+ /// includes return type at 0th index.
+ DIType createSubroutineType(DIFile File, DIArray ParameterTypes);
+
+ /// createArtificialType - Create a new DIType with "artificial" flag set.
+ DIType createArtificialType(DIType Ty);
+
+ /// createTemporaryType - Create a temporary forward-declared type.
+ DIType createTemporaryType();
+ DIType createTemporaryType(DIFile F);
+
+ /// retainType - Retain DIType in a module even if it is not referenced
+ /// through debug info anchors.
+ void retainType(DIType T);
+
+ /// createUnspecifiedParameter - Create unspeicified type descriptor
+ /// for a subroutine type.
+ DIDescriptor createUnspecifiedParameter();
+
+ /// getOrCreateArray - Get a DIArray, create one if required.
+ DIArray getOrCreateArray(Value *const *Elements, unsigned NumElements);
+
+ /// getOrCreateSubrange - Create a descriptor for a value range. This
+ /// implicitly uniques the values returned.
+ DISubrange getOrCreateSubrange(int64_t Lo, int64_t Hi);
+
+ /// createGlobalVariable - Create a new descriptor for the specified global.
+ /// @param Name Name of the variable.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Variable Type.
+ /// @param isLocalToUnit Boolean flag indicate whether this variable is
+ /// externally visible or not.
+ /// @param Val llvm::Value of the variable.
+ DIGlobalVariable
+ createGlobalVariable(StringRef Name, DIFile File, unsigned LineNo,
+ DIType Ty, bool isLocalToUnit, llvm::Value *Val);
+
+
+ /// createStaticVariable - Create a new descriptor for the specified
+ /// variable.
+ /// @param Conext Variable scope.
+ /// @param Name Name of the variable.
+ /// @param LinakgeName Mangled name of the variable.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Variable Type.
+ /// @param isLocalToUnit Boolean flag indicate whether this variable is
+ /// externally visible or not.
+ /// @param Val llvm::Value of the variable.
+ DIGlobalVariable
+ createStaticVariable(DIDescriptor Context, StringRef Name,
+ StringRef LinkageName, DIFile File, unsigned LineNo,
+ DIType Ty, bool isLocalToUnit, llvm::Value *Val);
+
+
+ /// createLocalVariable - Create a new descriptor for the specified
+ /// local variable.
+ /// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or
+ /// DW_TAG_arg_variable.
+ /// @param Scope Variable scope.
+ /// @param Name Variable name.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Variable Type
+ /// @param AlwaysPreserve Boolean. Set to true if debug info for this
+ /// variable should be preserved in optimized build.
+ /// @param Flags Flags, e.g. artificial variable.
+ /// @param ArgNo If this variable is an arugment then this argument's
+ /// number. 1 indicates 1st argument.
+ DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope,
+ StringRef Name,
+ DIFile File, unsigned LineNo,
+ DIType Ty, bool AlwaysPreserve = false,
+ unsigned Flags = 0,
+ unsigned ArgNo = 0);
+
+
+ /// createComplexVariable - Create a new descriptor for the specified
+ /// variable which has a complex address expression for its address.
+ /// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or
+ /// DW_TAG_arg_variable.
+ /// @param Scope Variable scope.
+ /// @param Name Variable name.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Variable Type
+ /// @param Addr A pointer to a vector of complex address operations.
+ /// @param NumAddr Num of address operations in the vector.
+ /// @param ArgNo If this variable is an arugment then this argument's
+ /// number. 1 indicates 1st argument.
+ DIVariable createComplexVariable(unsigned Tag, DIDescriptor Scope,
+ StringRef Name, DIFile F, unsigned LineNo,
+ DIType Ty, Value *const *Addr,
+ unsigned NumAddr, unsigned ArgNo = 0);
+
+ /// createFunction - Create a new descriptor for the specified subprogram.
+ /// See comments in DISubprogram for descriptions of these fields.
+ /// @param Scope Function scope.
+ /// @param Name Function name.
+ /// @param LinkageName Mangled function name.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Function type.
+ /// @param isLocalToUnit True if this function is not externally visible..
+ /// @param isDefinition True if this is a function definition.
+ /// @param Flags e.g. is this function prototyped or not.
+ /// This flags are used to emit dwarf attributes.
+ /// @param isOptimized True if optimization is ON.
+ /// @param Fn llvm::Function pointer.
+ DISubprogram createFunction(DIDescriptor Scope, StringRef Name,
+ StringRef LinkageName,
+ DIFile File, unsigned LineNo,
+ DIType Ty, bool isLocalToUnit,
+ bool isDefinition,
+ unsigned Flags = 0,
+ bool isOptimized = false,
+ Function *Fn = 0);
+
+ /// createMethod - Create a new descriptor for the specified C++ method.
+ /// See comments in DISubprogram for descriptions of these fields.
+ /// @param Scope Function scope.
+ /// @param Name Function name.
+ /// @param LinkageName Mangled function name.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Function type.
+ /// @param isLocalToUnit True if this function is not externally visible..
+ /// @param isDefinition True if this is a function definition.
+ /// @param Virtuality Attributes describing virutallness. e.g. pure
+ /// virtual function.
+ /// @param VTableIndex Index no of this method in virtual table.
+ /// @param VTableHolder Type that holds vtable.
+ /// @param Flags e.g. is this function prototyped or not.
+ /// This flags are used to emit dwarf attributes.
+ /// @param isOptimized True if optimization is ON.
+ /// @param Fn llvm::Function pointer.
+ DISubprogram createMethod(DIDescriptor Scope, StringRef Name,
+ StringRef LinkageName,
+ DIFile File, unsigned LineNo,
+ DIType Ty, bool isLocalToUnit,
+ bool isDefinition,
+ unsigned Virtuality = 0, unsigned VTableIndex = 0,
+ MDNode *VTableHolder = 0,
+ unsigned Flags = 0,
+ bool isOptimized = false,
+ Function *Fn = 0);
+
+ /// createNameSpace - This creates new descriptor for a namespace
+ /// with the specified parent scope.
+ /// @param Scope Namespace scope
+ /// @param Name Name of this namespace
+ /// @param File Source file
+ /// @param LineNo Line number
+ DINameSpace createNameSpace(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNo);
+
+
+ /// createLexicalBlock - This creates a descriptor for a lexical block
+ /// with the specified parent context.
+ /// @param Scope Parent lexical scope.
+ /// @param File Source file
+ /// @param Line Line number
+ /// @param Col Column number
+ DILexicalBlock createLexicalBlock(DIDescriptor Scope, DIFile File,
+ unsigned Line, unsigned Col);
+
+ /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+ /// @param Storage llvm::Value of the variable
+ /// @param VarInfo Variable's debug info descriptor.
+ /// @param InsertAtEnd Location for the new intrinsic.
+ Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo,
+ BasicBlock *InsertAtEnd);
+
+ /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+ /// @param Storage llvm::Value of the variable
+ /// @param VarInfo Variable's debug info descriptor.
+ /// @param InsertBefore Location for the new intrinsic.
+ Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo,
+ Instruction *InsertBefore);
+
+
+ /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+ /// @param Val llvm::Value of the variable
+ /// @param Offset Offset
+ /// @param VarInfo Variable's debug info descriptor.
+ /// @param InsertAtEnd Location for the new intrinsic.
+ Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
+ DIVariable VarInfo,
+ BasicBlock *InsertAtEnd);
+
+ /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+ /// @param Val llvm::Value of the variable
+ /// @param Offset Offset
+ /// @param VarInfo Variable's debug info descriptor.
+ /// @param InsertBefore Location for the new intrinsic.
+ Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
+ DIVariable VarInfo,
+ Instruction *InsertBefore);
+
};
} // end namespace llvm
diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h
index af683af0c9..951fd3cf1f 100644
--- a/include/llvm/Analysis/DebugInfo.h
+++ b/include/llvm/Analysis/DebugInfo.h
@@ -122,6 +122,8 @@ namespace llvm {
bool isType() const;
bool isGlobal() const;
bool isUnspecifiedParameter() const;
+ bool isTemplateTypeParameter() const;
+ bool isTemplateValueParameter() const;
};
/// DISubrange - This is used to represent ranges, for array bounds.
@@ -288,6 +290,7 @@ namespace llvm {
/// replaceAllUsesWith - Replace all uses of debug info referenced by
/// this descriptor.
void replaceAllUsesWith(DIDescriptor &D);
+ void replaceAllUsesWith(MDNode *D);
/// print - print type.
void print(raw_ostream &OS) const;
@@ -355,6 +358,7 @@ namespace llvm {
DICompositeType getContainingType() const {
return getFieldAs<DICompositeType>(12);
}
+ DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }
/// Verify - Verify that a composite type descriptor is well formed.
bool Verify() const;
@@ -366,6 +370,43 @@ namespace llvm {
void dump() const;
};
+ /// DITemplateTypeParameter - This is a wrapper for template type parameter.
+ class DITemplateTypeParameter : public DIDescriptor {
+ public:
+ explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getName() const { return getStringField(2); }
+ DIType getType() const { return getFieldAs<DIType>(3); }
+ StringRef getFilename() const {
+ return getFieldAs<DIFile>(4).getFilename();
+ }
+ StringRef getDirectory() const {
+ return getFieldAs<DIFile>(4).getDirectory();
+ }
+ unsigned getLineNumber() const { return getUnsignedField(5); }
+ unsigned getColumnNumber() const { return getUnsignedField(6); }
+ };
+
+ /// DITemplateValueParameter - This is a wrapper for template value parameter.
+ class DITemplateValueParameter : public DIDescriptor {
+ public:
+ explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getName() const { return getStringField(2); }
+ DIType getType() const { return getFieldAs<DIType>(3); }
+ uint64_t getValue() const { return getUInt64Field(4); }
+ StringRef getFilename() const {
+ return getFieldAs<DIFile>(5).getFilename();
+ }
+ StringRef getDirectory() const {
+ return getFieldAs<DIFile>(5).getDirectory();
+ }
+ unsigned getLineNumber() const { return getUnsignedField(6); }
+ unsigned getColumnNumber() const { return getUnsignedField(7); }
+ };
+
/// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
class DISubprogram : public DIScope {
public:
@@ -523,7 +564,13 @@ namespace llvm {
DIFile F = getFieldAs<DIFile>(3);
return F.getCompileUnit();
}
- unsigned getLineNumber() const { return getUnsignedField(4); }
+ unsigned getLineNumber() const {
+ return (getUnsignedField(4) << 8) >> 8;
+ }
+ unsigned getArgNumber() const {
+ unsigned L = getUnsignedField(4);
+ return L >> 24;
+ }
DIType getType() const { return getFieldAs<DIType>(5); }
/// isArtificial - Return true if this variable is marked as "artificial".
@@ -619,217 +666,6 @@ namespace llvm {
bool Verify() const;
};
- /// DIFactory - This object assists with the construction of the various
- /// descriptors.
- class DIFactory {
- Module &M;
- LLVMContext& VMContext;
-
- Function *DeclareFn; // llvm.dbg.declare
- Function *ValueFn; // llvm.dbg.value
-
- DIFactory(const DIFactory &); // DO NOT IMPLEMENT
- void operator=(const DIFactory&); // DO NOT IMPLEMENT
- public:
- enum ComplexAddrKind { OpPlus=1, OpDeref };
-
- explicit DIFactory(Module &m);
-
- /// GetOrCreateArray - Create an descriptor for an array of descriptors.
- /// This implicitly uniques the arrays created.
- DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys);
-
- /// GetOrCreateSubrange - Create a descriptor for a value range. This
- /// implicitly uniques the values returned.
- DISubrange GetOrCreateSubrange(int64_t Lo, int64_t Hi);
-
- /// CreateUnspecifiedParameter - Create unspeicified type descriptor
- /// for a subroutine type.
- DIDescriptor CreateUnspecifiedParameter();
-
- /// CreateCompileUnit - Create a new descriptor for the specified compile
- /// unit.
- DICompileUnit CreateCompileUnit(unsigned LangID,
- StringRef Filename,
- StringRef Directory,
- StringRef Producer,
- bool isMain = false,
- bool isOptimized = false,
- StringRef Flags = "",
- unsigned RunTimeVer = 0);
-
- /// CreateFile - Create a new descriptor for the specified file.
- DIFile CreateFile(StringRef Filename, StringRef Directory,
- DICompileUnit CU);
-
- /// CreateEnumerator - Create a single enumerator value.
- DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
-
- /// CreateBasicType - Create a basic type like int, float, etc.
- DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name,
- DIFile F, unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- unsigned Encoding);
-
- /// CreateBasicType - Create a basic type like int, float, etc.
- DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
- DIFile F, unsigned LineNumber,
- Constant *SizeInBits, Constant *AlignInBits,
- Constant *OffsetInBits, unsigned Flags,
- unsigned Encoding);
-
- /// CreateDerivedType - Create a derived type like const qualified type,
- /// pointer, typedef, etc.
- DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DIFile F,
- unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- DIType DerivedFrom);
-
- /// CreateDerivedType - Create a derived type like const qualified type,
- /// pointer, typedef, etc.
- DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DIFile F,
- unsigned LineNumber,
- Constant *SizeInBits,
- Constant *AlignInBits,
- Constant *OffsetInBits, unsigned Flags,
- DIType DerivedFrom);
-
- /// CreateCompositeType - Create a composite type like array, struct, etc.
- DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DIFile F,
- unsigned LineNumber,
- uint64_t SizeInBits,
- uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- DIType DerivedFrom,
- DIArray Elements,
- unsigned RunTimeLang = 0,
- MDNode *ContainingType = 0);
-
- /// CreateTemporaryType - Create a temporary forward-declared type.
- DIType CreateTemporaryType();
-
- /// CreateArtificialType - Create a new DIType with "artificial" flag set.
- DIType CreateArtificialType(DIType Ty);
-
- /// CreateCompositeType - Create a composite type like array, struct, etc.
- DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DIFile F,
- unsigned LineNumber,
- Constant *SizeInBits,
- Constant *AlignInBits,
- Constant *OffsetInBits,
- unsigned Flags,
- DIType DerivedFrom,
- DIArray Elements,
- unsigned RunTimeLang = 0,
- MDNode *ContainingType = 0);
-
- /// CreateSubprogram - Create a new descriptor for the specified subprogram.
- /// See comments in DISubprogram for descriptions of these fields.
- DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
- StringRef DisplayName,
- StringRef LinkageName,
- DIFile F, unsigned LineNo,
- DIType Ty, bool isLocalToUnit,
- bool isDefinition,
- unsigned VK = 0,
- unsigned VIndex = 0,
- DIType ContainingType = DIType(),
- unsigned Flags = 0,
- bool isOptimized = false,
- Function *Fn = 0);
-
- /// CreateSubprogramDefinition - Create new subprogram descriptor for the
- /// given declaration.
- DISubprogram CreateSubprogramDefinition(DISubprogram &SPDeclaration);
-
- /// CreateGlobalVariable - Create a new descriptor for the specified global.
- DIGlobalVariable
- CreateGlobalVariable(DIDescriptor Context, StringRef Name,
- StringRef DisplayName,
- StringRef LinkageName,
- DIFile F,
- unsigned LineNo, DIType Ty, bool isLocalToUnit,
- bool isDefinition, llvm::GlobalVariable *GV);
-
- /// CreateGlobalVariable - Create a new descriptor for the specified constant.
- DIGlobalVariable
- CreateGlobalVariable(DIDescriptor Context, StringRef Name,
- StringRef DisplayName,
- StringRef LinkageName,
- DIFile F,
- unsigned LineNo, DIType Ty, bool isLocalToUnit,
- bool isDefinition, llvm::Constant *C);
-
- /// CreateVariable - Create a new descriptor for the specified variable.
- DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
- StringRef Name,
- DIFile F, unsigned LineNo,
- DIType Ty, bool AlwaysPreserve = false,
- unsigned Flags = 0);
-
- /// CreateComplexVariable - Create a new descriptor for the specified
- /// variable which has a complex address expression for its address.
- DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
- StringRef Name, DIFile F, unsigned LineNo,
- DIType Ty, Value *const *Addr,
- unsigned NumAddr);
-
- /// CreateLexicalBlock - This creates a descriptor for a lexical block
- /// with the specified parent context.
- DILexicalBlock CreateLexicalBlock(DIDescriptor Context, DIFile F,
- unsigned Line = 0, unsigned Col = 0);
-
- /// CreateNameSpace - This creates new descriptor for a namespace
- /// with the specified parent context.
- DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
- DIFile F, unsigned LineNo);
-
- /// CreateLocation - Creates a debug info location.
- DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
- DIScope S, DILocation OrigLoc);
-
- /// CreateLocation - Creates a debug info location.
- DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
- DIScope S, MDNode *OrigLoc = 0);
-
- /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
- Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
- BasicBlock *InsertAtEnd);
-
- /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
- Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
- Instruction *InsertBefore);
-
- /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
- Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
- DIVariable D, BasicBlock *InsertAtEnd);
-
- /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
- Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
- DIVariable D, Instruction *InsertBefore);
-
- // RecordType - Record DIType in a module such that it is not lost even if
- // it is not referenced through debug info anchors.
- void RecordType(DIType T);
-
- private:
- Constant *GetTagConstant(unsigned TAG);
- };
-
- bool getLocationInfo(const Value *V, std::string &DisplayName,
- std::string &Type, unsigned &LineNo, std::string &File,
- std::string &Dir);
-
/// getDISubprogram - Find subprogram that is enclosing this scope.
DISubprogram getDISubprogram(const MDNode *Scope);
diff --git a/include/llvm/Analysis/DominanceFrontier.h b/include/llvm/Analysis/DominanceFrontier.h
new file mode 100644
index 0000000000..d7f74af1c6
--- /dev/null
+++ b/include/llvm/Analysis/DominanceFrontier.h
@@ -0,0 +1,189 @@
+//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DominanceFrontier class, which calculate and holds the
+// dominance frontier for a function.
+//
+// This should be considered deprecated, don't add any more uses of this data
+// structure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H
+#define LLVM_ANALYSIS_DOMINANCEFRONTIER_H
+
+#include "llvm/Analysis/Dominators.h"
+#include <map>
+#include <set>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// DominanceFrontierBase - Common base class for computing forward and inverse
+/// dominance frontiers for a function.
+///
+class DominanceFrontierBase : public FunctionPass {
+public:
+ typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb
+ typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
+protected:
+ DomSetMapType Frontiers;
+ std::vector<BasicBlock*> Roots;
+ const bool IsPostDominators;
+
+public:
+ DominanceFrontierBase(char &ID, bool isPostDom)
+ : FunctionPass(ID), IsPostDominators(isPostDom) {}
+
+ /// getRoots - Return the root blocks of the current CFG. This may include
+ /// multiple blocks if we are computing post dominators. For forward
+ /// dominators, this will always be a single block (the entry node).
+ ///
+ inline const std::vector<BasicBlock*> &getRoots() const { return Roots; }
+
+ /// isPostDominator - Returns true if analysis based of postdoms
+ ///
+ bool isPostDominator() const { return IsPostDominators; }
+
+ virtual void releaseMemory() { Frontiers.clear(); }
+
+ // Accessor interface:
+ typedef DomSetMapType::iterator iterator;
+ typedef DomSetMapType::const_iterator const_iterator;
+ iterator begin() { return Frontiers.begin(); }
+ const_iterator begin() const { return Frontiers.begin(); }
+ iterator end() { return Frontiers.end(); }
+ const_iterator end() const { return Frontiers.end(); }
+ iterator find(BasicBlock *B) { return Frontiers.find(B); }
+ const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }
+
+ iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
+ assert(find(BB) == end() && "Block already in DominanceFrontier!");
+ return Frontiers.insert(std::make_pair(BB, frontier)).first;
+ }
+
+ /// removeBlock - Remove basic block BB's frontier.
+ void removeBlock(BasicBlock *BB) {
+ assert(find(BB) != end() && "Block is not in DominanceFrontier!");
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ I->second.erase(BB);
+ Frontiers.erase(BB);
+ }
+
+ void addToFrontier(iterator I, BasicBlock *Node) {
+ assert(I != end() && "BB is not in DominanceFrontier!");
+ I->second.insert(Node);
+ }
+
+ void removeFromFrontier(iterator I, BasicBlock *Node) {
+ assert(I != end() && "BB is not in DominanceFrontier!");
+ assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
+ I->second.erase(Node);
+ }
+
+ /// compareDomSet - Return false if two domsets match. Otherwise
+ /// return true;
+ bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
+ std::set<BasicBlock *> tmpSet;
+ for (DomSetType::const_iterator I = DS2.begin(),
+ E = DS2.end(); I != E; ++I)
+ tmpSet.insert(*I);
+
+ for (DomSetType::const_iterator I = DS1.begin(),
+ E = DS1.end(); I != E; ) {
+ BasicBlock *Node = *I++;
+
+ if (tmpSet.erase(Node) == 0)
+ // Node is in DS1 but not in DS2.
+ return true;
+ }
+
+ if (!tmpSet.empty())
+ // There are nodes that are in DS2 but not in DS1.
+ return true;
+
+ // DS1 and DS2 matches.
+ return false;
+ }
+
+ /// compare - Return true if the other dominance frontier base matches
+ /// this dominance frontier base. Otherwise return false.
+ bool compare(DominanceFrontierBase &Other) const {
+ DomSetMapType tmpFrontiers;
+ for (DomSetMapType::const_iterator I = Other.begin(),
+ E = Other.end(); I != E; ++I)
+ tmpFrontiers.insert(std::make_pair(I->first, I->second));
+
+ for (DomSetMapType::iterator I = tmpFrontiers.begin(),
+ E = tmpFrontiers.end(); I != E; ) {
+ BasicBlock *Node = I->first;
+ const_iterator DFI = find(Node);
+ if (DFI == end())
+ return true;
+
+ if (compareDomSet(I->second, DFI->second))
+ return true;
+
+ ++I;
+ tmpFrontiers.erase(Node);
+ }
+
+ if (!tmpFrontiers.empty())
+ return true;
+
+ return false;
+ }
+
+ /// print - Convert to human readable form
+ ///
+ virtual void print(raw_ostream &OS, const Module* = 0) const;
+
+ /// dump - Dump the dominance frontier to dbgs().
+ void dump() const;
+};
+
+
+//===-------------------------------------
+/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
+/// used to compute a forward dominator frontiers.
+///
+class DominanceFrontier : public DominanceFrontierBase {
+public:
+ static char ID; // Pass ID, replacement for typeid
+ DominanceFrontier() :
+ DominanceFrontierBase(ID, false) {
+ initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
+ }
+
+ BasicBlock *getRoot() const {
+ assert(Roots.size() == 1 && "Should always have entry node!");
+ return Roots[0];
+ }
+
+ virtual bool runOnFunction(Function &) {
+ Frontiers.clear();
+ DominatorTree &DT = getAnalysis<DominatorTree>();
+ Roots = DT.getRoots();
+ assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
+ calculate(DT, DT[Roots[0]]);
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<DominatorTree>();
+ }
+
+ const DomSetType &calculate(const DominatorTree &DT,
+ const DomTreeNode *Node);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/DominatorInternals.h b/include/llvm/Analysis/DominatorInternals.h
index 654289e630..ae552b05ab 100644
--- a/include/llvm/Analysis/DominatorInternals.h
+++ b/include/llvm/Analysis/DominatorInternals.h
@@ -22,13 +22,9 @@
// A Fast Algorithm for Finding Dominators in a Flowgraph
// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
//
-// This implements both the O(n*ack(n)) and the O(n*log(n)) versions of EVAL and
-// LINK, but it turns out that the theoretically slower O(n*log(n))
-// implementation is actually faster than the "efficient" algorithm (even for
-// large CFGs) because the constant overheads are substantially smaller. The
-// lower-complexity version can be enabled with the following #define:
-//
-#define BALANCE_IDOM_TREE 0
+// 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.
//
//===----------------------------------------------------------------------===//
@@ -46,9 +42,6 @@ unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
VInfo.Label = V;
Vertex.push_back(V); // Vertex[n] = V;
- //Info[V].Ancestor = 0; // Ancestor[n] = 0
- //Info[V].Child = 0; // Child[v] = 0
- VInfo.Size = 1; // Size[v] = 1
for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) {
InfoRec &SuccVInfo = DT.Info[*SI];
@@ -58,10 +51,10 @@ unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
}
}
#else
- bool IsChilOfArtificialExit = (N != 0);
+ bool IsChildOfArtificialExit = (N != 0);
- std::vector<std::pair<typename GraphT::NodeType*,
- typename GraphT::ChildIteratorType> > Worklist;
+ SmallVector<std::pair<typename GraphT::NodeType*,
+ typename GraphT::ChildIteratorType>, 32> Worklist;
Worklist.push_back(std::make_pair(V, GraphT::child_begin(V)));
while (!Worklist.empty()) {
typename GraphT::NodeType* BB = Worklist.back().first;
@@ -76,14 +69,11 @@ unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
BBInfo.Label = BB;
DT.Vertex.push_back(BB); // Vertex[n] = V;
- //BBInfo[V].Ancestor = 0; // Ancestor[n] = 0
- //BBInfo[V].Child = 0; // Child[v] = 0
- BBInfo.Size = 1; // Size[v] = 1
- if (IsChilOfArtificialExit)
+ if (IsChildOfArtificialExit)
BBInfo.Parent = 1;
- IsChilOfArtificialExit = false;
+ IsChildOfArtificialExit = false;
}
// store the DFS number of the current BB - the reference to BBInfo might
@@ -114,118 +104,47 @@ unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
}
template<class GraphT>
-void Compress(DominatorTreeBase<typename GraphT::NodeType>& DT,
- typename GraphT::NodeType *VIn) {
+typename GraphT::NodeType*
+Eval(DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType *VIn, unsigned LastLinked) {
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInInfo =
+ DT.Info[VIn];
+ if (VInInfo.DFSNum < LastLinked)
+ return VIn;
+
SmallVector<typename GraphT::NodeType*, 32> Work;
SmallPtrSet<typename GraphT::NodeType*, 32> Visited;
- typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInVAInfo =
- DT.Info[DT.Vertex[DT.Info[VIn].Ancestor]];
- if (VInVAInfo.Ancestor != 0)
+ if (VInInfo.Parent >= LastLinked)
Work.push_back(VIn);
while (!Work.empty()) {
typename GraphT::NodeType* V = Work.back();
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
DT.Info[V];
- typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Ancestor];
- typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo =
- DT.Info[VAncestor];
+ typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent];
// Process Ancestor first
- if (Visited.insert(VAncestor) &&
- VAInfo.Ancestor != 0) {
+ if (Visited.insert(VAncestor) && VInfo.Parent >= LastLinked) {
Work.push_back(VAncestor);
continue;
}
Work.pop_back();
// Update VInfo based on Ancestor info
- if (VAInfo.Ancestor == 0)
+ if (VInfo.Parent < LastLinked)
continue;
+
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo =
+ DT.Info[VAncestor];
typename GraphT::NodeType* VAncestorLabel = VAInfo.Label;
typename GraphT::NodeType* VLabel = VInfo.Label;
if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
VInfo.Label = VAncestorLabel;
- VInfo.Ancestor = VAInfo.Ancestor;
- }
-}
-
-template<class GraphT>
-typename GraphT::NodeType*
-Eval(DominatorTreeBase<typename GraphT::NodeType>& DT,
- typename GraphT::NodeType *V) {
- typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
- DT.Info[V];
-#if !BALANCE_IDOM_TREE
- // Higher-complexity but faster implementation
- if (VInfo.Ancestor == 0)
- return V;
- Compress<GraphT>(DT, V);
- return VInfo.Label;
-#else
- // Lower-complexity but slower implementation
- if (VInfo.Ancestor == 0)
- return VInfo.Label;
- Compress<GraphT>(DT, V);
- GraphT::NodeType* VLabel = VInfo.Label;
-
- GraphT::NodeType* VAncestorLabel = DT.Info[VInfo.Ancestor].Label;
- if (DT.Info[VAncestorLabel].Semi >= DT.Info[VLabel].Semi)
- return VLabel;
- else
- return VAncestorLabel;
-#endif
-}
-
-template<class GraphT>
-void Link(DominatorTreeBase<typename GraphT::NodeType>& DT,
- unsigned DFSNumV, typename GraphT::NodeType* W,
- typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo) {
-#if !BALANCE_IDOM_TREE
- // Higher-complexity but faster implementation
- WInfo.Ancestor = DFSNumV;
-#else
- // Lower-complexity but slower implementation
- GraphT::NodeType* WLabel = WInfo.Label;
- unsigned WLabelSemi = DT.Info[WLabel].Semi;
- GraphT::NodeType* S = W;
- InfoRec *SInfo = &DT.Info[S];
-
- GraphT::NodeType* SChild = SInfo->Child;
- InfoRec *SChildInfo = &DT.Info[SChild];
-
- while (WLabelSemi < DT.Info[SChildInfo->Label].Semi) {
- GraphT::NodeType* SChildChild = SChildInfo->Child;
- if (SInfo->Size+DT.Info[SChildChild].Size >= 2*SChildInfo->Size) {
- SChildInfo->Ancestor = S;
- SInfo->Child = SChild = SChildChild;
- SChildInfo = &DT.Info[SChild];
- } else {
- SChildInfo->Size = SInfo->Size;
- S = SInfo->Ancestor = SChild;
- SInfo = SChildInfo;
- SChild = SChildChild;
- SChildInfo = &DT.Info[SChild];
- }
+ VInfo.Parent = VAInfo.Parent;
}
- DominatorTreeBase::InfoRec &VInfo = DT.Info[V];
- SInfo->Label = WLabel;
-
- assert(V != W && "The optimization here will not work in this case!");
- unsigned WSize = WInfo.Size;
- unsigned VSize = (VInfo.Size += WSize);
-
- if (VSize < 2*WSize)
- std::swap(S, VInfo.Child);
-
- while (S) {
- SInfo = &DT.Info[S];
- SInfo->Ancestor = V;
- S = SInfo->Child;
- }
-#endif
+ return VInInfo.Label;
}
template<class FuncT, class NodeT>
@@ -242,9 +161,6 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
BBInfo.Label = NULL;
DT.Vertex.push_back(NULL); // Vertex[n] = V;
- //BBInfo[V].Ancestor = 0; // Ancestor[n] = 0
- //BBInfo[V].Child = 0; // Child[v] = 0
- BBInfo.Size = 1; // Size[v] = 1
}
// Step #1: Number blocks in depth-first order and initialize variables used
@@ -257,12 +173,34 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
// infinite loops). In these cases an artificial exit node is required.
MultipleRoots |= (DT.isPostDominator() && N != F.size());
+ // When naively implemented, the Lengauer-Tarjan algorithm requires a separate
+ // bucket for each vertex. However, this is unnecessary, because each vertex
+ // is only placed into a single bucket (that of its semidominator), and each
+ // vertex's bucket is processed before it is added to any bucket itself.
+ //
+ // Instead of using a bucket per vertex, we use a single array Buckets that
+ // has two purposes. Before the vertex V with preorder number i is processed,
+ // Buckets[i] stores the index of the first element in V's bucket. After V's
+ // bucket is processed, Buckets[i] stores the index of the next element in the
+ // bucket containing V, if any.
+ SmallVector<unsigned, 32> Buckets;
+ Buckets.resize(N + 1);
+ for (unsigned i = 1; i <= N; ++i)
+ Buckets[i] = i;
+
for (unsigned i = N; i >= 2; --i) {
typename GraphT::NodeType* W = DT.Vertex[i];
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo =
DT.Info[W];
- // Step #2: Calculate the semidominators of all vertices
+ // Step #2: Implicitly define the immediate dominator of vertices
+ for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
+ typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
+ typename GraphT::NodeType* U = Eval<GraphT>(DT, V, i + 1);
+ DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
+ }
+
+ // Step #3: Calculate the semidominators of all vertices
// initialize the semi dominator to point to the parent node
WInfo.Semi = WInfo.Parent;
@@ -272,25 +210,28 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
E = InvTraits::child_end(W); CI != E; ++CI) {
typename InvTraits::NodeType *N = *CI;
if (DT.Info.count(N)) { // Only if this predecessor is reachable!
- unsigned SemiU = DT.Info[Eval<GraphT>(DT, N)].Semi;
+ unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi;
if (SemiU < WInfo.Semi)
WInfo.Semi = SemiU;
}
}
- DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W);
-
- typename GraphT::NodeType* WParent = DT.Vertex[WInfo.Parent];
- Link<GraphT>(DT, WInfo.Parent, W, WInfo);
+ // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is
+ // necessarily parent(V). In this case, set idom(V) here and avoid placing
+ // V into a bucket.
+ if (WInfo.Semi == WInfo.Parent) {
+ DT.IDoms[W] = DT.Vertex[WInfo.Parent];
+ } else {
+ Buckets[i] = Buckets[WInfo.Semi];
+ Buckets[WInfo.Semi] = i;
+ }
+ }
- // Step #3: Implicitly define the immediate dominator of vertices
- std::vector<typename GraphT::NodeType*> &WParentBucket =
- DT.Info[WParent].Bucket;
- while (!WParentBucket.empty()) {
- typename GraphT::NodeType* V = WParentBucket.back();
- WParentBucket.pop_back();
- typename GraphT::NodeType* U = Eval<GraphT>(DT, V);
- DT.IDoms[V] = DT.Info[U].Semi < DT.Info[V].Semi ? U : WParent;
+ if (N >= 1) {
+ typename GraphT::NodeType* Root = DT.Vertex[1];
+ for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
+ typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
+ DT.IDoms[V] = Root;
}
}
diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h
index 2620d2aaae..230e83d301 100644
--- a/include/llvm/Analysis/Dominators.h
+++ b/include/llvm/Analysis/Dominators.h
@@ -7,14 +7,8 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the following classes:
-// 1. DominatorTree: Represent dominators as an explicit tree structure.
-// 2. DominanceFrontier: Calculate and hold the dominance frontier for a
-// function.
-//
-// These data structures are listed in increasing order of complexity. It
-// takes longer to calculate the dominator frontier, for example, than the
-// DominatorTree mapping.
+// This file defines the DominatorTree class, which provides fast and efficient
+// dominance queries.
//
//===----------------------------------------------------------------------===//
@@ -23,19 +17,15 @@
#include "llvm/Pass.h"
#include "llvm/Function.h"
-#include "llvm/Instructions.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/Assembly/Writer.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
-#include <map>
-#include <set>
namespace llvm {
@@ -205,15 +195,11 @@ protected:
// Information record used during immediate dominators computation.
struct InfoRec {
unsigned DFSNum;
+ unsigned Parent;
unsigned Semi;
- unsigned Size;
- NodeT *Label, *Child;
- unsigned Parent, Ancestor;
-
- std::vector<NodeT*> Bucket;
+ NodeT *Label;
- InfoRec() : DFSNum(0), Semi(0), Size(0), Label(0), Child(0), Parent(0),
- Ancestor(0) {}
+ InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(0) {}
};
DenseMap<NodeT*, NodeT*> IDoms;
@@ -303,9 +289,6 @@ public:
: DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {}
virtual ~DominatorTreeBase() { reset(); }
- // FIXME: Should remove this
- virtual bool runOnFunction(Function &F) { return false; }
-
/// compare - Return false if the other dominator tree base matches this
/// dominator tree base. Otherwise return true.
bool compare(DominatorTreeBase &Other) const {
@@ -570,7 +553,7 @@ public:
o << "Inorder PostDominator Tree: ";
else
o << "Inorder Dominator Tree: ";
- if (this->DFSInfoValid)
+ if (!this->DFSInfoValid)
o << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
o << "\n";
@@ -581,18 +564,10 @@ public:
protected:
template<class GraphT>
- friend void Compress(DominatorTreeBase<typename GraphT::NodeType>& DT,
- typename GraphT::NodeType* VIn);
-
- template<class GraphT>
friend typename GraphT::NodeType* Eval(
DominatorTreeBase<typename GraphT::NodeType>& DT,
- typename GraphT::NodeType* V);
-
- template<class GraphT>
- friend void Link(DominatorTreeBase<typename GraphT::NodeType>& DT,
- unsigned DFSNumV, typename GraphT::NodeType* W,
- typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo);
+ typename GraphT::NodeType* V,
+ unsigned LastLinked);
template<class GraphT>
friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
@@ -766,7 +741,7 @@ public:
AU.setPreservesAll();
}
- inline bool dominates(DomTreeNode* A, DomTreeNode* B) const {
+ inline bool dominates(const DomTreeNode* A, const DomTreeNode* B) const {
return DT->dominates(A, B);
}
@@ -896,196 +871,6 @@ template <> struct GraphTraits<DominatorTree*>
};
-//===----------------------------------------------------------------------===//
-/// DominanceFrontierBase - Common base class for computing forward and inverse
-/// dominance frontiers for a function.
-///
-class DominanceFrontierBase : public FunctionPass {
-public:
- typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb
- typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
-protected:
- DomSetMapType Frontiers;
- std::vector<BasicBlock*> Roots;
- const bool IsPostDominators;
-
-public:
- DominanceFrontierBase(char &ID, bool isPostDom)
- : FunctionPass(ID), IsPostDominators(isPostDom) {}
-
- /// getRoots - Return the root blocks of the current CFG. This may include
- /// multiple blocks if we are computing post dominators. For forward
- /// dominators, this will always be a single block (the entry node).
- ///
- inline const std::vector<BasicBlock*> &getRoots() const { return Roots; }
-
- /// isPostDominator - Returns true if analysis based of postdoms
- ///
- bool isPostDominator() const { return IsPostDominators; }
-
- virtual void releaseMemory() { Frontiers.clear(); }
-
- // Accessor interface:
- typedef DomSetMapType::iterator iterator;
- typedef DomSetMapType::const_iterator const_iterator;
- iterator begin() { return Frontiers.begin(); }
- const_iterator begin() const { return Frontiers.begin(); }
- iterator end() { return Frontiers.end(); }
- const_iterator end() const { return Frontiers.end(); }
- iterator find(BasicBlock *B) { return Frontiers.find(B); }
- const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }
-
- iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
- assert(find(BB) == end() && "Block already in DominanceFrontier!");
- return Frontiers.insert(std::make_pair(BB, frontier)).first;
- }
-
- /// removeBlock - Remove basic block BB's frontier.
- void removeBlock(BasicBlock *BB) {
- assert(find(BB) != end() && "Block is not in DominanceFrontier!");
- for (iterator I = begin(), E = end(); I != E; ++I)
- I->second.erase(BB);
- Frontiers.erase(BB);
- }
-
- void addToFrontier(iterator I, BasicBlock *Node) {
- assert(I != end() && "BB is not in DominanceFrontier!");
- I->second.insert(Node);
- }
-
- void removeFromFrontier(iterator I, BasicBlock *Node) {
- assert(I != end() && "BB is not in DominanceFrontier!");
- assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
- I->second.erase(Node);
- }
-
- /// compareDomSet - Return false if two domsets match. Otherwise
- /// return true;
- bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
- std::set<BasicBlock *> tmpSet;
- for (DomSetType::const_iterator I = DS2.begin(),
- E = DS2.end(); I != E; ++I)
- tmpSet.insert(*I);
-
- for (DomSetType::const_iterator I = DS1.begin(),
- E = DS1.end(); I != E; ) {
- BasicBlock *Node = *I++;
-
- if (tmpSet.erase(Node) == 0)
- // Node is in DS1 but not in DS2.
- return true;
- }
-
- if (!tmpSet.empty())
- // There are nodes that are in DS2 but not in DS1.
- return true;
-
- // DS1 and DS2 matches.
- return false;
- }
-
- /// compare - Return true if the other dominance frontier base matches
- /// this dominance frontier base. Otherwise return false.
- bool compare(DominanceFrontierBase &Other) const {
- DomSetMapType tmpFrontiers;
- for (DomSetMapType::const_iterator I = Other.begin(),
- E = Other.end(); I != E; ++I)
- tmpFrontiers.insert(std::make_pair(I->first, I->second));
-
- for (DomSetMapType::iterator I = tmpFrontiers.begin(),
- E = tmpFrontiers.end(); I != E; ) {
- BasicBlock *Node = I->first;
- const_iterator DFI = find(Node);
- if (DFI == end())
- return true;
-
- if (compareDomSet(I->second, DFI->second))
- return true;
-
- ++I;
- tmpFrontiers.erase(Node);
- }
-
- if (!tmpFrontiers.empty())
- return true;
-
- return false;
- }
-
- /// print - Convert to human readable form
- ///
- virtual void print(raw_ostream &OS, const Module* = 0) const;
-
- /// dump - Dump the dominance frontier to dbgs().
- void dump() const;
-};
-
-
-//===-------------------------------------
-/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
-/// used to compute a forward dominator frontiers.
-///
-class DominanceFrontier : public DominanceFrontierBase {
-public:
- static char ID; // Pass ID, replacement for typeid
- DominanceFrontier() :
- DominanceFrontierBase(ID, false) {
- initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
- }
-
- BasicBlock *getRoot() const {
- assert(Roots.size() == 1 && "Should always have entry node!");
- return Roots[0];
- }
-
- virtual bool runOnFunction(Function &) {
- Frontiers.clear();
- DominatorTree &DT = getAnalysis<DominatorTree>();
- Roots = DT.getRoots();
- assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
- calculate(DT, DT[Roots[0]]);
- return false;
- }
-
- virtual void verifyAnalysis() const;
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<DominatorTree>();
- }
-
- /// splitBlock - BB is split and now it has one successor. Update dominance
- /// frontier to reflect this change.
- void splitBlock(BasicBlock *BB);
-
- /// BasicBlock BB's new dominator is NewBB. Update BB's dominance frontier
- /// to reflect this change.
- void changeImmediateDominator(BasicBlock *BB, BasicBlock *NewBB,
- DominatorTree *DT) {
- // NewBB is now dominating BB. Which means BB's dominance
- // frontier is now part of NewBB's dominance frontier. However, BB
- // itself is not member of NewBB's dominance frontier.
- DominanceFrontier::iterator NewDFI = find(NewBB);
- DominanceFrontier::iterator DFI = find(BB);
- // If BB was an entry block then its frontier is empty.
- if (DFI == end())
- return;
- DominanceFrontier::DomSetType BBSet = DFI->second;
- for (DominanceFrontier::DomSetType::iterator BBSetI = BBSet.begin(),
- BBSetE = BBSet.end(); BBSetI != BBSetE; ++BBSetI) {
- BasicBlock *DFMember = *BBSetI;
- // Insert only if NewBB dominates DFMember.
- if (!DT->dominates(NewBB, DFMember))
- NewDFI->second.insert(DFMember);
- }
- NewDFI->second.erase(BB);
- }
-
- const DomSetType &calculate(const DominatorTree &DT,
- const DomTreeNode *Node);
-};
-
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
index ccec4c5247..b08bf57ace 100644
--- a/include/llvm/Analysis/InlineCost.h
+++ b/include/llvm/Analysis/InlineCost.h
@@ -33,7 +33,7 @@ namespace llvm {
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
const int InstrCost = 5;
- const int IndirectCallBonus = 500;
+ const int IndirectCallBonus = -100;
const int CallPenalty = 25;
const int LastCallToStaticBonus = -15000;
const int ColdccPenalty = 2000;
@@ -96,10 +96,9 @@ namespace llvm {
public:
unsigned ConstantWeight;
unsigned AllocaWeight;
- unsigned ConstantBonus;
- ArgInfo(unsigned CWeight, unsigned AWeight, unsigned CBonus)
- : ConstantWeight(CWeight), AllocaWeight(AWeight), ConstantBonus(CBonus)
+ ArgInfo(unsigned CWeight, unsigned AWeight)
+ : ConstantWeight(CWeight), AllocaWeight(AWeight)
{}
};
@@ -112,8 +111,6 @@ namespace llvm {
/// entry here.
std::vector<ArgInfo> ArgumentWeights;
-
-
/// analyzeFunction - Add information about the specified function
/// to the current structure.
void analyzeFunction(Function *F);
@@ -127,6 +124,10 @@ namespace llvm {
// the ValueMap will update itself when this happens.
ValueMap<const Function *, FunctionInfo> CachedFunctionInfo;
+ int CountBonusForConstant(Value *V, Constant *C = NULL);
+ int ConstantFunctionBonus(CallSite CS, Constant *C);
+ int getInlineSize(CallSite CS, Function *Callee);
+ int getInlineBonuses(CallSite CS, Function *Callee);
public:
/// getInlineCost - The heuristic used to determine if we should inline the
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index d1ad061d5c..dff1ba2f7b 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -7,9 +7,12 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares routines for folding instructions into simpler forms that
-// do not require creating new instructions. For example, this does constant
-// folding, and can handle identities like (X&0)->0.
+// This file declares routines for folding instructions into simpler forms
+// that do not require creating new instructions. This does constant folding
+// ("add i32 1, 1" -> "2") but can also handle non-constant operands, either
+// returning a constant ("and i32 %x, 0" -> "0") or an already existing value
+// ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction
+// then it dominates the original instruction.
//
//===----------------------------------------------------------------------===//
@@ -25,37 +28,86 @@ namespace llvm {
/// SimplifyAddInst - Given operands for an Add, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
- const TargetData *TD = 0);
+ const TargetData *TD = 0, const DominatorTree *DT = 0);
+
+ /// SimplifySubInst - Given operands for a Sub, see if we can
+ /// fold the result. If not, this returns null.
+ Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
+ const TargetData *TD = 0, const DominatorTree *DT = 0);
+
+ /// SimplifyMulInst - Given operands for a Mul, see if we can
+ /// fold the result. If not, this returns null.
+ Value *SimplifyMulInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
+
+ /// SimplifySDivInst - Given operands for an SDiv, see if we can
+ /// fold the result. If not, this returns null.
+ Value *SimplifySDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
+
+ /// SimplifyUDivInst - Given operands for a UDiv, see if we can
+ /// fold the result. If not, this returns null.
+ Value *SimplifyUDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
+
+ /// SimplifyFDivInst - Given operands for an FDiv, see if we can
+ /// fold the result. If not, this returns null.
+ Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
+
+ /// SimplifyShlInst - Given operands for a Shl, see if we can
+ /// fold the result. If not, this returns null.
+ Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+ const TargetData *TD = 0, const DominatorTree *DT = 0);
+
+ /// SimplifyLShrInst - Given operands for a LShr, see if we can
+ /// fold the result. If not, this returns null.
+ Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
+ const TargetData *TD = 0, const DominatorTree *DT=0);
+
+ /// SimplifyAShrInst - Given operands for a AShr, see if we can
+ /// fold the result. If not, this returns null.
+ Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
+ const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
/// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyAndInst(Value *LHS, Value *RHS,
- const TargetData *TD = 0);
+ Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
/// SimplifyOrInst - Given operands for an Or, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyOrInst(Value *LHS, Value *RHS,
- const TargetData *TD = 0);
+ Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
+
+ /// SimplifyXorInst - Given operands for a Xor, see if we can
+ /// fold the result. If not, this returns null.
+ Value *SimplifyXorInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD = 0);
+ const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD = 0);
+ const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
- const TargetData *TD = 0);
+ const TargetData *TD = 0,
+ const DominatorTree *DT = 0);
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyGEPInst(Value * const *Ops, unsigned NumOps,
- const TargetData *TD = 0);
+ const TargetData *TD = 0, const DominatorTree *DT = 0);
//=== Helper functions for higher up the class hierarchy.
@@ -63,17 +115,15 @@ namespace llvm {
/// SimplifyCmpInst - Given operands for a CmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD = 0);
+ const TargetData *TD = 0, const DominatorTree *DT = 0);
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const TargetData *TD = 0);
+ const TargetData *TD = 0, const DominatorTree *DT = 0);
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
- /// WARNING: If called on unreachable code, an instruction may be reported
- /// to simplify to itself.
Value *SimplifyInstruction(Instruction *I, const TargetData *TD = 0,
const DominatorTree *DT = 0);
diff --git a/include/llvm/Analysis/LiveValues.h b/include/llvm/Analysis/LiveValues.h
deleted file mode 100644
index b92cb7833a..0000000000
--- a/include/llvm/Analysis/LiveValues.h
+++ /dev/null
@@ -1,99 +0,0 @@
-//===- LiveValues.h - Liveness information for LLVM IR Values. ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface for the LLVM IR Value liveness
-// analysis pass.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_LIVEVALUES_H
-#define LLVM_ANALYSIS_LIVEVALUES_H
-
-#include "llvm/Pass.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-
-namespace llvm {
-
-class DominatorTree;
-class LoopInfo;
-class Value;
-
-/// LiveValues - Analysis that provides liveness information for
-/// LLVM IR Values.
-///
-class LiveValues : public FunctionPass {
- DominatorTree *DT;
- LoopInfo *LI;
-
- /// Memo - A bunch of state to be associated with a value.
- ///
- struct Memo {
- /// Used - The set of blocks which contain a use of the value.
- ///
- SmallPtrSet<const BasicBlock *, 4> Used;
-
- /// LiveThrough - A conservative approximation of the set of blocks in
- /// which the value is live-through, meaning blocks properly dominated
- /// by the definition, and from which blocks containing uses of the
- /// value are reachable.
- ///
- SmallPtrSet<const BasicBlock *, 4> LiveThrough;
-
- /// Killed - A conservative approximation of the set of blocks in which
- /// the value is used and not live-out.
- ///
- SmallPtrSet<const BasicBlock *, 4> Killed;
- };
-
- /// Memos - Remembers the Memo for each Value. This is populated on
- /// demand.
- ///
- DenseMap<const Value *, Memo> Memos;
-
- /// getMemo - Retrieve an existing Memo for the given value if one
- /// is available, otherwise compute a new one.
- ///
- Memo &getMemo(const Value *V);
-
- /// compute - Compute a new Memo for the given value.
- ///
- Memo &compute(const Value *V);
-
-public:
- static char ID;
- LiveValues();
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual bool runOnFunction(Function &F);
- virtual void releaseMemory();
-
- /// isUsedInBlock - Test if the given value is used in the given block.
- ///
- bool isUsedInBlock(const Value *V, const BasicBlock *BB);
-
- /// isLiveThroughBlock - Test if the given value is known to be
- /// live-through the given block, meaning that the block is properly
- /// dominated by the value's definition, and there exists a block
- /// reachable from it that contains a use. This uses a conservative
- /// approximation that errs on the side of returning false.
- ///
- bool isLiveThroughBlock(const Value *V, const BasicBlock *BB);
-
- /// isKilledInBlock - Test if the given value is known to be killed in
- /// the given block, meaning that the block contains a use of the value,
- /// and no blocks reachable from the block contain a use. This uses a
- /// conservative approximation that errs on the side of returning false.
- ///
- bool isKilledInBlock(const Value *V, const BasicBlock *BB);
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 326b9d2891..392bdad5ab 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -32,6 +32,7 @@
#define LLVM_ANALYSIS_LOOP_INFO_H
#include "llvm/Pass.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallVector.h"
@@ -40,6 +41,7 @@
#include "llvm/Support/CFG.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <map>
namespace llvm {
@@ -53,6 +55,7 @@ static void RemoveFromVector(std::vector<T*> &V, T *N) {
class DominatorTree;
class LoopInfo;
class Loop;
+class PHINode;
template<class N, class M> class LoopInfoBase;
template<class N, class M> class LoopBase;
@@ -629,7 +632,7 @@ private:
template<class BlockT, class LoopT>
class LoopInfoBase {
// BBMap - Mapping of basic blocks to the inner most loop they occur in
- std::map<BlockT *, LoopT *> BBMap;
+ DenseMap<BlockT *, LoopT *> BBMap;
std::vector<LoopT *> TopLevelLoops;
friend class LoopBase<BlockT, LoopT>;
@@ -660,7 +663,7 @@ public:
/// block is in no loop (for example the entry node), null is returned.
///
LoopT *getLoopFor(const BlockT *BB) const {
- typename std::map<BlockT *, LoopT *>::const_iterator I=
+ typename DenseMap<BlockT *, LoopT *>::const_iterator I=
BBMap.find(const_cast<BlockT*>(BB));
return I != BBMap.end() ? I->second : 0;
}
@@ -728,7 +731,7 @@ public:
/// including all of the Loop objects it is nested in and our mapping from
/// BasicBlocks to loops.
void removeBlock(BlockT *BB) {
- typename std::map<BlockT *, LoopT *>::iterator I = BBMap.find(BB);
+ typename DenseMap<BlockT *, LoopT *>::iterator I = BBMap.find(BB);
if (I != BBMap.end()) {
for (LoopT *L = I->second; L; L = L->getParentLoop())
L->removeBlockFromLoop(BB);
@@ -922,7 +925,7 @@ public:
for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
TopLevelLoops[i]->print(OS);
#if 0
- for (std::map<BasicBlock*, LoopT*>::const_iterator I = BBMap.begin(),
+ for (DenseMap<BasicBlock*, LoopT*>::const_iterator I = BBMap.begin(),
E = BBMap.end(); I != E; ++I)
OS << "BB '" << I->first->getName() << "' level = "
<< I->second->getLoopDepth() << "\n";
@@ -1020,6 +1023,27 @@ public:
void removeBlock(BasicBlock *BB) {
LI.removeBlock(BB);
}
+
+ /// replacementPreservesLCSSAForm - Returns true if replacing From with To
+ /// everywhere is guaranteed to preserve LCSSA form.
+ bool replacementPreservesLCSSAForm(Instruction *From, Value *To) {
+ // Preserving LCSSA form is only problematic if the replacing value is an
+ // instruction.
+ Instruction *I = dyn_cast<Instruction>(To);
+ if (!I) return true;
+ // If both instructions are defined in the same basic block then replacement
+ // cannot break LCSSA form.
+ if (I->getParent() == From->getParent())
+ return true;
+ // If the instruction is not defined in a loop then it can safely replace
+ // anything.
+ Loop *ToLoop = getLoopFor(I->getParent());
+ if (!ToLoop) return true;
+ // If the replacing instruction is defined in the same loop as the original
+ // instruction, or in a loop that contains it as an inner loop, then using
+ // it as a replacement will not break LCSSA form.
+ return ToLoop->contains(getLoopFor(From->getParent()));
+ }
};
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index a4f916227b..22493f6f8b 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -74,6 +74,10 @@ Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
/// isFreeCall - Returns non-null if the value is a call to the builtin free()
const CallInst *isFreeCall(const Value *I);
+
+static inline CallInst *isFreeCall(Value *I) {
+ return const_cast<CallInst*>(isFreeCall((const Value*)I));
+}
} // End llvm namespace
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index cc34992b45..4d5dd1987f 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -47,6 +47,9 @@ namespace llvm {
/// pair holds the instruction that clobbers the memory. For example,
/// this occurs when we see a may-aliased store to the memory location we
/// care about.
+ ///
+ /// A dependence query on the first instruction of the entry block will
+ /// return a clobber(self) result.
Clobber,
/// Def - This is a dependence on the specified instruction which
@@ -335,11 +338,19 @@ namespace llvm {
/// critical edges.
void invalidateCachedPredecessors();
- private:
+ /// getPointerDependencyFrom - Return the instruction on which a memory
+ /// location depends. If isLoad is true, this routine ignores may-aliases
+ /// with read-only operations. If isLoad is false, this routine ignores
+ /// may-aliases with reads from read-only locations.
+ ///
+ /// Note that this is an uncached query, and thus may be inefficient.
+ ///
MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
bool isLoad,
BasicBlock::iterator ScanIt,
BasicBlock *BB);
+
+ private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
BasicBlock::iterator ScanIt,
BasicBlock *BB);
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
index 64bd290dd6..0eff75fe2f 100644
--- a/include/llvm/Analysis/Passes.h
+++ b/include/llvm/Analysis/Passes.h
@@ -116,6 +116,28 @@ namespace llvm {
//===--------------------------------------------------------------------===//
//
+ // createPathProfileLoaderPass - This pass loads information from a path
+ // profile dump file.
+ //
+ ModulePass *createPathProfileLoaderPass();
+ extern char &PathProfileLoaderPassID;
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createNoPathProfileInfoPass - This pass implements the default
+ // "no path profile".
+ //
+ ImmutablePass *createNoPathProfileInfoPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createPathProfileVerifierPass - This pass verifies path profiling
+ // information.
+ //
+ ModulePass *createPathProfileVerifierPass();
+
+ //===--------------------------------------------------------------------===//
+ //
// createDSAAPass - This pass implements simple context sensitive alias
// analysis.
//
@@ -137,12 +159,6 @@ namespace llvm {
//===--------------------------------------------------------------------===//
//
- // createLiveValuesPass - This creates an instance of the LiveValues pass.
- //
- FunctionPass *createLiveValuesPass();
-
- //===--------------------------------------------------------------------===//
- //
/// createLazyValueInfoPass - This creates an instance of the LazyValueInfo
/// pass.
FunctionPass *createLazyValueInfoPass();
@@ -153,7 +169,7 @@ namespace llvm {
// LoopDependenceAnalysis pass.
//
LoopPass *createLoopDependenceAnalysisPass();
-
+
// Minor pass prototypes, allowing us to expose them through bugpoint and
// analyze.
FunctionPass *createInstCountPass();
diff --git a/include/llvm/Analysis/PathNumbering.h b/include/llvm/Analysis/PathNumbering.h
new file mode 100644
index 0000000000..7025e28484
--- /dev/null
+++ b/include/llvm/Analysis/PathNumbering.h
@@ -0,0 +1,304 @@
+//===- PathNumbering.h ----------------------------------------*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Ball-Larus path numbers uniquely identify paths through a directed acyclic
+// graph (DAG) [Ball96]. For a CFG backedges are removed and replaced by phony
+// edges to obtain a DAG, and thus the unique path numbers [Ball96].
+//
+// The purpose of this analysis is to enumerate the edges in a CFG in order
+// to obtain paths from path numbers in a convenient manner. As described in
+// [Ball96] edges can be enumerated such that given a path number by following
+// the CFG and updating the path number, the path is obtained.
+//
+// [Ball96]
+// T. Ball and J. R. Larus. "Efficient Path Profiling."
+// International Symposium on Microarchitecture, pages 46-57, 1996.
+// http://portal.acm.org/citation.cfm?id=243857
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PATH_NUMBERING_H
+#define LLVM_PATH_NUMBERING_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Analysis/ProfileInfoTypes.h"
+#include <map>
+#include <stack>
+#include <vector>
+
+namespace llvm {
+class BallLarusNode;
+class BallLarusEdge;
+class BallLarusDag;
+
+// typedefs for storage/ interators of various DAG components
+typedef std::vector<BallLarusNode*> BLNodeVector;
+typedef std::vector<BallLarusNode*>::iterator BLNodeIterator;
+typedef std::vector<BallLarusEdge*> BLEdgeVector;
+typedef std::vector<BallLarusEdge*>::iterator BLEdgeIterator;
+typedef std::map<BasicBlock*, BallLarusNode*> BLBlockNodeMap;
+typedef std::stack<BallLarusNode*> BLNodeStack;
+
+// Represents a basic block with information necessary for the BallLarus
+// algorithms.
+class BallLarusNode {
+public:
+ enum NodeColor { WHITE, GRAY, BLACK };
+
+ // Constructor: Initializes a new Node for the given BasicBlock
+ BallLarusNode(BasicBlock* BB) :
+ _basicBlock(BB), _numberPaths(0), _color(WHITE) {
+ static unsigned nextUID = 0;
+ _uid = nextUID++;
+ }
+
+ // Returns the basic block for the BallLarusNode
+ BasicBlock* getBlock();
+
+ // Get/set the number of paths to the exit starting at the node.
+ unsigned getNumberPaths();
+ void setNumberPaths(unsigned numberPaths);
+
+ // Get/set the NodeColor used in graph algorithms.
+ NodeColor getColor();
+ void setColor(NodeColor color);
+
+ // Iterator information for predecessor edges. Includes phony and
+ // backedges.
+ BLEdgeIterator predBegin();
+ BLEdgeIterator predEnd();
+ unsigned getNumberPredEdges();
+
+ // Iterator information for successor edges. Includes phony and
+ // backedges.
+ BLEdgeIterator succBegin();
+ BLEdgeIterator succEnd();
+ unsigned getNumberSuccEdges();
+
+ // Add an edge to the predecessor list.
+ void addPredEdge(BallLarusEdge* edge);
+
+ // Remove an edge from the predecessor list.
+ void removePredEdge(BallLarusEdge* edge);
+
+ // Add an edge to the successor list.
+ void addSuccEdge(BallLarusEdge* edge);
+
+ // Remove an edge from the successor list.
+ void removeSuccEdge(BallLarusEdge* edge);
+
+ // Returns the name of the BasicBlock being represented. If BasicBlock
+ // is null then returns "<null>". If BasicBlock has no name, then
+ // "<unnamed>" is returned. Intended for use with debug output.
+ std::string getName();
+
+private:
+ // The corresponding underlying BB.
+ BasicBlock* _basicBlock;
+
+ // Holds the predecessor edges of this node.
+ BLEdgeVector _predEdges;
+
+ // Holds the successor edges of this node.
+ BLEdgeVector _succEdges;
+
+ // The number of paths from the node to the exit.
+ unsigned _numberPaths;
+
+ // 'Color' used by graph algorithms to mark the node.
+ NodeColor _color;
+
+ // Unique ID to ensure naming difference with dotgraphs
+ unsigned _uid;
+
+ // Removes an edge from an edgeVector. Used by removePredEdge and
+ // removeSuccEdge.
+ void removeEdge(BLEdgeVector& v, BallLarusEdge* e);
+};
+
+// Represents an edge in the Dag. For an edge, v -> w, v is the source, and
+// w is the target.
+class BallLarusEdge {
+public:
+ enum EdgeType { NORMAL, BACKEDGE, SPLITEDGE,
+ BACKEDGE_PHONY, SPLITEDGE_PHONY, CALLEDGE_PHONY };
+
+ // Constructor: Initializes an BallLarusEdge with a source and target.
+ BallLarusEdge(BallLarusNode* source, BallLarusNode* target,
+ unsigned duplicateNumber)
+ : _source(source), _target(target), _weight(0), _edgeType(NORMAL),
+ _realEdge(NULL), _duplicateNumber(duplicateNumber) {}
+
+ // Returns the source/ target node of this edge.
+ BallLarusNode* getSource() const;
+ BallLarusNode* getTarget() const;
+
+ // Sets the type of the edge.
+ EdgeType getType() const;
+
+ // Gets the type of the edge.
+ void setType(EdgeType type);
+
+ // Returns the weight of this edge. Used to decode path numbers to
+ // sequences of basic blocks.
+ unsigned getWeight();
+
+ // Sets the weight of the edge. Used during path numbering.
+ void setWeight(unsigned weight);
+
+ // Gets/sets the phony edge originating at the root.
+ BallLarusEdge* getPhonyRoot();
+ void setPhonyRoot(BallLarusEdge* phonyRoot);
+
+ // Gets/sets the phony edge terminating at the exit.
+ BallLarusEdge* getPhonyExit();
+ void setPhonyExit(BallLarusEdge* phonyExit);
+
+ // Gets/sets the associated real edge if this is a phony edge.
+ BallLarusEdge* getRealEdge();
+ void setRealEdge(BallLarusEdge* realEdge);
+
+ // Returns the duplicate number of the edge.
+ unsigned getDuplicateNumber();
+
+protected:
+ // Source node for this edge.
+ BallLarusNode* _source;
+
+ // Target node for this edge.
+ BallLarusNode* _target;
+
+private:
+ // Edge weight cooresponding to path number increments before removing
+ // increments along a spanning tree. The sum over the edge weights gives
+ // the path number.
+ unsigned _weight;
+
+ // Type to represent for what this edge is intended
+ EdgeType _edgeType;
+
+ // For backedges and split-edges, the phony edge which is linked to the
+ // root node of the DAG. This contains a path number initialization.
+ BallLarusEdge* _phonyRoot;
+
+ // For backedges and split-edges, the phony edge which is linked to the
+ // exit node of the DAG. This contains a path counter increment, and
+ // potentially a path number increment.
+ BallLarusEdge* _phonyExit;
+
+ // If this is a phony edge, _realEdge is a link to the back or split
+ // edge. Otherwise, this is null.
+ BallLarusEdge* _realEdge;
+
+ // An ID to differentiate between those edges which have the same source
+ // and destination blocks.
+ unsigned _duplicateNumber;
+};
+
+// Represents the Ball Larus DAG for a given Function. Can calculate
+// various properties required for instrumentation or analysis. E.g. the
+// edge weights that determine the path number.
+class BallLarusDag {
+public:
+ // Initializes a BallLarusDag from the CFG of a given function. Must
+ // call init() after creation, since some initialization requires
+ // virtual functions.
+ BallLarusDag(Function &F)
+ : _root(NULL), _exit(NULL), _function(F) {}
+
+ // Initialization that requires virtual functions which are not fully
+ // functional in the constructor.
+ void init();
+
+ // Frees all memory associated with the DAG.
+ virtual ~BallLarusDag();
+
+ // Calculate the path numbers by assigning edge increments as prescribed
+ // in Ball-Larus path profiling.
+ void calculatePathNumbers();
+
+ // Returns the number of paths for the DAG.
+ unsigned getNumberOfPaths();
+
+ // Returns the root (i.e. entry) node for the DAG.
+ BallLarusNode* getRoot();
+
+ // Returns the exit node for the DAG.
+ BallLarusNode* getExit();
+
+ // Returns the function for the DAG.
+ Function& getFunction();
+
+ // Clears the node colors.
+ void clearColors(BallLarusNode::NodeColor color);
+
+protected:
+ // All nodes in the DAG.
+ BLNodeVector _nodes;
+
+ // All edges in the DAG.
+ BLEdgeVector _edges;
+
+ // All backedges in the DAG.
+ BLEdgeVector _backEdges;
+
+ // Allows subclasses to determine which type of Node is created.
+ // Override this method to produce subclasses of BallLarusNode if
+ // necessary. The destructor of BallLarusDag will call free on each pointer
+ // created.
+ virtual BallLarusNode* createNode(BasicBlock* BB);
+
+ // Allows subclasses to determine which type of Edge is created.
+ // Override this method to produce subclasses of BallLarusEdge if
+ // necessary. Parameters source and target will have been created by
+ // createNode and can be cast to the subclass of BallLarusNode*
+ // returned by createNode. The destructor of BallLarusDag will call free
+ // on each pointer created.
+ virtual BallLarusEdge* createEdge(BallLarusNode* source, BallLarusNode*
+ target, unsigned duplicateNumber);
+
+ // Proxy to node's constructor. Updates the DAG state.
+ BallLarusNode* addNode(BasicBlock* BB);
+
+ // Proxy to edge's constructor. Updates the DAG state.
+ BallLarusEdge* addEdge(BallLarusNode* source, BallLarusNode* target,
+ unsigned duplicateNumber);
+
+private:
+ // The root (i.e. entry) node for this DAG.
+ BallLarusNode* _root;
+
+ // The exit node for this DAG.
+ BallLarusNode* _exit;
+
+ // The function represented by this DAG.
+ Function& _function;
+
+ // Processes one node and its imediate edges for building the DAG.
+ void buildNode(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>& dfsStack);
+
+ // Process an edge in the CFG for DAG building.
+ void buildEdge(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>& dfsStack,
+ BallLarusNode* currentNode, BasicBlock* succBB,
+ unsigned duplicateNumber);
+
+ // The weight on each edge is the increment required along any path that
+ // contains that edge.
+ void calculatePathNumbersFrom(BallLarusNode* node);
+
+ // Adds a backedge with its phony edges. Updates the DAG state.
+ void addBackedge(BallLarusNode* source, BallLarusNode* target,
+ unsigned duplicateCount);
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/PathProfileInfo.h b/include/llvm/Analysis/PathProfileInfo.h
new file mode 100644
index 0000000000..263763f7a8
--- /dev/null
+++ b/include/llvm/Analysis/PathProfileInfo.h
@@ -0,0 +1,113 @@
+//===- PathProfileInfo.h --------------------------------------*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file outlines the interface used by optimizers to load path profiles.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PATHPROFILEINFO_H
+#define LLVM_PATHPROFILEINFO_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Analysis/PathNumbering.h"
+#include <stack>
+
+namespace llvm {
+
+class ProfilePath;
+class ProfilePathEdge;
+class PathProfileInfo;
+
+typedef std::vector<ProfilePathEdge> ProfilePathEdgeVector;
+typedef std::vector<ProfilePathEdge>::iterator ProfilePathEdgeIterator;
+
+typedef std::vector<BasicBlock*> ProfilePathBlockVector;
+typedef std::vector<BasicBlock*>::iterator ProfilePathBlockIterator;
+
+typedef std::map<unsigned int,ProfilePath*> ProfilePathMap;
+typedef std::map<unsigned int,ProfilePath*>::iterator ProfilePathIterator;
+
+typedef std::map<Function*,unsigned int> FunctionPathCountMap;
+typedef std::map<Function*,ProfilePathMap> FunctionPathMap;
+typedef std::map<Function*,ProfilePathMap>::iterator FunctionPathIterator;
+
+class ProfilePathEdge {
+public:
+ ProfilePathEdge(BasicBlock* source, BasicBlock* target,
+ unsigned duplicateNumber);
+
+ inline unsigned getDuplicateNumber() { return _duplicateNumber; }
+ inline BasicBlock* getSource() { return _source; }
+ inline BasicBlock* getTarget() { return _target; }
+
+protected:
+ BasicBlock* _source;
+ BasicBlock* _target;
+ unsigned _duplicateNumber;
+};
+
+class ProfilePath {
+public:
+ ProfilePath(unsigned int number, unsigned int count,
+ double countStdDev, PathProfileInfo* ppi);
+
+ double getFrequency() const;
+
+ inline unsigned int getNumber() const { return _number; }
+ inline unsigned int getCount() const { return _count; }
+ inline double getCountStdDev() const { return _countStdDev; }
+
+ ProfilePathEdgeVector* getPathEdges() const;
+ ProfilePathBlockVector* getPathBlocks() const;
+
+ BasicBlock* getFirstBlockInPath() const;
+
+private:
+ unsigned int _number;
+ unsigned int _count;
+ double _countStdDev;
+
+ // double pointer back to the profiling info
+ PathProfileInfo* _ppi;
+};
+
+// TODO: overload [] operator for getting path
+// Add: getFunctionCallCount()
+class PathProfileInfo {
+ public:
+ PathProfileInfo();
+ ~PathProfileInfo();
+
+ void setCurrentFunction(Function* F);
+ Function* getCurrentFunction() const;
+ BasicBlock* getCurrentFunctionEntry();
+
+ ProfilePath* getPath(unsigned int number);
+ unsigned int getPotentialPathCount();
+
+ ProfilePathIterator pathBegin();
+ ProfilePathIterator pathEnd();
+ unsigned int pathsRun();
+
+ static char ID; // Pass identification
+ std::string argList;
+
+protected:
+ FunctionPathMap _functionPaths;
+ FunctionPathCountMap _functionPathCounts;
+
+private:
+ BallLarusDag* _currentDag;
+ Function* _currentFunction;
+
+ friend class ProfilePath;
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h
index b75dd909a9..2cd6ae346e 100644
--- a/include/llvm/Analysis/PostDominators.h
+++ b/include/llvm/Analysis/PostDominators.h
@@ -14,7 +14,7 @@
#ifndef LLVM_ANALYSIS_POST_DOMINATORS_H
#define LLVM_ANALYSIS_POST_DOMINATORS_H
-#include "llvm/Analysis/Dominators.h"
+#include "llvm/Analysis/DominanceFrontier.h"
namespace llvm {
diff --git a/include/llvm/Analysis/ProfileInfoTypes.h b/include/llvm/Analysis/ProfileInfoTypes.h
index 0d531d5c5f..6b4ac85082 100644
--- a/include/llvm/Analysis/ProfileInfoTypes.h
+++ b/include/llvm/Analysis/ProfileInfoTypes.h
@@ -1,4 +1,4 @@
-/*===-- ProfileInfoTypes.h - Profiling info shared constants ------*- C -*-===*\
+/*===-- ProfileInfoTypes.h - Profiling info shared constants --------------===*\
|*
|* The LLVM Compiler Infrastructure
|*
@@ -16,6 +16,17 @@
#ifndef LLVM_ANALYSIS_PROFILEINFOTYPES_H
#define LLVM_ANALYSIS_PROFILEINFOTYPES_H
+/* Included by libprofile. */
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* IDs to distinguish between those path counters stored in hashses vs arrays */
+enum ProfilingStorageType {
+ ProfilingArray = 1,
+ ProfilingHash = 2
+};
+
enum ProfilingType {
ArgumentInfo = 1, /* The command line argument block */
FunctionInfo = 2, /* Function profiling information */
@@ -26,4 +37,24 @@ enum ProfilingType {
OptEdgeInfo = 7 /* Edge profiling information, optimal version */
};
+/*
+ * The header for tables that map path numbers to path counters.
+ */
+typedef struct {
+ unsigned fnNumber; /* function number for these counters */
+ unsigned numEntries; /* number of entries stored */
+} PathProfileHeader;
+
+/*
+ * Describes an entry in a tagged table for path counters.
+ */
+typedef struct {
+ unsigned pathNumber;
+ unsigned pathCounter;
+} PathProfileTableEntry;
+
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* LLVM_ANALYSIS_PROFILEINFOTYPES_H */
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index 737d46cac6..a36ca110d8 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -305,6 +305,20 @@ public:
/// NULL if such a basic block does not exist.
Region *getExpandedRegion() const;
+ /// @brief Return the first block of this region's single entry edge,
+ /// if existing.
+ ///
+ /// @return The BasicBlock starting this region's single entry edge,
+ /// else NULL.
+ BasicBlock *getEnteringBlock() const;
+
+ /// @brief Return the first block of this region's single exit edge,
+ /// if existing.
+ ///
+ /// @return The BasicBlock starting this region's single exit edge,
+ /// else NULL.
+ BasicBlock *getExitingBlock() const;
+
/// @brief Is this a simple region?
///
/// A region is simple if it has exactly one exit and one entry edge.
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 1fa94e9c31..d1938061be 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -24,7 +24,7 @@
#include "llvm/Pass.h"
#include "llvm/Instructions.h"
#include "llvm/Function.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ConstantRange.h"
@@ -70,27 +70,16 @@ namespace llvm {
private:
SCEV(const SCEV &); // DO NOT IMPLEMENT
void operator=(const SCEV &); // DO NOT IMPLEMENT
- protected:
- virtual ~SCEV();
+
public:
explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) :
FastID(ID), SCEVType(SCEVTy), SubclassData(0) {}
unsigned getSCEVType() const { return SCEVType; }
- /// isLoopInvariant - Return true if the value of this SCEV is unchanging in
- /// the specified loop.
- virtual bool isLoopInvariant(const Loop *L) const = 0;
-
- /// hasComputableLoopEvolution - Return true if this SCEV changes value in a
- /// known way in the specified loop. This property being true implies that
- /// the value is variant in the loop AND that we can emit an expression to
- /// compute the value of the expression at any particular loop iteration.
- virtual bool hasComputableLoopEvolution(const Loop *L) const = 0;
-
/// getType - Return the LLVM type of this SCEV expression.
///
- virtual const Type *getType() const = 0;
+ const Type *getType() const;
/// isZero - Return true if the expression is a constant zero.
///
@@ -105,22 +94,10 @@ namespace llvm {
///
bool isAllOnesValue() const;
- /// hasOperand - Test whether this SCEV has Op as a direct or
- /// indirect operand.
- virtual bool hasOperand(const SCEV *Op) const = 0;
-
- /// dominates - Return true if elements that makes up this SCEV dominates
- /// the specified basic block.
- virtual bool dominates(BasicBlock *BB, DominatorTree *DT) const = 0;
-
- /// properlyDominates - Return true if elements that makes up this SCEV
- /// properly dominate the specified basic block.
- virtual bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const = 0;
-
/// print - Print out the internal representation of this scalar to the
/// specified stream. This should really only be used for debugging
/// purposes.
- virtual void print(raw_ostream &OS) const = 0;
+ void print(raw_ostream &OS) const;
/// dump - This method is used for debugging.
///
@@ -155,21 +132,6 @@ namespace llvm {
struct SCEVCouldNotCompute : public SCEV {
SCEVCouldNotCompute();
- // None of these methods are valid for this object.
- virtual bool isLoopInvariant(const Loop *L) const;
- virtual const Type *getType() const;
- virtual bool hasComputableLoopEvolution(const Loop *L) const;
- virtual void print(raw_ostream &OS) const;
- virtual bool hasOperand(const SCEV *Op) const;
-
- virtual bool dominates(BasicBlock *BB, DominatorTree *DT) const {
- return true;
- }
-
- virtual bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const {
- return true;
- }
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCouldNotCompute *S) { return true; }
static bool classof(const SCEV *S);
@@ -180,6 +142,24 @@ namespace llvm {
/// they must ask this class for services.
///
class ScalarEvolution : public FunctionPass {
+ public:
+ /// LoopDisposition - An enum describing the relationship between a
+ /// SCEV and a loop.
+ enum LoopDisposition {
+ LoopVariant, ///< The SCEV is loop-variant (unknown).
+ LoopInvariant, ///< The SCEV is loop-invariant.
+ LoopComputable ///< The SCEV varies predictably with the loop.
+ };
+
+ /// BlockDisposition - An enum describing the relationship between a
+ /// SCEV and a basic block.
+ enum BlockDisposition {
+ DoesNotDominateBlock, ///< The SCEV does not dominate the block.
+ DominatesBlock, ///< The SCEV dominates the block.
+ ProperlyDominatesBlock ///< The SCEV properly dominates the block.
+ };
+
+ private:
/// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be
/// notified whenever a Value is deleted.
class SCEVCallbackVH : public CallbackVH {
@@ -267,6 +247,46 @@ namespace llvm {
std::map<const SCEV *,
std::map<const Loop *, const SCEV *> > ValuesAtScopes;
+ /// LoopDispositions - Memoized computeLoopDisposition results.
+ std::map<const SCEV *,
+ std::map<const Loop *, LoopDisposition> > LoopDispositions;
+
+ /// computeLoopDisposition - Compute a LoopDisposition value.
+ LoopDisposition computeLoopDisposition(const SCEV *S, const Loop *L);
+
+ /// BlockDispositions - Memoized computeBlockDisposition results.
+ std::map<const SCEV *,
+ std::map<const BasicBlock *, BlockDisposition> > BlockDispositions;
+
+ /// computeBlockDisposition - Compute a BlockDisposition value.
+ BlockDisposition computeBlockDisposition(const SCEV *S, const BasicBlock *BB);
+
+ /// UnsignedRanges - Memoized results from getUnsignedRange
+ DenseMap<const SCEV *, ConstantRange> UnsignedRanges;
+
+ /// SignedRanges - Memoized results from getSignedRange
+ DenseMap<const SCEV *, ConstantRange> SignedRanges;
+
+ /// setUnsignedRange - Set the memoized unsigned range for the given SCEV.
+ const ConstantRange &setUnsignedRange(const SCEV *S,
+ const ConstantRange &CR) {
+ std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
+ UnsignedRanges.insert(std::make_pair(S, CR));
+ if (!Pair.second)
+ Pair.first->second = CR;
+ return Pair.first->second;
+ }
+
+ /// setUnsignedRange - Set the memoized signed range for the given SCEV.
+ const ConstantRange &setSignedRange(const SCEV *S,
+ const ConstantRange &CR) {
+ std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
+ SignedRanges.insert(std::make_pair(S, CR));
+ if (!Pair.second)
+ Pair.first->second = CR;
+ return Pair.first->second;
+ }
+
/// createSCEV - We know that there is no SCEV for the specified value.
/// Analyze the expression.
const SCEV *createSCEV(Value *V);
@@ -408,6 +428,9 @@ namespace llvm {
bool isKnownPredicateWithRanges(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS);
+ /// forgetMemoizedResults - Drop memoized information computed for S.
+ void forgetMemoizedResults(const SCEV *S);
+
public:
static char ID; // Pass identification, replacement for typeid
ScalarEvolution();
@@ -514,10 +537,11 @@ namespace llvm {
///
const SCEV *getNotSCEV(const SCEV *V);
- /// getMinusSCEV - Return LHS-RHS.
- ///
- const SCEV *getMinusSCEV(const SCEV *LHS,
- const SCEV *RHS);
+ /// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1,
+ /// and thus the HasNUW and HasNSW bits apply to the resultant add, not
+ /// whether the sub would have overflowed.
+ const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
+ bool HasNUW = false, bool HasNSW = false);
/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion
/// of the input value to the specified type. If the type must be
@@ -675,6 +699,36 @@ namespace llvm {
const SCEV *&LHS,
const SCEV *&RHS);
+ /// getLoopDisposition - Return the "disposition" of the given SCEV with
+ /// respect to the given loop.
+ LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L);
+
+ /// isLoopInvariant - Return true if the value of the given SCEV is
+ /// unchanging in the specified loop.
+ bool isLoopInvariant(const SCEV *S, const Loop *L);
+
+ /// hasComputableLoopEvolution - Return true if the given SCEV changes value
+ /// in a known way in the specified loop. This property being true implies
+ /// that the value is variant in the loop AND that we can emit an expression
+ /// to compute the value of the expression at any particular loop iteration.
+ bool hasComputableLoopEvolution(const SCEV *S, const Loop *L);
+
+ /// getLoopDisposition - Return the "disposition" of the given SCEV with
+ /// respect to the given block.
+ BlockDisposition getBlockDisposition(const SCEV *S, const BasicBlock *BB);
+
+ /// dominates - Return true if elements that makes up the given SCEV
+ /// dominate the specified basic block.
+ bool dominates(const SCEV *S, const BasicBlock *BB);
+
+ /// properlyDominates - Return true if elements that makes up the given SCEV
+ /// properly dominate the specified basic block.
+ bool properlyDominates(const SCEV *S, const BasicBlock *BB);
+
+ /// hasOperand - Test whether the given SCEV has Op as a direct or
+ /// indirect operand.
+ bool hasOperand(const SCEV *S, const SCEV *Op) const;
+
virtual bool runOnFunction(Function &F);
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index 4b02f82035..39d378ed9b 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -35,6 +35,9 @@ namespace llvm {
std::set<AssertingVH<Value> > InsertedValues;
std::set<AssertingVH<Value> > InsertedPostIncValues;
+ /// RelevantLoops - A memoization of the "relevant" loop for a given SCEV.
+ DenseMap<const SCEV *, const Loop *> RelevantLoops;
+
/// PostIncLoops - Addrecs referring to any of the given loops are expanded
/// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mode
/// returns the add instruction that adds one to the phi for {0,+,1}<L>,
@@ -168,6 +171,9 @@ namespace llvm {
return InsertedValues.count(I) || InsertedPostIncValues.count(I);
}
+ /// getRelevantLoop - Determine the most "relevant" loop for the given SCEV.
+ const Loop *getRelevantLoop(const SCEV *);
+
Value *visitConstant(const SCEVConstant *S) {
return S->getValue();
}
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index 4213a28701..db432c8173 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -42,29 +42,7 @@ namespace llvm {
public:
ConstantInt *getValue() const { return V; }
- virtual bool isLoopInvariant(const Loop *L) const {
- return true;
- }
-
- virtual bool hasComputableLoopEvolution(const Loop *L) const {
- return false; // Not loop variant
- }
-
- virtual const Type *getType() const;
-
- virtual bool hasOperand(const SCEV *) const {
- return false;
- }
-
- bool dominates(BasicBlock *BB, DominatorTree *DT) const {
- return true;
- }
-
- bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const {
- return true;
- }
-
- virtual void print(raw_ostream &OS) const;
+ const Type *getType() const { return V->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVConstant *S) { return true; }
@@ -86,23 +64,7 @@ namespace llvm {
public:
const SCEV *getOperand() const { return Op; }
- virtual const Type *getType() const { return Ty; }
-
- virtual bool isLoopInvariant(const Loop *L) const {
- return Op->isLoopInvariant(L);
- }
-
- virtual bool hasComputableLoopEvolution(const Loop *L) const {
- return Op->hasComputableLoopEvolution(L);
- }
-
- virtual bool hasOperand(const SCEV *O) const {
- return Op == O || Op->hasOperand(O);
- }
-
- virtual bool dominates(BasicBlock *BB, DominatorTree *DT) const;
-
- virtual bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
+ const Type *getType() const { return Ty; }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCastExpr *S) { return true; }
@@ -124,8 +86,6 @@ namespace llvm {
const SCEV *op, const Type *ty);
public:
- virtual void print(raw_ostream &OS) const;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVTruncateExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
@@ -144,8 +104,6 @@ namespace llvm {
const SCEV *op, const Type *ty);
public:
- virtual void print(raw_ostream &OS) const;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVZeroExtendExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
@@ -164,8 +122,6 @@ namespace llvm {
const SCEV *op, const Type *ty);
public:
- virtual void print(raw_ostream &OS) const;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVSignExtendExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
@@ -202,20 +158,7 @@ namespace llvm {
op_iterator op_begin() const { return Operands; }
op_iterator op_end() const { return Operands + NumOperands; }
- virtual bool isLoopInvariant(const Loop *L) const;
-
- // hasComputableLoopEvolution - N-ary expressions have computable loop
- // evolutions iff they have at least one operand that varies with the loop,
- // but that all varying operands are computable.
- virtual bool hasComputableLoopEvolution(const Loop *L) const;
-
- virtual bool hasOperand(const SCEV *O) const;
-
- bool dominates(BasicBlock *BB, DominatorTree *DT) const;
-
- bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
-
- virtual const Type *getType() const { return getOperand(0)->getType(); }
+ const Type *getType() const { return getOperand(0)->getType(); }
bool hasNoUnsignedWrap() const { return SubclassData & (1 << 0); }
void setHasNoUnsignedWrap(bool B) {
@@ -248,10 +191,6 @@ namespace llvm {
: SCEVNAryExpr(ID, T, O, N) {}
public:
- virtual const char *getOperationStr() const = 0;
-
- virtual void print(raw_ostream &OS) const;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCommutativeExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
@@ -275,9 +214,7 @@ namespace llvm {
}
public:
- virtual const char *getOperationStr() const { return " + "; }
-
- virtual const Type *getType() const {
+ const Type *getType() const {
// Use the type of the last operand, which is likely to be a pointer
// type, if there is one. This doesn't usually matter, but it can help
// reduce casts when the expressions are expanded.
@@ -303,8 +240,6 @@ namespace llvm {
}
public:
- virtual const char *getOperationStr() const { return " * "; }
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVMulExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
@@ -328,27 +263,15 @@ namespace llvm {
const SCEV *getLHS() const { return LHS; }
const SCEV *getRHS() const { return RHS; }
- virtual bool isLoopInvariant(const Loop *L) const {
- return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L);
- }
-
- virtual bool hasComputableLoopEvolution(const Loop *L) const {
- return LHS->hasComputableLoopEvolution(L) &&
- RHS->hasComputableLoopEvolution(L);
- }
-
- virtual bool hasOperand(const SCEV *O) const {
- return O == LHS || O == RHS || LHS->hasOperand(O) || RHS->hasOperand(O);
+ const Type *getType() const {
+ // In most cases the types of LHS and RHS will be the same, but in some
+ // crazy cases one or the other may be a pointer. ScalarEvolution doesn't
+ // depend on the type for correctness, but handling types carefully can
+ // avoid extra casts in the SCEVExpander. The LHS is more likely to be
+ // a pointer type than the RHS, so use the RHS' type here.
+ return getRHS()->getType();
}
- bool dominates(BasicBlock *BB, DominatorTree *DT) const;
-
- bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
-
- virtual const Type *getType() const;
-
- void print(raw_ostream &OS) const;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUDivExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
@@ -373,11 +296,7 @@ namespace llvm {
SCEVAddRecExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N, const Loop *l)
- : SCEVNAryExpr(ID, scAddRecExpr, O, N), L(l) {
- for (size_t i = 0, e = NumOperands; i != e; ++i)
- assert(Operands[i]->isLoopInvariant(l) &&
- "Operands of AddRec must be loop-invariant!");
- }
+ : SCEVNAryExpr(ID, scAddRecExpr, O, N), L(l) {}
public:
const SCEV *getStart() const { return Operands[0]; }
@@ -393,16 +312,6 @@ namespace llvm {
getLoop());
}
- virtual bool hasComputableLoopEvolution(const Loop *QL) const {
- return L == QL;
- }
-
- virtual bool isLoopInvariant(const Loop *QueryLoop) const;
-
- bool dominates(BasicBlock *BB, DominatorTree *DT) const;
-
- bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
-
/// isAffine - Return true if this is an affine AddRec (i.e., it represents
/// an expressions A+B*x where A and B are loop invariant values.
bool isAffine() const {
@@ -437,8 +346,6 @@ namespace llvm {
return cast<SCEVAddRecExpr>(SE.getAddExpr(this, getStepRecurrence(SE)));
}
- virtual void print(raw_ostream &OS) const;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVAddRecExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
@@ -462,8 +369,6 @@ namespace llvm {
}
public:
- virtual const char *getOperationStr() const { return " smax "; }
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVSMaxExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
@@ -487,8 +392,6 @@ namespace llvm {
}
public:
- virtual const char *getOperationStr() const { return " umax "; }
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUMaxExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
@@ -534,22 +437,7 @@ namespace llvm {
bool isAlignOf(const Type *&AllocTy) const;
bool isOffsetOf(const Type *&STy, Constant *&FieldNo) const;
- virtual bool isLoopInvariant(const Loop *L) const;
- virtual bool hasComputableLoopEvolution(const Loop *QL) const {
- return false; // not computable
- }
-
- virtual bool hasOperand(const SCEV *) const {
- return false;
- }
-
- bool dominates(BasicBlock *BB, DominatorTree *DT) const;
-
- bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
-
- virtual const Type *getType() const;
-
- virtual void print(raw_ostream &OS) const;
+ const Type *getType() const { return getValPtr()->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUnknown *S) { return true; }
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index 7b6026fea0..6df1693c78 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -15,7 +15,7 @@
#ifndef LLVM_ANALYSIS_VALUETRACKING_H
#define LLVM_ANALYSIS_VALUETRACKING_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
@@ -39,6 +39,23 @@ namespace llvm {
APInt &KnownOne, const TargetData *TD = 0,
unsigned Depth = 0);
+ /// ComputeSignBit - Determine whether the sign bit is known to be zero or
+ /// one. Convenience wrapper around ComputeMaskedBits.
+ void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
+ const TargetData *TD = 0, unsigned Depth = 0);
+
+ /// isPowerOfTwo - Return true if the given value is known to have exactly one
+ /// bit set when defined. For vectors return true if every element is known to
+ /// be a power of two when defined. Supports values with integer or pointer
+ /// type and vectors of integers.
+ bool isPowerOfTwo(Value *V, const TargetData *TD = 0, unsigned Depth = 0);
+
+ /// isKnownNonZero - Return true if the given value is known to be non-zero
+ /// when defined. For vectors return true if every element is known to be
+ /// non-zero when defined. Supports values with integer or pointer type and
+ /// vectors of integers.
+ bool isKnownNonZero(Value *V, const TargetData *TD = 0, unsigned Depth = 0);
+
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
/// this predicate to simplify operations downstream. Mask is known to be
/// zero for bits that V cannot have.
@@ -77,7 +94,13 @@ namespace llvm {
///
bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0);
-
+ /// isBytewiseValue - If the specified value can be set by repeating the same
+ /// byte in memory, return the i8 value that it is represented with. This is
+ /// true for all i8 values obviously, but is also true for i32 0, i32 -1,
+ /// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated
+ /// byte store (e.g. i16 0x1234), return null.
+ Value *isBytewiseValue(Value *V);
+
/// FindInsertedValue - Given an aggregrate and an sequence of indices, see if
/// the scalar value indexed is already around as a register, for example if
/// it were inserted directly into the aggregrate.
@@ -97,6 +120,17 @@ namespace llvm {
return FindInsertedValue(V, &Idxs[0], &Idxs[1], InsertBefore);
}
+ /// GetPointerBaseWithConstantOffset - Analyze the specified pointer to see if
+ /// it can be expressed as a base pointer plus a constant offset. Return the
+ /// base and offset to the caller.
+ Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
+ const TargetData &TD);
+ static inline const Value *
+ GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset,
+ const TargetData &TD) {
+ return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
+ }
+
/// GetConstantStringInfo - This function computes the length of a
/// null-terminated C string pointed to by V. If successful, it returns true
/// and returns the string in Str. If unsuccessful, it returns false. If
@@ -110,6 +144,20 @@ namespace llvm {
/// GetStringLength - If we can compute the length of the string pointed to by
/// the specified pointer, return 'len+1'. If we can't, return 0.
uint64_t GetStringLength(Value *V);
+
+ /// GetUnderlyingObject - This method strips off any GEP address adjustments
+ /// and pointer casts from the specified value, returning the original object
+ /// being addressed. Note that the returned value has pointer type if the
+ /// specified value does. If the MaxLookup value is non-zero, it limits the
+ /// number of instructions to be stripped off.
+ Value *GetUnderlyingObject(Value *V, const TargetData *TD = 0,
+ unsigned MaxLookup = 6);
+ static inline const Value *
+ GetUnderlyingObject(const Value *V, const TargetData *TD = 0,
+ unsigned MaxLookup = 6) {
+ return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
+ }
+
} // end namespace llvm
#endif
diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h
index bf5874f682..7e7c9e7694 100644
--- a/include/llvm/BasicBlock.h
+++ b/include/llvm/BasicBlock.h
@@ -18,7 +18,7 @@
#include "llvm/SymbolTableListTraits.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -58,9 +58,9 @@ private:
/// tables. The type of a BasicBlock is "Type::LabelTy" because the basic block
/// represents a label to which a branch can jump.
///
-/// A well formed basic block is formed of a list of non-terminating
-/// instructions followed by a single TerminatorInst instruction.
-/// TerminatorInst's may not occur in the middle of basic blocks, and must
+/// A well formed basic block is formed of a list of non-terminating
+/// instructions followed by a single TerminatorInst instruction.
+/// TerminatorInst's may not occur in the middle of basic blocks, and must
/// terminate the blocks. The BasicBlock class allows malformed basic blocks to
/// occur because it may be useful in the intermediate stage of constructing or
/// modifying a program. However, the verifier will ensure that basic blocks
@@ -90,7 +90,7 @@ private:
public:
/// getContext - Get the context in which this basic block lives.
LLVMContext &getContext() const;
-
+
/// Instruction iterators...
typedef InstListType::iterator iterator;
typedef InstListType::const_iterator const_iterator;
@@ -98,7 +98,7 @@ public:
/// Create - Creates a new BasicBlock. If the Parent parameter is specified,
/// the basic block is automatically inserted at either the end of the
/// function (if InsertBefore is 0), or before the specified basic block.
- static BasicBlock *Create(LLVMContext &Context, const Twine &Name = "",
+ static BasicBlock *Create(LLVMContext &Context, const Twine &Name = "",
Function *Parent = 0,BasicBlock *InsertBefore = 0) {
return new BasicBlock(Context, Name, Parent, InsertBefore);
}
@@ -114,15 +114,15 @@ public:
/// and BlockAddress's).
User *use_back() { return cast<User>(*use_begin());}
const User *use_back() const { return cast<User>(*use_begin());}
-
+
/// getTerminator() - If this is a well formed basic block, then this returns
/// a pointer to the terminator instruction. If it is not, then you get a
/// null pointer back.
///
TerminatorInst *getTerminator();
const TerminatorInst *getTerminator() const;
-
- /// Returns a pointer to the first instructon in this block that is not a
+
+ /// Returns a pointer to the first instructon in this block that is not a
/// PHINode instruction. When adding instruction to the beginning of the
/// basic block, they should be added before the returned value, not before
/// the first instruction, which might be PHI.
@@ -137,7 +137,7 @@ public:
const Instruction* getFirstNonPHIOrDbg() const {
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg();
}
-
+
/// removeFromParent - This method unlinks 'this' from the containing
/// function, but does not delete it.
///
@@ -147,15 +147,15 @@ public:
/// and deletes it.
///
void eraseFromParent();
-
+
/// moveBefore - Unlink this basic block from its current function and
/// insert it into the function that MovePos lives in, right before MovePos.
void moveBefore(BasicBlock *MovePos);
-
+
/// moveAfter - Unlink this basic block from its current function and
/// insert it into the function that MovePos lives in, right after MovePos.
void moveAfter(BasicBlock *MovePos);
-
+
/// getSinglePredecessor - If this basic block has a single predecessor block,
/// return the block, otherwise return a null pointer.
@@ -166,8 +166,8 @@ public:
/// getUniquePredecessor - If this basic block has a unique predecessor block,
/// return the block, otherwise return a null pointer.
- /// Note that unique predecessor doesn't mean single edge, there can be
- /// multiple edges from the unique predecessor to this block (for example
+ /// Note that unique predecessor doesn't mean single edge, there can be
+ /// multiple edges from the unique predecessor to this block (for example
/// a switch statement with multiple cases having the same destination).
BasicBlock *getUniquePredecessor();
const BasicBlock *getUniquePredecessor() const {
@@ -247,7 +247,7 @@ public:
/// hasAddressTaken - returns true if there are any uses of this basic block
/// other than direct branches, switches, etc. to it.
bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; }
-
+
private:
/// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
/// objects using it. This is almost always 0, sometimes one, possibly but
diff --git a/include/llvm/Bitcode/Archive.h b/include/llvm/Bitcode/Archive.h
index 934e764b65..4abfa6e844 100644
--- a/include/llvm/Bitcode/Archive.h
+++ b/include/llvm/Bitcode/Archive.h
@@ -19,7 +19,7 @@
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <map>
#include <set>
@@ -82,7 +82,7 @@ class ArchiveMember : public ilist_node<ArchiveMember> {
unsigned getGroup() const { return info.getGroup(); }
/// The "mode" specifies the access permissions for the file per Unix
- /// security. This may not have any applicabiity on non-Unix systems but is
+ /// security. This may not have any applicability on non-Unix systems but is
/// a required component of the "ar" file format.
/// @brief Get the permission mode associated with this archive member.
unsigned getMode() const { return info.getMode(); }
@@ -144,7 +144,7 @@ class ArchiveMember : public ilist_node<ArchiveMember> {
/// allowed that doesn't have this restriction. This method determines if
/// that "long format" is used for this member.
/// @returns true iff the file name uses the long form
- /// @brief Determin if the member has a long file name
+ /// @brief Determine if the member has a long file name
bool hasLongFilename() const { return flags&HasLongFilenameFlag; }
/// This method returns the status info (like Unix stat(2)) for the archive
@@ -402,7 +402,7 @@ class Archive {
/// bitcode archive. It first makes sure the symbol table has been loaded
/// and has a non-zero size. If it does, then it is an archive. If not,
/// then it tries to load all the bitcode modules of the archive. Finally,
- /// it returns whether it was successfull.
+ /// it returns whether it was successful.
/// @returns true if the archive is a proper llvm bitcode archive
/// @brief Determine whether the archive is a proper llvm bitcode archive.
bool isBitcodeArchive();
diff --git a/include/llvm/Bitcode/BitCodes.h b/include/llvm/Bitcode/BitCodes.h
index ada2e65ee6..449dc35d7d 100644
--- a/include/llvm/Bitcode/BitCodes.h
+++ b/include/llvm/Bitcode/BitCodes.h
@@ -19,7 +19,7 @@
#define LLVM_BITCODE_BITCODES_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index d15c3ce93e..7692bd2872 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -199,10 +199,10 @@ namespace bitc {
OBO_NO_SIGNED_WRAP = 1
};
- /// SDivOperatorOptionalFlags - Flags for serializing SDivOperator's
- /// SubclassOptionalData contents.
- enum SDivOperatorOptionalFlags {
- SDIV_EXACT = 0
+ /// PossiblyExactOperatorOptionalFlags - Flags for serializing
+ /// PossiblyExactOperator's SubclassOptionalData contents.
+ enum PossiblyExactOperatorOptionalFlags {
+ PEO_EXACT = 0
};
// The function body block (FUNCTION_BLOCK_ID) describes function bodies. It
diff --git a/include/llvm/CMakeLists.txt b/include/llvm/CMakeLists.txt
index 5e4f40881d..0c3ca1cd0c 100644
--- a/include/llvm/CMakeLists.txt
+++ b/include/llvm/CMakeLists.txt
@@ -4,6 +4,7 @@ tablegen(Intrinsics.gen -gen-intrinsic)
add_custom_target(intrinsics_gen ALL
DEPENDS ${llvm_builded_incs_dir}/Intrinsics.gen)
+set_target_properties(intrinsics_gen PROPERTIES FOLDER "Tablegenning")
set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} intrinsics_gen PARENT_SCOPE)
@@ -16,4 +17,5 @@ if( MSVC_IDE OR XCODE )
# 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")
endif()
diff --git a/include/llvm/CallingConv.h b/include/llvm/CallingConv.h
index 2679cb7139..4c5ee62670 100644
--- a/include/llvm/CallingConv.h
+++ b/include/llvm/CallingConv.h
@@ -87,7 +87,14 @@ namespace CallingConv {
/// PTX_Device - Call to a PTX device function.
/// Passes all arguments in register or parameter space.
- PTX_Device = 72
+ PTX_Device = 72,
+
+ /// MBLAZE_INTR - Calling convention used for MBlaze interrupt routines.
+ MBLAZE_INTR = 73,
+
+ /// MBLAZE_INTR - Calling convention used for MBlaze interrupt support
+ /// routines (i.e. GCC's save_volatiles attribute).
+ MBLAZE_SVOL = 74
};
} // End CallingConv namespace
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h
index a8292ea649..78bf9fc11a 100644
--- a/include/llvm/CodeGen/Analysis.h
+++ b/include/llvm/CodeGen/Analysis.h
@@ -23,8 +23,10 @@
namespace llvm {
-class TargetLowering;
class GlobalVariable;
+class TargetLowering;
+class SDNode;
+class SelectionDAG;
/// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence
/// of insertvalue or extractvalue indices that identify a member, return
@@ -75,6 +77,9 @@ ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred);
bool isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr,
const TargetLowering &TLI);
+bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
+ const TargetLowering &TLI);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 7eef9567a0..a071febb10 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -17,7 +17,7 @@
#define LLVM_CODEGEN_ASMPRINTER_H
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class BlockAddress;
@@ -49,6 +49,7 @@ namespace llvm {
class MCSection;
class MCStreamer;
class MCSymbol;
+ class MDNode;
class DwarfDebug;
class DwarfException;
class Mangler;
@@ -388,7 +389,7 @@ namespace llvm {
/// frame.
void EmitFrameMoves(const std::vector<MachineMove> &Moves,
MCSymbol *BaseLabel, bool isEH) const;
-
+ void EmitCFIFrameMoves(const std::vector<MachineMove> &Moves) const;
//===------------------------------------------------------------------===//
// Inline Asm Support
@@ -432,7 +433,7 @@ namespace llvm {
mutable unsigned SetCounter;
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
- void EmitInlineAsm(StringRef Str, unsigned LocCookie) const;
+ void EmitInlineAsm(StringRef Str, const MDNode *LocMDNode = 0) const;
/// EmitInlineAsm - This method formats and emits the specified machine
/// instruction that is an inline asm.
@@ -444,7 +445,8 @@ namespace llvm {
/// EmitVisibility - This emits visibility information about symbol, if
/// this is suported by the target.
- void EmitVisibility(MCSymbol *Sym, unsigned Visibility) const;
+ void EmitVisibility(MCSymbol *Sym, unsigned Visibility,
+ bool IsDefinition = true) const;
void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const;
diff --git a/include/llvm/CodeGen/BinaryObject.h b/include/llvm/CodeGen/BinaryObject.h
index 3ade7c9e47..8c1431ffbe 100644
--- a/include/llvm/CodeGen/BinaryObject.h
+++ b/include/llvm/CodeGen/BinaryObject.h
@@ -16,7 +16,7 @@
#define LLVM_CODEGEN_BINARYOBJECT_H
#include "llvm/CodeGen/MachineRelocation.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
#include <vector>
diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h
index 24264d7f97..1f5f088be7 100644
--- a/include/llvm/CodeGen/CalcSpillWeights.h
+++ b/include/llvm/CodeGen/CalcSpillWeights.h
@@ -11,7 +11,7 @@
#ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H
#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
-#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/ADT/DenseMap.h"
namespace llvm {
@@ -20,6 +20,23 @@ namespace llvm {
class LiveIntervals;
class MachineLoopInfo;
+ /// normalizeSpillWeight - The spill weight of a live interval is computed as:
+ ///
+ /// (sum(use freq) + sum(def freq)) / (K + size)
+ ///
+ /// @param UseDefFreq Expected number of executed use and def instructions
+ /// per function call. Derived from block frequencies.
+ /// @param Size Size of live interval as returnexd by getSize()
+ ///
+ static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size) {
+ // The constant 25 instructions is added to avoid depending too much on
+ // accidental SlotIndex gaps for small intervals. The effect is that small
+ // intervals have a spill weight that is mostly proportional to the number
+ // of uses, while large intervals get a spill weight that is closer to a use
+ // density.
+ return UseDefFreq / (Size + 25*SlotIndex::InstrDist);
+ }
+
/// VirtRegAuxInfo - Calculate auxiliary information for a virtual
/// register such as its spill weight and allocation hint.
class VirtRegAuxInfo {
diff --git a/include/llvm/CodeGen/EdgeBundles.h b/include/llvm/CodeGen/EdgeBundles.h
new file mode 100644
index 0000000000..2c5215a792
--- /dev/null
+++ b/include/llvm/CodeGen/EdgeBundles.h
@@ -0,0 +1,61 @@
+//===-------- EdgeBundles.h - Bundles of CFG edges --------------*- c++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The EdgeBundles analysis forms equivalence classes of CFG edges such that all
+// edges leaving a machine basic block are in the same bundle, and all edges
+// leaving a basic block are in the same bundle.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_EDGEBUNDLES_H
+#define LLVM_CODEGEN_EDGEBUNDLES_H
+
+#include "llvm/ADT/IntEqClasses.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+
+class EdgeBundles : public MachineFunctionPass {
+ const MachineFunction *MF;
+
+ /// EC - Each edge bundle is an equivalence class. The keys are:
+ /// 2*BB->getNumber() -> Ingoing bundle.
+ /// 2*BB->getNumber()+1 -> Outgoing bundle.
+ IntEqClasses EC;
+
+public:
+ static char ID;
+ EdgeBundles() : MachineFunctionPass(ID) {}
+
+ /// getBundle - Return the ingoing (Out = false) or outgoing (Out = true)
+ /// bundle number for basic block #N
+ unsigned getBundle(unsigned N, bool Out) const { return EC[2 * N + Out]; }
+
+ /// getNumBundles - Return the total number of bundles in the CFG.
+ unsigned getNumBundles() const { return EC.getNumClasses(); }
+
+ /// getMachineFunction - Return the last machine function computed.
+ const MachineFunction *getMachineFunction() const { return MF; }
+
+ /// view - Visualize the annotated bipartite CFG with Graphviz.
+ void view() const;
+
+private:
+ virtual bool runOnMachineFunction(MachineFunction&);
+ virtual void getAnalysisUsage(AnalysisUsage&) const;
+};
+
+/// Specialize WriteGraph, the standard implementation won't work.
+raw_ostream &WriteGraph(raw_ostream &O, const EdgeBundles &G,
+ bool ShortNames = false,
+ const std::string &Title = "");
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h
index f17fe5a146..4421cc02d1 100644
--- a/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -19,6 +19,7 @@
#include "llvm/Instructions.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
#ifndef NDEBUG
#include "llvm/ADT/SmallSet.h"
@@ -27,6 +28,7 @@
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/Support/CallSite.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include <vector>
namespace llvm {
@@ -99,14 +101,16 @@ public:
#endif
struct LiveOutInfo {
- unsigned NumSignBits;
+ unsigned NumSignBits : 31;
+ bool IsValid : 1;
APInt KnownOne, KnownZero;
- LiveOutInfo() : NumSignBits(0), KnownOne(1, 0), KnownZero(1, 0) {}
+ LiveOutInfo() : NumSignBits(0), IsValid(true), KnownOne(1, 0),
+ KnownZero(1, 0) {}
};
-
- /// LiveOutRegInfo - Information about live out vregs, indexed by their
- /// register number offset by 'FirstVirtualRegister'.
- std::vector<LiveOutInfo> LiveOutRegInfo;
+
+ /// VisitedBBs - The set of basic blocks visited thus far by instruction
+ /// selection.
+ DenseSet<const BasicBlock*> VisitedBBs;
/// PHINodesToUpdate - A list of phi instructions whose operand list will
/// be updated after processing the current basic block.
@@ -142,12 +146,67 @@ public:
return R = CreateRegs(V->getType());
}
+ /// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the
+ /// register is a PHI destination and the PHI's LiveOutInfo is not valid.
+ const LiveOutInfo *GetLiveOutRegInfo(unsigned Reg) {
+ if (!LiveOutRegInfo.inBounds(Reg))
+ return NULL;
+
+ const LiveOutInfo *LOI = &LiveOutRegInfo[Reg];
+ if (!LOI->IsValid)
+ return NULL;
+
+ return LOI;
+ }
+
+ /// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the
+ /// register is a PHI destination and the PHI's LiveOutInfo is not valid. If
+ /// the register's LiveOutInfo is for a smaller bit width, it is extended to
+ /// the larger bit width by zero extension. The bit width must be no smaller
+ /// than the LiveOutInfo's existing bit width.
+ const LiveOutInfo *GetLiveOutRegInfo(unsigned Reg, unsigned BitWidth);
+
+ /// AddLiveOutRegInfo - Adds LiveOutInfo for a register.
+ void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits,
+ const APInt &KnownZero, const APInt &KnownOne) {
+ // Only install this information if it tells us something.
+ if (NumSignBits == 1 && KnownZero == 0 && KnownOne == 0)
+ return;
+
+ LiveOutRegInfo.grow(Reg);
+ LiveOutInfo &LOI = LiveOutRegInfo[Reg];
+ LOI.NumSignBits = NumSignBits;
+ LOI.KnownOne = KnownOne;
+ LOI.KnownZero = KnownZero;
+ }
+
+ /// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination
+ /// register based on the LiveOutInfo of its operands.
+ void ComputePHILiveOutRegInfo(const PHINode*);
+
+ /// InvalidatePHILiveOutRegInfo - Invalidates a PHI's LiveOutInfo, to be
+ /// called when a block is visited before all of its predecessors.
+ void InvalidatePHILiveOutRegInfo(const PHINode *PN) {
+ // PHIs with no uses have no ValueMap entry.
+ DenseMap<const Value*, unsigned>::const_iterator It = ValueMap.find(PN);
+ if (It == ValueMap.end())
+ return;
+
+ unsigned Reg = It->second;
+ LiveOutRegInfo.grow(Reg);
+ LiveOutRegInfo[Reg].IsValid = false;
+ }
+
/// setByValArgumentFrameIndex - Record frame index for the byval
/// argument.
void setByValArgumentFrameIndex(const Argument *A, int FI);
/// getByValArgumentFrameIndex - Get frame index for the byval argument.
int getByValArgumentFrameIndex(const Argument *A);
+
+private:
+ /// LiveOutRegInfo - Information about live out vregs.
+ IndexedMap<LiveOutInfo, VirtReg2IndexFunctor> LiveOutRegInfo;
};
/// AddCatchInfo - Extract the personality and type infos from an eh.selector
@@ -155,8 +214,9 @@ public:
void AddCatchInfo(const CallInst &I,
MachineModuleInfo *MMI, MachineBasicBlock *MBB);
-/// CopyCatchInfo - Copy catch information from DestBB to SrcBB.
-void CopyCatchInfo(const BasicBlock *SrcBB, const BasicBlock *DestBB,
+/// CopyCatchInfo - Copy catch information from SuccBB (or one of its
+/// successors) to LPad.
+void CopyCatchInfo(const BasicBlock *SuccBB, const BasicBlock *LPad,
MachineModuleInfo *MMI, FunctionLoweringInfo &FLI);
} // end namespace llvm
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index 31da0211eb..3da11c4a0e 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -269,16 +269,24 @@ namespace ISD {
/// lengths of the input vectors.
CONCAT_VECTORS,
+ /// INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector
+ /// with VECTOR2 inserted into VECTOR1 at the (potentially
+ /// variable) element number IDX, which must be a multiple of the
+ /// VECTOR2 vector length. The elements of VECTOR1 starting at
+ /// IDX are overwritten with VECTOR2. Elements IDX through
+ /// vector_length(VECTOR2) must be valid VECTOR1 indices.
+ INSERT_SUBVECTOR,
+
/// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an
- /// vector value) starting with the (potentially variable) element number
- /// IDX, which must be a multiple of the result vector length.
+ /// vector value) starting with the element number IDX, which must be a
+ /// constant multiple of the result vector length.
EXTRACT_SUBVECTOR,
- /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as
+ /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as
/// VEC1/VEC2. A VECTOR_SHUFFLE node also contains an array of constant int
/// values that indicate which value (or undef) each result element will
- /// get. These constant ints are accessible through the
- /// ShuffleVectorSDNode class. This is quite similar to the Altivec
+ /// get. These constant ints are accessible through the
+ /// ShuffleVectorSDNode class. This is quite similar to the Altivec
/// 'vperm' instruction, except that the indices must be constants and are
/// in terms of the element size of VEC1/VEC2, not in terms of bytes.
VECTOR_SHUFFLE,
@@ -295,13 +303,21 @@ namespace ISD {
// an unsigned/signed value of type i[2*N], then return the top part.
MULHU, MULHS,
- // Bitwise operators - logical and, logical or, logical xor, shift left,
- // shift right algebraic (shift in sign bits), shift right logical (shift in
- // zeroes), rotate left, rotate right, and byteswap.
- AND, OR, XOR, SHL, SRA, SRL, ROTL, ROTR, BSWAP,
+ /// Bitwise operators - logical and, logical or, logical xor.
+ AND, OR, XOR,
+
+ /// Shift and rotation operations. After legalization, the type of the
+ /// shift amount is known to be TLI.getShiftAmountTy(). Before legalization
+ /// the shift amount can be any type, but care must be taken to ensure it is
+ /// large enough. TLI.getShiftAmountTy() is i8 on some targets, but before
+ /// legalization, types like i1024 can occur and i8 doesn't have enough bits
+ /// to represent the shift amount. By convention, DAGCombine and
+ /// SelectionDAGBuilder forces these shift amounts to i32 for simplicity.
+ ///
+ SHL, SRA, SRL, ROTL, ROTR,
- // Counting operators
- CTTZ, CTLZ, CTPOP,
+ /// Byte Swap and Counting operators.
+ BSWAP, CTTZ, CTLZ, CTPOP,
// Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not
// i1 then the high bits must conform to getBooleanContents.
@@ -399,14 +415,14 @@ namespace ISD {
/// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
FP_EXTEND,
- // BIT_CONVERT - This operator converts between integer, vector and FP
+ // BITCAST - This operator converts between integer, vector and FP
// values, as if the value was stored to memory with one type and loaded
// from the same address with the other type (or equivalently for vector
// format conversions, etc). The source and result are required to have
// the same bit size (e.g. f32 <-> i32). This can also be used for
// int-to-int or fp-to-fp conversions, but that is a noop, deleted by
// getNode().
- BIT_CONVERT,
+ BITCAST,
// CONVERT_RNDSAT - This operator is used to support various conversions
// between various types (float, signed, unsigned and vectors of those
@@ -482,6 +498,7 @@ namespace ISD {
// Operand #0 : Input chain.
// Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
// Operand #2 : a MDNodeSDNode with the !srcloc metadata.
+ // Operand #3 : HasSideEffect, IsAlignStack bits.
// After this, it is followed by a list of operands with this format:
// ConstantSDNode: Flags that encode whether it is a mem or not, the
// of operands that follow, etc. See InlineAsm.h.
@@ -532,7 +549,7 @@ namespace ISD {
// SRCVALUE - This is a node type that holds a Value* that is used to
// make reference to a value in the LLVM IR.
SRCVALUE,
-
+
// MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to
// reference metadata in the IR.
MDNODE_SDNODE,
diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h
index eefbc45cb2..767b666225 100644
--- a/include/llvm/CodeGen/IntrinsicLowering.h
+++ b/include/llvm/CodeGen/IntrinsicLowering.h
@@ -48,6 +48,11 @@ namespace llvm {
/// be capable of handling this kind of change.
///
void LowerIntrinsicCall(CallInst *CI);
+
+ /// LowerToByteSwap - Replace a call instruction into a call to bswap
+ /// intrinsic. Return false if it has determined the call is not a
+ /// simple integer bswap.
+ static bool LowerToByteSwap(CallInst *CI);
};
}
diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h
index eb373fb145..fea8523051 100644
--- a/include/llvm/CodeGen/JITCodeEmitter.h
+++ b/include/llvm/CodeGen/JITCodeEmitter.h
@@ -18,7 +18,7 @@
#define LLVM_CODEGEN_JITCODEEMITTER_H
#include <string>
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/ADT/DenseMap.h"
diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h
index 13cebeaf42..1ed2547ca6 100644
--- a/include/llvm/CodeGen/LatencyPriorityQueue.h
+++ b/include/llvm/CodeGen/LatencyPriorityQueue.h
@@ -20,25 +20,25 @@
namespace llvm {
class LatencyPriorityQueue;
-
+
/// Sorting functions for the Available queue.
struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> {
LatencyPriorityQueue *PQ;
explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {}
-
+
bool operator()(const SUnit* left, const SUnit* right) const;
};
class LatencyPriorityQueue : public SchedulingPriorityQueue {
// SUnits - The SUnits for the current graph.
std::vector<SUnit> *SUnits;
-
+
/// NumNodesSolelyBlocking - This vector contains, for every node in the
/// Queue, the number of nodes that the node is the sole unscheduled
/// predecessor for. This is used as a tie-breaker heuristic for better
/// mobility.
std::vector<unsigned> NumNodesSolelyBlocking;
-
+
/// Queue - The queue.
std::vector<SUnit*> Queue;
latency_sort Picker;
@@ -47,6 +47,8 @@ namespace llvm {
LatencyPriorityQueue() : Picker(this) {
}
+ bool isBottomUp() const { return false; }
+
void initNodes(std::vector<SUnit> &sunits) {
SUnits = &sunits;
NumNodesSolelyBlocking.resize(SUnits->size(), 0);
@@ -62,25 +64,27 @@ namespace llvm {
void releaseState() {
SUnits = 0;
}
-
+
unsigned getLatency(unsigned NodeNum) const {
assert(NodeNum < (*SUnits).size());
return (*SUnits)[NodeNum].getHeight();
}
-
+
unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
assert(NodeNum < NumNodesSolelyBlocking.size());
return NumNodesSolelyBlocking[NodeNum];
}
-
+
bool empty() const { return Queue.empty(); }
-
+
virtual void push(SUnit *U);
-
+
virtual SUnit *pop();
virtual void remove(SUnit *SU);
+ virtual void dump(ScheduleDAG* DAG) const;
+
// ScheduledNode - As nodes are scheduled, we look to see if there are any
// successor nodes that have a single unscheduled predecessor. If so, that
// single predecessor has a higher priority, since scheduling it will make
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
index bc06d43b8f..c931261f63 100644
--- a/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -36,6 +36,7 @@ namespace {
(void) llvm::createFastRegisterAllocator();
(void) llvm::createBasicRegisterAllocator();
(void) llvm::createLinearScanRegisterAllocator();
+ (void) llvm::createGreedyRegisterAllocator();
(void) llvm::createDefaultPBQPRegisterAllocator();
(void) llvm::createSimpleRegisterCoalescer();
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index c21df28cdd..427af87960 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -21,7 +21,7 @@
#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
#define LLVM_CODEGEN_LIVEINTERVAL_H
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/IntEqClasses.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/CodeGen/SlotIndexes.h"
@@ -205,8 +205,7 @@ namespace llvm {
typedef SmallVector<LiveRange,4> Ranges;
typedef SmallVector<VNInfo*,4> VNInfoList;
- unsigned reg; // the register or stack slot of this interval
- // if the top bits is set, it represents a stack slot.
+ const unsigned reg; // the register or stack slot of this interval.
float weight; // weight of this interval
Ranges ranges; // the ranges in which this register is live
VNInfoList valnos; // value#'s
@@ -222,11 +221,8 @@ namespace llvm {
};
- LiveInterval(unsigned Reg, float Weight, bool IsSS = false)
- : reg(Reg), weight(Weight) {
- if (IsSS)
- reg = reg | (1U << (sizeof(unsigned)*CHAR_BIT-1));
- }
+ LiveInterval(unsigned Reg, float Weight)
+ : reg(Reg), weight(Weight) {}
typedef Ranges::iterator iterator;
iterator begin() { return ranges.begin(); }
@@ -250,6 +246,7 @@ namespace llvm {
/// position is in a hole, this method returns an iterator pointing to the
/// LiveRange immediately after the hole.
iterator advanceTo(iterator I, SlotIndex Pos) {
+ assert(I != end());
if (Pos >= endIndex())
return end();
while (I->end <= Pos) ++I;
@@ -274,19 +271,6 @@ namespace llvm {
ranges.clear();
}
- /// isStackSlot - Return true if this is a stack slot interval.
- ///
- bool isStackSlot() const {
- return reg & (1U << (sizeof(unsigned)*CHAR_BIT-1));
- }
-
- /// getStackSlotIndex - Return stack slot index if this is a stack slot
- /// interval.
- int getStackSlotIndex() const {
- assert(isStackSlot() && "Interval is not a stack slot interval!");
- return reg & ~(1U << (sizeof(unsigned)*CHAR_BIT-1));
- }
-
bool hasAtLeastOneValue() const { return !valnos.empty(); }
bool containsOneValue() const { return valnos.size() == 1; }
@@ -463,6 +447,11 @@ namespace llvm {
addRangeFrom(LR, ranges.begin());
}
+ /// extendInBlock - If this interval is live before UseIdx in the basic
+ /// block that starts at StartIdx, extend it to be live at UseIdx and return
+ /// the value. If there is no live range before UseIdx, return NULL.
+ VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex UseIdx);
+
/// join - Join two live intervals (this, and other) together. This applies
/// mappings to the value numbers in the LHS/RHS intervals as specified. If
/// the intervals are not joinable, this aborts.
@@ -560,11 +549,7 @@ namespace llvm {
class ConnectedVNInfoEqClasses {
LiveIntervals &lis_;
-
- // Map each value number to its equivalence class.
- // The invariant is that EqClass[x] <= x.
- // Two values are connected iff EqClass[x] == EqClass[b].
- SmallVector<unsigned, 8> eqClass_;
+ IntEqClasses eqClass_;
// Note that values a and b are connected.
void Connect(unsigned a, unsigned b);
@@ -580,7 +565,7 @@ namespace llvm {
/// getEqClass - Classify creates equivalence classes numbered 0..N. Return
/// the equivalence class assigned the VNI.
- unsigned getEqClass(const VNInfo *VNI) { return eqClass_[VNI->id]; }
+ unsigned getEqClass(const VNInfo *VNI) const { return eqClass_[VNI->id]; }
/// Distribute - Distribute values in LIV[0] into a separate LiveInterval
/// for each connected component. LIV must have a LiveInterval for each
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index 143a1a6836..b09f8d1110 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -75,14 +75,6 @@ namespace llvm {
// Calculate the spill weight to assign to a single instruction.
static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);
- // After summing the spill weights of all defs and uses, the final weight
- // should be normalized, dividing the weight of the interval by its size.
- // This encourages spilling of intervals that are large and have few uses,
- // and discourages spilling of small intervals with many uses.
- void normalizeSpillWeight(LiveInterval &li) {
- li.weight /= getApproximateInstructionCount(li) + 25;
- }
-
typedef Reg2IntervalMap::iterator iterator;
typedef Reg2IntervalMap::const_iterator const_iterator;
const_iterator begin() const { return r2iMap_.begin(); }
@@ -163,6 +155,12 @@ namespace llvm {
LiveRange addLiveRangeToEndOfBlock(unsigned reg,
MachineInstr* startInst);
+ /// shrinkToUses - After removing some uses of a register, shrink its live
+ /// range to just the remaining uses. This method does not compute reaching
+ /// defs for new uses, and it doesn't remove dead defs.
+ /// Dead PHIDef values are marked as unused.
+ void shrinkToUses(LiveInterval *li);
+
// Interval removal
void removeInterval(unsigned Reg) {
@@ -171,6 +169,10 @@ namespace llvm {
r2iMap_.erase(I);
}
+ SlotIndexes *getSlotIndexes() const {
+ return indexes_;
+ }
+
SlotIndex getZeroIndex() const {
return indexes_->getZeroIndex();
}
@@ -304,6 +306,16 @@ namespace llvm {
/// within a single basic block.
bool intervalIsInOneMBB(const LiveInterval &li) const;
+ /// getLastSplitPoint - Return the last possible insertion point in mbb for
+ /// spilling and splitting code. This is the first terminator, or the call
+ /// instruction if li is live into a landing pad successor.
+ MachineBasicBlock::iterator getLastSplitPoint(const LiveInterval &li,
+ MachineBasicBlock *mbb) const;
+
+ /// addKillFlags - Add kill flags to any instruction that kills a virtual
+ /// register.
+ void addKillFlags();
+
private:
/// computeIntervals - Compute live intervals.
void computeIntervals();
@@ -441,9 +453,6 @@ namespace llvm {
DenseMap<unsigned,unsigned> &MBBVRegsMap,
std::vector<LiveInterval*> &NewLIs);
- // Normalize the spill weight of all the intervals in NewLIs.
- void normalizeSpillWeights(std::vector<LiveInterval*> &NewLIs);
-
static LiveInterval* createInterval(unsigned Reg);
void printInstrs(raw_ostream &O) const;
diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h
index 9310a30a4d..8a8dcaf572 100644
--- a/include/llvm/CodeGen/LiveStackAnalysis.h
+++ b/include/llvm/CodeGen/LiveStackAnalysis.h
@@ -52,19 +52,7 @@ namespace llvm {
unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
- LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC) {
- assert(Slot >= 0 && "Spill slot indice must be >= 0");
- SS2IntervalMap::iterator I = S2IMap.find(Slot);
- if (I == S2IMap.end()) {
- I = S2IMap.insert(I,std::make_pair(Slot, LiveInterval(Slot,0.0F,true)));
- S2RCMap.insert(std::make_pair(Slot, RC));
- } else {
- // Use the largest common subclass register class.
- const TargetRegisterClass *OldRC = S2RCMap[Slot];
- S2RCMap[Slot] = getCommonSubClass(OldRC, RC);
- }
- return I->second;
- }
+ LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC);
LiveInterval &getInterval(int Slot) {
assert(Slot >= 0 && "Spill slot indice must be >= 0");
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h
index ea32efaf0c..f9b81b1ea7 100644
--- a/include/llvm/CodeGen/LiveVariables.h
+++ b/include/llvm/CodeGen/LiveVariables.h
@@ -32,8 +32,10 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseBitVector.h"
@@ -121,10 +123,9 @@ public:
private:
/// VirtRegInfo - This list is a mapping from virtual register number to
- /// variable information. FirstVirtualRegister is subtracted from the virtual
- /// register number before indexing into this list.
+ /// variable information.
///
- std::vector<VarInfo> VirtRegInfo;
+ IndexedMap<VarInfo, VirtReg2IndexFunctor> VirtRegInfo;
/// PHIJoins - list of virtual registers that are PHI joins. These registers
/// may have multiple definitions, and they require special handling when
diff --git a/include/llvm/CodeGen/MachORelocation.h b/include/llvm/CodeGen/MachORelocation.h
index 27306c62d8..21fe74f8e1 100644
--- a/include/llvm/CodeGen/MachORelocation.h
+++ b/include/llvm/CodeGen/MachORelocation.h
@@ -15,7 +15,7 @@
#ifndef LLVM_CODEGEN_MACHO_RELOCATION_H
#define LLVM_CODEGEN_MACHO_RELOCATION_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 49daf5f4d3..1906093388 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -16,6 +16,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ADT/GraphTraits.h"
+#include <functional>
namespace llvm {
@@ -224,6 +225,10 @@ public:
/// this basic block is entered via an exception handler.
void setIsLandingPad() { IsLandingPad = true; }
+ /// getLandingPadSuccessor - If this block has a successor that is a landing
+ /// pad, return it. Otherwise return NULL.
+ const MachineBasicBlock *getLandingPadSuccessor() const;
+
// Code Layout methods.
/// moveBefore/moveAfter - move 'this' block before or after the specified
@@ -300,6 +305,10 @@ public:
/// it returns end()
iterator getFirstTerminator();
+ /// getLastNonDebugInstr - returns an iterator to the last non-debug
+ /// instruction in the basic block, or end()
+ iterator getLastNonDebugInstr();
+
/// SplitCriticalEdge - Split the critical edge from this block to the
/// given successor block, and return the newly created block, or null
/// if splitting is not possible.
@@ -403,6 +412,14 @@ raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB);
void WriteAsOperand(raw_ostream &, const MachineBasicBlock*, bool t);
+// This is useful when building IndexedMaps keyed on basic block pointers.
+struct MBB2NumberFunctor :
+ public std::unary_function<const MachineBasicBlock*, unsigned> {
+ unsigned operator()(const MachineBasicBlock *MBB) const {
+ return MBB->getNumber();
+ }
+};
+
//===--------------------------------------------------------------------===//
// GraphTraits specializations for machine basic block graphs (machine-CFGs)
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h
index 7abb49a219..8fc80adf7f 100644
--- a/include/llvm/CodeGen/MachineCodeEmitter.h
+++ b/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -17,7 +17,7 @@
#ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H
#define LLVM_CODEGEN_MACHINECODEEMITTER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/DebugLoc.h"
namespace llvm {
diff --git a/include/llvm/CodeGen/MachineCodeInfo.h b/include/llvm/CodeGen/MachineCodeInfo.h
index a75c02a052..c5c0c44504 100644
--- a/include/llvm/CodeGen/MachineCodeInfo.h
+++ b/include/llvm/CodeGen/MachineCodeInfo.h
@@ -17,7 +17,7 @@
#ifndef EE_MACHINE_CODE_INFO_H
#define EE_MACHINE_CODE_INFO_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h
index 498f815b9b..5727321a0d 100644
--- a/include/llvm/CodeGen/MachineConstantPool.h
+++ b/include/llvm/CodeGen/MachineConstantPool.h
@@ -16,6 +16,7 @@
#ifndef LLVM_CODEGEN_MACHINECONSTANTPOOL_H
#define LLVM_CODEGEN_MACHINECONSTANTPOOL_H
+#include "llvm/ADT/DenseSet.h"
#include <cassert>
#include <climits>
#include <vector>
@@ -130,6 +131,8 @@ class MachineConstantPool {
const TargetData *TD; ///< The machine's TargetData.
unsigned PoolAlignment; ///< The alignment for the pool.
std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
+ /// MachineConstantPoolValues that use an existing MachineConstantPoolEntry.
+ DenseSet<MachineConstantPoolValue*> MachineCPVsSharingEntries;
public:
/// @brief The only constructor.
explicit MachineConstantPool(const TargetData *td)
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index dca65ef6d4..22a82a9d6e 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -16,7 +16,7 @@
#include "llvm/ADT/SmallVector.h"
//#include "llvm/ADT/IndexedMap.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <vector>
@@ -27,7 +27,7 @@ class TargetRegisterClass;
class Type;
class MachineFunction;
class MachineBasicBlock;
-class TargetFrameInfo;
+class TargetFrameLowering;
class BitVector;
/// The CalleeSavedInfo class tracks the information need to locate where a
@@ -192,13 +192,9 @@ class MachineFrameInfo {
/// CSIValid - Has CSInfo been set yet?
bool CSIValid;
- /// SpillObjects - A vector indicating which frame indices refer to
- /// spill slots.
- SmallVector<bool, 8> SpillObjects;
-
- /// TargetFrameInfo - Target information about frame layout.
+ /// TargetFrameLowering - Target information about frame layout.
///
- const TargetFrameInfo &TFI;
+ const TargetFrameLowering &TFI;
/// LocalFrameObjects - References to frame indices which are mapped
/// into the local frame allocation block. <FrameIdx, LocalOffset>
@@ -217,7 +213,7 @@ class MachineFrameInfo {
bool UseLocalStackAllocationBlock;
public:
- explicit MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) {
+ explicit MachineFrameInfo(const TargetFrameLowering &tfi) : TFI(tfi) {
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
HasVarSizedObjects = false;
FrameAddressTaken = false;
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index eeba1bbddf..f56c053e47 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -271,7 +271,7 @@ public:
/// verify - Run the current MachineFunction through the machine code
/// verifier, useful for debugger use.
- void verify(Pass *p=NULL) const;
+ void verify(Pass *p = NULL, const char *Banner = NULL) const;
// Provide accessors for the MachineBasicBlock list...
typedef BasicBlockListType::iterator iterator;
diff --git a/include/llvm/CodeGen/MachineFunctionAnalysis.h b/include/llvm/CodeGen/MachineFunctionAnalysis.h
index 75dbaab973..50676ad4ad 100644
--- a/include/llvm/CodeGen/MachineFunctionAnalysis.h
+++ b/include/llvm/CodeGen/MachineFunctionAnalysis.h
@@ -37,6 +37,10 @@ public:
MachineFunction &getMF() const { return *MF; }
CodeGenOpt::Level getOptLevel() const { return OptLevel; }
+
+ virtual const char* getPassName() const {
+ return "Machine Function Analysis";
+ }
private:
virtual bool doInitialization(Module &M);
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index d1f17d39db..0f69a7789c 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -50,13 +50,22 @@ public:
enum CommentFlag {
ReloadReuse = 0x1
};
-
+
+ enum MIFlag {
+ NoFlags = 0,
+ FrameSetup = 1 << 0 // Instruction is used as a part of
+ // function frame setup code.
+ };
private:
const TargetInstrDesc *TID; // Instruction descriptor.
- unsigned short NumImplicitOps; // Number of implicit operands (which
+ uint16_t NumImplicitOps; // Number of implicit operands (which
// are determined at construction time).
- unsigned short AsmPrinterFlags; // Various bits of information used by
+ uint8_t Flags; // Various bits of additional
+ // information about machine
+ // instruction.
+
+ uint8_t AsmPrinterFlags; // Various bits of information used by
// the AsmPrinter to emit helpful
// comments. This is *not* semantic
// information. Do not use this for
@@ -125,8 +134,12 @@ public:
/// getAsmPrinterFlags - Return the asm printer flags bitvector.
///
- unsigned short getAsmPrinterFlags() const { return AsmPrinterFlags; }
+ uint8_t getAsmPrinterFlags() const { return AsmPrinterFlags; }
+ /// clearAsmPrinterFlags - clear the AsmPrinter bitvector
+ ///
+ void clearAsmPrinterFlags() { AsmPrinterFlags = 0; }
+
/// getAsmPrinterFlag - Return whether an AsmPrinter flag is set.
///
bool getAsmPrinterFlag(CommentFlag Flag) const {
@@ -136,13 +149,38 @@ public:
/// setAsmPrinterFlag - Set a flag for the AsmPrinter.
///
void setAsmPrinterFlag(CommentFlag Flag) {
- AsmPrinterFlags |= (unsigned short)Flag;
+ AsmPrinterFlags |= (uint8_t)Flag;
+ }
+
+ /// getFlags - Return the MI flags bitvector.
+ uint8_t getFlags() const {
+ return Flags;
+ }
+
+ /// getFlag - Return whether an MI flag is set.
+ bool getFlag(MIFlag Flag) const {
+ return Flags & Flag;
+ }
+
+ /// setFlag - Set a MI flag.
+ void setFlag(MIFlag Flag) {
+ Flags |= (uint8_t)Flag;
+ }
+
+ void setFlags(unsigned flags) {
+ Flags = flags;
+ }
+
+ /// clearAsmPrinterFlag - clear specific AsmPrinter flags
+ ///
+ void clearAsmPrinterFlag(CommentFlag Flag) {
+ AsmPrinterFlags &= ~Flag;
}
/// getDebugLoc - Returns the debug location id of this MachineInstr.
///
DebugLoc getDebugLoc() const { return debugLoc; }
-
+
/// getDesc - Returns the target instruction descriptor of this
/// MachineInstr.
const TargetInstrDesc &getDesc() const { return *TID; }
@@ -227,6 +265,7 @@ public:
bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
+ bool isStackAligningInlineAsm() const;
bool isInsertSubreg() const {
return getOpcode() == TargetOpcode::INSERT_SUBREG;
}
@@ -422,6 +461,15 @@ public:
/// return 0.
unsigned isConstantValuePHI() const;
+ /// hasUnmodeledSideEffects - Return true if this instruction has side
+ /// effects that are not modeled by mayLoad / mayStore, etc.
+ /// For all instructions, the property is encoded in TargetInstrDesc::Flags
+ /// (see TargetInstrDesc::hasUnmodeledSideEffects(). The only exception is
+ /// INLINEASM instruction, in which case the side effect property is encoded
+ /// in one of its operands (see InlineAsm::Extra_HasSideEffect).
+ ///
+ bool hasUnmodeledSideEffects() const;
+
/// allDefsAreDead - Return true if all the defs of this instruction are dead.
///
bool allDefsAreDead() const;
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index 1eb9735308..f04dee2b4b 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -145,6 +145,16 @@ public:
return *this;
}
+ const MachineInstrBuilder &setMIFlags(unsigned Flags) const {
+ MI->setFlags(Flags);
+ return *this;
+ }
+
+ const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const {
+ MI->setFlag(Flag);
+ return *this;
+ }
+
// Add a displacement from an existing MachineOperand with an added offset.
const MachineInstrBuilder &addDisp(const MachineOperand &Disp,
int64_t off) const {
diff --git a/include/llvm/CodeGen/MachineLocation.h b/include/llvm/CodeGen/MachineLocation.h
index a1fcb9fe75..21951b6680 100644
--- a/include/llvm/CodeGen/MachineLocation.h
+++ b/include/llvm/CodeGen/MachineLocation.h
@@ -32,7 +32,7 @@ private:
public:
enum {
// The target register number for an abstract frame pointer. The value is
- // an arbitrary value greater than TargetRegisterInfo::FirstVirtualRegister.
+ // an arbitrary value that doesn't collide with any real target register.
VirtualFP = ~0U
};
MachineLocation()
@@ -41,6 +41,11 @@ public:
: IsRegister(true), Register(R), Offset(0) {}
MachineLocation(unsigned R, int O)
: IsRegister(false), Register(R), Offset(O) {}
+
+ bool operator==(const MachineLocation &Other) const {
+ return IsRegister == Other.IsRegister && Register == Other.Register &&
+ Offset == Other.Offset;
+ }
// Accessors
bool isReg() const { return IsRegister; }
diff --git a/include/llvm/CodeGen/MachineLoopRanges.h b/include/llvm/CodeGen/MachineLoopRanges.h
new file mode 100644
index 0000000000..6a30e8b53c
--- /dev/null
+++ b/include/llvm/CodeGen/MachineLoopRanges.h
@@ -0,0 +1,112 @@
+//===- MachineLoopRanges.h - Ranges of machine loops -----------*- c++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the interface to the MachineLoopRanges analysis.
+//
+// Provide on-demand information about the ranges of machine instructions
+// covered by a loop.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINELOOPRANGES_H
+#define LLVM_CODEGEN_MACHINELOOPRANGES_H
+
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+
+namespace llvm {
+
+class MachineLoop;
+class MachineLoopInfo;
+class raw_ostream;
+
+/// MachineLoopRange - Range information for a single loop.
+class MachineLoopRange {
+ friend class MachineLoopRanges;
+
+public:
+ typedef IntervalMap<SlotIndex, unsigned, 4> Map;
+ typedef Map::Allocator Allocator;
+
+private:
+ /// The mapped loop.
+ const MachineLoop *const Loop;
+
+ /// Map intervals to a bit mask.
+ /// Bit 0 = inside loop block.
+ Map Intervals;
+
+ /// Loop area as measured by SlotIndex::distance.
+ unsigned Area;
+
+ /// Create a MachineLoopRange, only accessible to MachineLoopRanges.
+ MachineLoopRange(const MachineLoop*, Allocator&, SlotIndexes&);
+
+public:
+ /// getLoop - Return the mapped machine loop.
+ const MachineLoop *getLoop() const { return Loop; }
+
+ /// overlaps - Return true if this loop overlaps the given range of machine
+ /// inteructions.
+ bool overlaps(SlotIndex Start, SlotIndex Stop);
+
+ /// getNumber - Return the loop number. This is the same as the number of the
+ /// header block.
+ unsigned getNumber() const;
+
+ /// getArea - Return the loop area. This number is approximately proportional
+ /// to the number of instructions in the loop.
+ unsigned getArea() const { return Area; }
+
+ /// getMap - Allow public read-only access for IntervalMapOverlaps.
+ const Map &getMap() { return Intervals; }
+
+ /// print - Print loop ranges on OS.
+ void print(raw_ostream&) const;
+
+ /// byNumber - Comparator for array_pod_sort that sorts a list of
+ /// MachineLoopRange pointers by number.
+ static int byNumber(const void*, const void*);
+
+ /// byAreaDesc - Comparator for array_pod_sort that sorts a list of
+ /// MachineLoopRange pointers by descending area, then by number.
+ static int byAreaDesc(const void*, const void*);
+};
+
+raw_ostream &operator<<(raw_ostream&, const MachineLoopRange&);
+
+/// MachineLoopRanges - Analysis pass that provides on-demand per-loop range
+/// information.
+class MachineLoopRanges : public MachineFunctionPass {
+ typedef DenseMap<const MachineLoop*, MachineLoopRange*> CacheMap;
+ typedef MachineLoopRange::Allocator MapAllocator;
+
+ MapAllocator Allocator;
+ SlotIndexes *Indexes;
+ CacheMap Cache;
+
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ MachineLoopRanges() : MachineFunctionPass(ID), Indexes(0) {}
+ ~MachineLoopRanges() { releaseMemory(); }
+
+ /// getLoopRange - Return the range of loop.
+ MachineLoopRange *getLoopRange(const MachineLoop *Loop);
+
+private:
+ virtual bool runOnMachineFunction(MachineFunction&);
+ virtual void releaseMemory();
+ virtual void getAnalysisUsage(AnalysisUsage&) const;
+};
+
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_MACHINELOOPRANGES_H
diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h
index cabd129353..768ce47f8b 100644
--- a/include/llvm/CodeGen/MachineMemOperand.h
+++ b/include/llvm/CodeGen/MachineMemOperand.h
@@ -16,7 +16,7 @@
#ifndef LLVM_CODEGEN_MACHINEMEMOPERAND_H
#define LLVM_CODEGEN_MACHINEMEMOPERAND_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index 43405c0937..6bc80b099f 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -39,7 +39,7 @@
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/ValueHandle.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -170,7 +170,8 @@ public:
VariableDbgInfoMapTy VariableDbgInfo;
MachineModuleInfo(); // DUMMY CONSTRUCTOR, DO NOT CALL.
- MachineModuleInfo(const MCAsmInfo &MAI); // Real constructor.
+ // Real constructor.
+ MachineModuleInfo(const MCAsmInfo &MAI, const TargetAsmInfo *TAI);
~MachineModuleInfo();
bool doInitialization();
@@ -208,7 +209,7 @@ public:
/// hasDebugInfo - Returns true if valid debug info is present.
///
bool hasDebugInfo() const { return DbgInfoAvailable; }
- void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = true; }
+ void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; }
bool callsEHReturn() const { return CallsEHReturn; }
void setCallsEHReturn(bool b) { CallsEHReturn = b; }
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index aaf6a2fe4f..8acc9490d8 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CODEGEN_MACHINEOPERAND_H
#define LLVM_CODEGEN_MACHINEOPERAND_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
@@ -153,6 +153,16 @@ public:
MachineInstr *getParent() { return ParentMI; }
const MachineInstr *getParent() const { return ParentMI; }
+ /// clearParent - Reset the parent pointer.
+ ///
+ /// The MachineOperand copy constructor also copies ParentMI, expecting the
+ /// original to be deleted. If a MachineOperand is ever stored outside a
+ /// MachineInstr, the parent pointer must be cleared.
+ ///
+ /// Never call clearParent() on an operand in a MachineInstr.
+ ///
+ void clearParent() { ParentMI = 0; }
+
void print(raw_ostream &os, const TargetMachine *TM = 0) const;
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index ddba61bf18..74df8da20e 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -16,6 +16,7 @@
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/IndexedMap.h"
#include <vector>
namespace llvm {
@@ -24,13 +25,12 @@ namespace llvm {
/// registers, including vreg register classes, use/def chains for registers,
/// etc.
class MachineRegisterInfo {
- /// VRegInfo - Information we keep for each virtual register. The entries in
- /// this vector are actually converted to vreg numbers by adding the
- /// TargetRegisterInfo::FirstVirtualRegister delta to their index.
+ /// VRegInfo - Information we keep for each virtual register.
///
/// Each element in this list contains the register class of the vreg and the
/// start of the use/def list for the register.
- std::vector<std::pair<const TargetRegisterClass*, MachineOperand*> > VRegInfo;
+ IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>,
+ VirtReg2IndexFunctor> VRegInfo;
/// RegClassVRegMap - This vector acts as a map from TargetRegisterClass to
/// virtual registers. For each target register class, it keeps a list of
@@ -44,7 +44,7 @@ class MachineRegisterInfo {
/// register for allocation. For example, if the hint is <0, 1024>, it means
/// the allocator should prefer the physical register allocated to the virtual
/// register of the hint.
- std::vector<std::pair<unsigned, unsigned> > RegAllocHints;
+ IndexedMap<std::pair<unsigned, unsigned>, VirtReg2IndexFunctor> RegAllocHints;
/// PhysRegUseDefLists - This is an array of the head of the use/def list for
/// physical registers.
@@ -159,17 +159,15 @@ public:
/// getRegUseDefListHead - Return the head pointer for the register use/def
/// list for the specified virtual or physical register.
MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
- if (RegNo < TargetRegisterInfo::FirstVirtualRegister)
- return PhysRegUseDefLists[RegNo];
- RegNo -= TargetRegisterInfo::FirstVirtualRegister;
- return VRegInfo[RegNo].second;
+ if (TargetRegisterInfo::isVirtualRegister(RegNo))
+ return VRegInfo[RegNo].second;
+ return PhysRegUseDefLists[RegNo];
}
MachineOperand *getRegUseDefListHead(unsigned RegNo) const {
- if (RegNo < TargetRegisterInfo::FirstVirtualRegister)
- return PhysRegUseDefLists[RegNo];
- RegNo -= TargetRegisterInfo::FirstVirtualRegister;
- return VRegInfo[RegNo].second;
+ if (TargetRegisterInfo::isVirtualRegister(RegNo))
+ return VRegInfo[RegNo].second;
+ return PhysRegUseDefLists[RegNo];
}
/// getVRegDef - Return the machine instr that defines the specified virtual
@@ -194,8 +192,6 @@ public:
/// getRegClass - Return the register class of the specified virtual register.
///
const TargetRegisterClass *getRegClass(unsigned Reg) const {
- Reg -= TargetRegisterInfo::FirstVirtualRegister;
- assert(Reg < VRegInfo.size() && "Invalid vreg!");
return VRegInfo[Reg].first;
}
@@ -216,11 +212,9 @@ public:
///
unsigned createVirtualRegister(const TargetRegisterClass *RegClass);
- /// getLastVirtReg - Return the highest currently assigned virtual register.
+ /// getNumVirtRegs - Return the number of virtual registers created.
///
- unsigned getLastVirtReg() const {
- return (unsigned)VRegInfo.size()+TargetRegisterInfo::FirstVirtualRegister-1;
- }
+ unsigned getNumVirtRegs() const { return VRegInfo.size(); }
/// getRegClassVirtRegs - Return the list of virtual registers of the given
/// target register class.
@@ -232,8 +226,6 @@ public:
/// setRegAllocationHint - Specify a register allocation hint for the
/// specified virtual register.
void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) {
- Reg -= TargetRegisterInfo::FirstVirtualRegister;
- assert(Reg < VRegInfo.size() && "Invalid vreg!");
RegAllocHints[Reg].first = Type;
RegAllocHints[Reg].second = PrefReg;
}
@@ -242,8 +234,6 @@ public:
/// specified virtual register.
std::pair<unsigned, unsigned>
getRegAllocationHint(unsigned Reg) const {
- Reg -= TargetRegisterInfo::FirstVirtualRegister;
- assert(Reg < VRegInfo.size() && "Invalid vreg!");
return RegAllocHints[Reg];
}
diff --git a/include/llvm/CodeGen/MachineRelocation.h b/include/llvm/CodeGen/MachineRelocation.h
index c316785dd1..244b466e17 100644
--- a/include/llvm/CodeGen/MachineRelocation.h
+++ b/include/llvm/CodeGen/MachineRelocation.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CODEGEN_MACHINERELOCATION_H
#define LLVM_CODEGEN_MACHINERELOCATION_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index bbedabd407..53aee7a9c9 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -45,10 +45,19 @@ namespace llvm {
///
extern char &MachineLoopInfoID;
+ /// MachineLoopRanges pass - This pass is an on-demand loop coverage
+ /// analysis pass.
+ ///
+ extern char &MachineLoopRangesID;
+
/// MachineDominators pass - This pass is a machine dominators analysis pass.
///
extern char &MachineDominatorsID;
+ /// EdgeBundles analysis - Bundle machine CFG edges.
+ ///
+ extern char &EdgeBundlesID;
+
/// PHIElimination pass - This pass eliminates machine instruction PHI nodes
/// by inserting copy instructions. This destroys SSA information, but is the
/// desired input for some register allocators. This pass is "required" by
@@ -79,6 +88,11 @@ namespace llvm {
/// register allocators.
extern char &TwoAddressInstructionPassID;
+ /// SpillPlacement analysis. Suggest optimal placement of spill code between
+ /// basic blocks.
+ ///
+ extern char &SpillPlacementID;
+
/// UnreachableMachineBlockElimination pass - This pass removes unreachable
/// machine basic blocks.
extern char &UnreachableMachineBlockElimID;
@@ -103,6 +117,11 @@ namespace llvm {
///
FunctionPass *createBasicRegisterAllocator();
+ /// Greedy register allocation pass - This pass implements a global register
+ /// allocator for optimized builds.
+ ///
+ FunctionPass *createGreedyRegisterAllocator();
+
/// LinearScanRegisterAllocation Pass - This pass implements the linear scan
/// register allocation algorithm, a global register allocator.
///
@@ -196,7 +215,7 @@ namespace llvm {
/// createMachineVerifierPass - This pass verifies cenerated machine code
/// instructions for correctness.
- FunctionPass *createMachineVerifierPass();
+ FunctionPass *createMachineVerifierPass(const char *Banner = 0);
/// createDwarfEHPass - This pass mulches exception handling code into a form
/// adapted to code generation. Required if using dwarf exception handling.
@@ -213,6 +232,10 @@ namespace llvm {
/// addressing.
FunctionPass *createLocalStackSlotAllocationPass();
+ /// createExpandISelPseudosPass - This pass expands pseudo-instructions.
+ ///
+ FunctionPass *createExpandISelPseudosPass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/CodeGen/PostRAHazardRecognizer.h b/include/llvm/CodeGen/PostRAHazardRecognizer.h
deleted file mode 100644
index 4160384f89..0000000000
--- a/include/llvm/CodeGen/PostRAHazardRecognizer.h
+++ /dev/null
@@ -1,94 +0,0 @@
-//=- llvm/CodeGen/PostRAHazardRecognizer.h - Scheduling Support -*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the PostRAHazardRecognizer class, which
-// implements hazard-avoidance heuristics for scheduling, based on the
-// scheduling itineraries specified for the target.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_EXACTHAZARDRECOGNIZER_H
-#define LLVM_CODEGEN_EXACTHAZARDRECOGNIZER_H
-
-#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
-#include "llvm/System/DataTypes.h"
-
-#include <cassert>
-#include <cstring>
-#include <string>
-
-namespace llvm {
-
-class InstrItineraryData;
-class SUnit;
-
-class PostRAHazardRecognizer : public ScheduleHazardRecognizer {
- // ScoreBoard to track function unit usage. ScoreBoard[0] is a
- // mask of the FUs in use in the cycle currently being
- // schedule. ScoreBoard[1] is a mask for the next cycle. The
- // ScoreBoard is used as a circular buffer with the current cycle
- // indicated by Head.
- class ScoreBoard {
- unsigned *Data;
-
- // The maximum number of cycles monitored by the Scoreboard. This
- // value is determined based on the target itineraries to ensure
- // that all hazards can be tracked.
- size_t Depth;
- // Indices into the Scoreboard that represent the current cycle.
- size_t Head;
- public:
- ScoreBoard():Data(NULL), Depth(0), Head(0) { }
- ~ScoreBoard() {
- delete[] Data;
- }
-
- size_t getDepth() const { return Depth; }
- unsigned& operator[](size_t idx) const {
- assert(Depth && "ScoreBoard was not initialized properly!");
-
- return Data[(Head + idx) % Depth];
- }
-
- void reset(size_t d = 1) {
- if (Data == NULL) {
- Depth = d;
- Data = new unsigned[Depth];
- }
-
- memset(Data, 0, Depth * sizeof(Data[0]));
- Head = 0;
- }
-
- void advance() {
- Head = (Head + 1) % Depth;
- }
-
- // Print the scoreboard.
- void dump() const;
- };
-
- // Itinerary data for the target.
- const InstrItineraryData *ItinData;
-
- ScoreBoard ReservedScoreboard;
- ScoreBoard RequiredScoreboard;
-
-public:
- PostRAHazardRecognizer(const InstrItineraryData *ItinData);
-
- virtual HazardType getHazardType(SUnit *SU);
- virtual void Reset();
- virtual void EmitInstruction(SUnit *SU);
- virtual void AdvanceCycle();
-};
-
-}
-
-#endif
diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h
index 008a7b3bf3..7e8745edde 100644
--- a/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/include/llvm/CodeGen/RegAllocPBQP.h
@@ -22,10 +22,11 @@
#include "llvm/CodeGen/PBQP/Solution.h"
#include <map>
+#include <set>
namespace llvm {
- class LiveInterval;
+ class LiveIntervals;
class MachineFunction;
class MachineLoopInfo;
diff --git a/include/llvm/CodeGen/RegisterCoalescer.h b/include/llvm/CodeGen/RegisterCoalescer.h
index 7644433a33..af0b394691 100644
--- a/include/llvm/CodeGen/RegisterCoalescer.h
+++ b/include/llvm/CodeGen/RegisterCoalescer.h
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/System/IncludeFile.h"
+#include "llvm/Support/IncludeFile.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/ADT/SmallPtrSet.h"
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
index 246831c034..26b6773c05 100644
--- a/include/llvm/CodeGen/RegisterScavenging.h
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -100,7 +100,7 @@ public:
/// getRegsAvailable - Return all available registers in the register class
/// in Mask.
- void getRegsAvailable(const TargetRegisterClass *RC, BitVector &Mask);
+ BitVector getRegsAvailable(const TargetRegisterClass *RC);
/// FindUnusedReg - Find a unused register of the specified register class.
/// Return 0 if none is found.
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index a86ba83185..3864ffd50a 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -221,6 +221,9 @@ namespace llvm {
}
};
+ template <>
+ struct isPodLike<SDep> { static const bool value = true; };
+
/// SUnit - Scheduling unit. This is a node in the scheduling DAG.
class SUnit {
private:
@@ -229,9 +232,8 @@ namespace llvm {
public:
SUnit *OrigNode; // If not this, the node from which
// this node was cloned.
-
- // Preds/Succs - The SUnits before/after us in the graph. The boolean value
- // is true if the edge is a token chain edge, false if it is a value edge.
+
+ // Preds/Succs - The SUnits before/after us in the graph.
SmallVector<SDep, 4> Preds; // All sunit predecessors.
SmallVector<SDep, 4> Succs; // All sunit successors.
@@ -242,11 +244,12 @@ namespace llvm {
unsigned NodeNum; // Entry # of node in the node vector.
unsigned NodeQueueId; // Queue id of node.
- unsigned short Latency; // Node latency.
unsigned NumPreds; // # of SDep::Data preds.
unsigned NumSuccs; // # of SDep::Data sucss.
unsigned NumPredsLeft; // # of preds not scheduled.
unsigned NumSuccsLeft; // # of succs not scheduled.
+ unsigned short NumRegDefsLeft; // # of reg defs with no scheduled use.
+ unsigned short Latency; // Node latency.
bool isCall : 1; // Is a function call.
bool isTwoAddress : 1; // Is a two-address instruction.
bool isCommutable : 1; // Is a commutable instruction.
@@ -268,13 +271,13 @@ namespace llvm {
public:
const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
const TargetRegisterClass *CopySrcRC;
-
+
/// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
/// an SDNode and any nodes flagged to it.
SUnit(SDNode *node, unsigned nodenum)
: Node(node), Instr(0), OrigNode(0), NodeNum(nodenum),
- NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
- NumSuccsLeft(0),
+ NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
+ NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
isCall(false), isTwoAddress(false), isCommutable(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
@@ -287,8 +290,8 @@ namespace llvm {
/// a MachineInstr.
SUnit(MachineInstr *instr, unsigned nodenum)
: Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum),
- NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
- NumSuccsLeft(0),
+ NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
+ NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
isCall(false), isTwoAddress(false), isCommutable(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
@@ -300,8 +303,8 @@ namespace llvm {
/// SUnit - Construct a placeholder SUnit.
SUnit()
: Node(0), Instr(0), OrigNode(0), NodeNum(~0u),
- NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
- NumSuccsLeft(0),
+ NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
+ NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
isCall(false), isTwoAddress(false), isCommutable(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
@@ -324,6 +327,10 @@ namespace llvm {
return Node;
}
+ /// isInstr - Return true if this SUnit refers to a machine instruction as
+ /// opposed to an SDNode.
+ bool isInstr() const { return Instr; }
+
/// setInstr - Assign the instruction for the SUnit.
/// This may be used during post-regalloc scheduling.
void setInstr(MachineInstr *MI) {
@@ -341,7 +348,7 @@ namespace llvm {
/// addPred - This adds the specified edge as a pred of the current node if
/// not already. It also adds the current node as a successor of the
/// specified node.
- void addPred(const SDep &D);
+ bool addPred(const SDep &D);
/// removePred - This removes the specified edge as a pred of the current
/// node if it exists. It also removes the current node as a successor of
@@ -351,7 +358,7 @@ namespace llvm {
/// getDepth - Return the depth of this node, which is the length of the
/// maximum path up to any node with has no predecessors.
unsigned getDepth() const {
- if (!isDepthCurrent)
+ if (!isDepthCurrent)
const_cast<SUnit *>(this)->ComputeDepth();
return Depth;
}
@@ -359,7 +366,7 @@ namespace llvm {
/// getHeight - Return the height of this node, which is the length of the
/// maximum path down to any node with has no successors.
unsigned getHeight() const {
- if (!isHeightCurrent)
+ if (!isHeightCurrent)
const_cast<SUnit *>(this)->ComputeHeight();
return Height;
}
@@ -391,7 +398,7 @@ namespace llvm {
return true;
return false;
}
-
+
/// isSucc - Test if node N is a successor of this node.
bool isSucc(SUnit *N) {
for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
@@ -412,25 +419,38 @@ namespace llvm {
//===--------------------------------------------------------------------===//
/// SchedulingPriorityQueue - This interface is used to plug different
/// priorities computation algorithms into the list scheduler. It implements
- /// the interface of a standard priority queue, where nodes are inserted in
+ /// the interface of a standard priority queue, where nodes are inserted in
/// arbitrary order and returned in priority order. The computation of the
/// priority and the representation of the queue are totally up to the
/// implementation to decide.
- ///
+ ///
class SchedulingPriorityQueue {
unsigned CurCycle;
+ bool HasReadyFilter;
public:
- SchedulingPriorityQueue() : CurCycle(0) {}
+ SchedulingPriorityQueue(bool rf = false):
+ CurCycle(0), HasReadyFilter(rf) {}
virtual ~SchedulingPriorityQueue() {}
-
+
+ virtual bool isBottomUp() const = 0;
+
virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
virtual void addNode(const SUnit *SU) = 0;
virtual void updateNode(const SUnit *SU) = 0;
virtual void releaseState() = 0;
virtual bool empty() const = 0;
+
+ bool hasReadyFilter() const { return HasReadyFilter; }
+
+ virtual bool tracksRegPressure() const { return false; }
+
+ virtual bool isReady(SUnit *) const {
+ assert(!HasReadyFilter && "The ready filter must override isReady()");
+ return true;
+ }
virtual void push(SUnit *U) = 0;
-
+
void push_all(const std::vector<SUnit *> &Nodes) {
for (std::vector<SUnit *>::const_iterator I = Nodes.begin(),
E = Nodes.end(); I != E; ++I)
@@ -441,6 +461,8 @@ namespace llvm {
virtual void remove(SUnit *SU) = 0;
+ virtual void dump(ScheduleDAG *) const {}
+
/// ScheduledNode - As each node is scheduled, this method is invoked. This
/// allows the priority function to adjust the priority of related
/// unscheduled nodes, for example.
@@ -455,7 +477,7 @@ namespace llvm {
unsigned getCurCycle() const {
return CurCycle;
- }
+ }
};
class ScheduleDAG {
@@ -477,11 +499,18 @@ namespace llvm {
virtual ~ScheduleDAG();
+ /// getInstrDesc - Return the TargetInstrDesc of this SUnit.
+ /// Return NULL for SDNodes without a machine opcode.
+ const TargetInstrDesc *getInstrDesc(const SUnit *SU) const {
+ if (SU->isInstr()) return &SU->getInstr()->getDesc();
+ return getNodeDesc(SU->getNode());
+ }
+
/// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
/// using 'dot'.
///
void viewGraph();
-
+
/// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock
/// according to the order specified in Sequence.
///
@@ -540,6 +569,10 @@ namespace llvm {
void EmitNoop();
void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
+
+ private:
+ // Return the TargetInstrDesc of this SDNode or NULL.
+ const TargetInstrDesc *getNodeDesc(const SDNode *Node) const;
};
class SUnitIterator : public std::iterator<std::forward_iterator_tag,
@@ -631,7 +664,7 @@ namespace llvm {
/// Visited - a set of nodes visited during a DFS traversal.
BitVector Visited;
- /// DFS - make a DFS traversal and mark all nodes affected by the
+ /// DFS - make a DFS traversal and mark all nodes affected by the
/// edge insertion. These nodes will later get new topological indexes
/// by means of the Shift method.
void DFS(const SUnit *SU, int UpperBound, bool& HasLoop);
@@ -646,7 +679,7 @@ namespace llvm {
public:
explicit ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits);
- /// InitDAGTopologicalSorting - create the initial topological
+ /// InitDAGTopologicalSorting - create the initial topological
/// ordering from the DAG to be scheduled.
void InitDAGTopologicalSorting();
diff --git a/include/llvm/CodeGen/ScheduleHazardRecognizer.h b/include/llvm/CodeGen/ScheduleHazardRecognizer.h
index 09e3e88613..2f53baa1c7 100644
--- a/include/llvm/CodeGen/ScheduleHazardRecognizer.h
+++ b/include/llvm/CodeGen/ScheduleHazardRecognizer.h
@@ -23,7 +23,15 @@ class SUnit;
/// issued this cycle, and whether or not a noop needs to be inserted to handle
/// the hazard.
class ScheduleHazardRecognizer {
+protected:
+ /// MaxLookAhead - Indicate the number of cycles in the scoreboard
+ /// state. Important to restore the state after backtracking. Additionally,
+ /// MaxLookAhead=0 identifies a fake recognizer, allowing the client to
+ /// bypass virtual calls. Currently the PostRA scheduler ignores it.
+ unsigned MaxLookAhead;
+
public:
+ ScheduleHazardRecognizer(): MaxLookAhead(0) {}
virtual ~ScheduleHazardRecognizer();
enum HazardType {
@@ -32,6 +40,14 @@ public:
NoopHazard // This instruction can't be emitted, and needs noops.
};
+ unsigned getMaxLookAhead() const { return MaxLookAhead; }
+
+ bool isEnabled() const { return MaxLookAhead != 0; }
+
+ /// atIssueLimit - Return true if no more instructions may be issued in this
+ /// cycle.
+ virtual bool atIssueLimit() const { return false; }
+
/// getHazardType - Return the hazard type of emitting this node. There are
/// three possible results. Either:
/// * NoHazard: it is legal to issue this instruction on this cycle.
@@ -39,7 +55,7 @@ public:
/// other instruction is available, issue it first.
/// * NoopHazard: issuing this instruction would break the program. If
/// some other instruction can be issued, do so, otherwise issue a noop.
- virtual HazardType getHazardType(SUnit *) {
+ virtual HazardType getHazardType(SUnit *m, int Stalls) {
return NoHazard;
}
@@ -52,12 +68,18 @@ public:
/// emitted, to advance the hazard state.
virtual void EmitInstruction(SUnit *) {}
- /// AdvanceCycle - This callback is invoked when no instructions can be
- /// issued on this cycle without a hazard. This should increment the
+ /// AdvanceCycle - This callback is invoked whenever the next top-down
+ /// instruction to be scheduled cannot issue in the current cycle, either
+ /// because of latency or resource conflicts. This should increment the
/// internal state of the hazard recognizer so that previously "Hazard"
/// instructions will now not be hazards.
virtual void AdvanceCycle() {}
+ /// RecedeCycle - This callback is invoked whenever the next bottom-up
+ /// instruction to be scheduled cannot issue in the current cycle, either
+ /// because of latency or resource conflicts.
+ virtual void RecedeCycle() {}
+
/// EmitNoop - This callback is invoked when a noop was added to the
/// instruction stream.
virtual void EmitNoop() {
diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
new file mode 100644
index 0000000000..8850006df8
--- /dev/null
+++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
@@ -0,0 +1,129 @@
+//=- llvm/CodeGen/ScoreboardHazardRecognizer.h - Schedule Support -*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ScoreboardHazardRecognizer class, which
+// encapsulates hazard-avoidance heuristics for scheduling, based on the
+// scheduling itineraries specified for the target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
+#define LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
+
+#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
+#include "llvm/Support/DataTypes.h"
+
+#include <cassert>
+#include <cstring>
+#include <string>
+
+namespace llvm {
+
+class InstrItineraryData;
+class TargetInstrDesc;
+class ScheduleDAG;
+class SUnit;
+
+class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer {
+ // Scoreboard to track function unit usage. Scoreboard[0] is a
+ // mask of the FUs in use in the cycle currently being
+ // schedule. Scoreboard[1] is a mask for the next cycle. The
+ // Scoreboard is used as a circular buffer with the current cycle
+ // indicated by Head.
+ //
+ // Scoreboard always counts cycles in forward execution order. If used by a
+ // bottom-up scheduler, then the scoreboard cycles are the inverse of the
+ // scheduler's cycles.
+ class Scoreboard {
+ unsigned *Data;
+
+ // The maximum number of cycles monitored by the Scoreboard. This
+ // value is determined based on the target itineraries to ensure
+ // that all hazards can be tracked.
+ size_t Depth;
+ // Indices into the Scoreboard that represent the current cycle.
+ size_t Head;
+ public:
+ Scoreboard():Data(NULL), Depth(0), Head(0) { }
+ ~Scoreboard() {
+ delete[] Data;
+ }
+
+ size_t getDepth() const { return Depth; }
+ unsigned& operator[](size_t idx) const {
+ // Depth is expected to be a power-of-2.
+ assert(Depth && !(Depth & (Depth - 1)) &&
+ "Scoreboard was not initialized properly!");
+
+ return Data[(Head + idx) & (Depth-1)];
+ }
+
+ void reset(size_t d = 1) {
+ if (Data == NULL) {
+ Depth = d;
+ Data = new unsigned[Depth];
+ }
+
+ memset(Data, 0, Depth * sizeof(Data[0]));
+ Head = 0;
+ }
+
+ void advance() {
+ Head = (Head + 1) & (Depth-1);
+ }
+
+ void recede() {
+ Head = (Head - 1) & (Depth-1);
+ }
+
+ // Print the scoreboard.
+ void dump() const;
+ };
+
+#ifndef NDEBUG
+ // Support for tracing ScoreboardHazardRecognizer as a component within
+ // another module. Follows the current thread-unsafe model of tracing.
+ static const char *DebugType;
+#endif
+
+ // Itinerary data for the target.
+ const InstrItineraryData *ItinData;
+
+ const ScheduleDAG *DAG;
+
+ /// IssueWidth - Max issue per cycle. 0=Unknown.
+ unsigned IssueWidth;
+
+ /// IssueCount - Count instructions issued in this cycle.
+ unsigned IssueCount;
+
+ Scoreboard ReservedScoreboard;
+ Scoreboard RequiredScoreboard;
+
+public:
+ ScoreboardHazardRecognizer(const InstrItineraryData *ItinData,
+ const ScheduleDAG *DAG,
+ const char *ParentDebugType = "");
+
+ /// atIssueLimit - Return true if no more instructions may be issued in this
+ /// cycle.
+ virtual bool atIssueLimit() const;
+
+ // Stalls provides an cycle offset at which SU will be scheduled. It will be
+ // negative for bottom-up scheduling.
+ virtual HazardType getHazardType(SUnit *SU, int Stalls);
+ virtual void Reset();
+ virtual void EmitInstruction(SUnit *SU);
+ virtual void AdvanceCycle();
+ virtual void RecedeCycle();
+};
+
+}
+
+#endif //!LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 4dfc3c6728..c9de95bebd 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -171,9 +171,6 @@ class SelectionDAG {
/// DbgInfo - Tracks dbg_value information through SDISel.
SDDbgInfo *DbgInfo;
- /// VerifyNode - Sanity check the given node. Aborts if it is invalid.
- void VerifyNode(SDNode *N);
-
/// setGraphColorHelper - Implementation of setSubgraphColor.
/// Return whether we had to truncate the search.
///
@@ -401,21 +398,21 @@ public:
}
// This version of the getCopyToReg method takes an extra operand, which
- // indicates that there is potentially an incoming flag value (if Flag is not
- // null) and that there should be a flag result.
+ // indicates that there is potentially an incoming glue value (if Glue is not
+ // null) and that there should be a glue result.
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N,
- SDValue Flag) {
- SDVTList VTs = getVTList(MVT::Other, MVT::Flag);
- SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Flag };
- return getNode(ISD::CopyToReg, dl, VTs, Ops, Flag.getNode() ? 4 : 3);
+ SDValue Glue) {
+ SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
+ SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Glue };
+ return getNode(ISD::CopyToReg, dl, VTs, Ops, Glue.getNode() ? 4 : 3);
}
// Similar to last getCopyToReg() except parameter Reg is a SDValue
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, SDValue Reg, SDValue N,
- SDValue Flag) {
- SDVTList VTs = getVTList(MVT::Other, MVT::Flag);
- SDValue Ops[] = { Chain, Reg, N, Flag };
- return getNode(ISD::CopyToReg, dl, VTs, Ops, Flag.getNode() ? 4 : 3);
+ SDValue Glue) {
+ SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
+ SDValue Ops[] = { Chain, Reg, N, Glue };
+ return getNode(ISD::CopyToReg, dl, VTs, Ops, Glue.getNode() ? 4 : 3);
}
SDValue getCopyFromReg(SDValue Chain, DebugLoc dl, unsigned Reg, EVT VT) {
@@ -425,13 +422,13 @@ public:
}
// This version of the getCopyFromReg method takes an extra operand, which
- // indicates that there is potentially an incoming flag value (if Flag is not
- // null) and that there should be a flag result.
+ // indicates that there is potentially an incoming glue value (if Glue is not
+ // null) and that there should be a glue result.
SDValue getCopyFromReg(SDValue Chain, DebugLoc dl, unsigned Reg, EVT VT,
- SDValue Flag) {
- SDVTList VTs = getVTList(VT, MVT::Other, MVT::Flag);
- SDValue Ops[] = { Chain, getRegister(Reg, VT), Flag };
- return getNode(ISD::CopyFromReg, dl, VTs, Ops, Flag.getNode() ? 3 : 2);
+ SDValue Glue) {
+ SDVTList VTs = getVTList(VT, MVT::Other, MVT::Glue);
+ SDValue Ops[] = { Chain, getRegister(Reg, VT), Glue };
+ return getNode(ISD::CopyFromReg, dl, VTs, Ops, Glue.getNode() ? 3 : 2);
}
SDValue getCondCode(ISD::CondCode Cond);
@@ -465,27 +462,27 @@ public:
SDValue getNOT(DebugLoc DL, SDValue Val, EVT VT);
/// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have
- /// a flag result (to ensure it's not CSE'd). CALLSEQ_START does not have a
+ /// a glue result (to ensure it's not CSE'd). CALLSEQ_START does not have a
/// useful DebugLoc.
SDValue getCALLSEQ_START(SDValue Chain, SDValue Op) {
- SDVTList VTs = getVTList(MVT::Other, MVT::Flag);
+ SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
SDValue Ops[] = { Chain, Op };
return getNode(ISD::CALLSEQ_START, DebugLoc(), VTs, Ops, 2);
}
/// getCALLSEQ_END - Return a new CALLSEQ_END node, which always must have a
- /// flag result (to ensure it's not CSE'd). CALLSEQ_END does not have
+ /// glue result (to ensure it's not CSE'd). CALLSEQ_END does not have
/// a useful DebugLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2,
- SDValue InFlag) {
- SDVTList NodeTys = getVTList(MVT::Other, MVT::Flag);
+ SDValue InGlue) {
+ SDVTList NodeTys = getVTList(MVT::Other, MVT::Glue);
SmallVector<SDValue, 4> Ops;
Ops.push_back(Chain);
Ops.push_back(Op1);
Ops.push_back(Op2);
- Ops.push_back(InFlag);
+ Ops.push_back(InGlue);
return getNode(ISD::CALLSEQ_END, DebugLoc(), NodeTys, &Ops[0],
- (unsigned)Ops.size() - (InFlag.getNode() == 0 ? 1 : 0));
+ (unsigned)Ops.size() - (InGlue.getNode() == 0 ? 1 : 0));
}
/// getUNDEF - Return an UNDEF node. UNDEF does not have a useful DebugLoc.
@@ -633,7 +630,7 @@ public:
MachinePointerInfo PtrInfo, bool isVolatile,
bool isNonTemporal, unsigned Alignment,
const MDNode *TBAAInfo = 0);
- SDValue getExtLoad(ISD::LoadExtType ExtType, EVT VT, DebugLoc dl,
+ SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT,
SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo,
EVT MemVT, bool isVolatile,
bool isNonTemporal, unsigned Alignment,
@@ -904,6 +901,9 @@ public:
SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) {
return DbgInfo->getSDDbgValues(SD);
}
+
+ /// TransferDbgValues - Transfer SDDbgValues.
+ void TransferDbgValues(SDValue From, SDValue To);
/// hasDebugValues - Return true if there are any SDDbgValue nodes associated
/// with this SelectionDAG.
@@ -966,6 +966,13 @@ public:
/// class to allow target nodes to be understood.
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth = 0) const;
+ /// isBaseWithConstantOffset - Return true if the specified operand is an
+ /// ISD::ADD with a ConstantSDNode on the right-hand side, or if it is an
+ /// ISD::OR with a ConstantSDNode that is guaranteed to have the same
+ /// semantics as an ADD. This handles the equivalence:
+ /// X|Cst == X+Cst iff X&Cst = 0.
+ bool isBaseWithConstantOffset(SDValue Op) const;
+
/// isKnownNeverNan - Test whether the given SDValue is known to never be NaN.
bool isKnownNeverNaN(SDValue Op) const;
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index 9601bbc2f9..54576794de 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -35,7 +35,7 @@ namespace llvm {
class GCFunctionInfo;
class ScheduleDAGSDNodes;
class LoadInst;
-
+
/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
/// pattern-matching instruction selectors.
class SelectionDAGISel : public MachineFunctionPass {
@@ -55,7 +55,7 @@ public:
explicit SelectionDAGISel(const TargetMachine &tm,
CodeGenOpt::Level OL = CodeGenOpt::Default);
virtual ~SelectionDAGISel();
-
+
const TargetLowering &getTargetLowering() { return TLI; }
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
@@ -63,18 +63,18 @@ public:
virtual bool runOnMachineFunction(MachineFunction &MF);
virtual void EmitFunctionEntryCode() {}
-
+
/// PreprocessISelDAG - This hook allows targets to hack on the graph before
/// instruction selection starts.
virtual void PreprocessISelDAG() {}
-
+
/// PostprocessISelDAG() - This hook allows the target to hack on the graph
/// right after selection.
virtual void PostprocessISelDAG() {}
-
+
/// Select - Main hook targets implement to select a node.
virtual SDNode *Select(SDNode *N) = 0;
-
+
/// SelectInlineAsmMemoryOperand - Select the specified address as a target
/// addressing mode, according to the specified constraint code. If this does
/// not match or is not implemented, return true. The resultant operands
@@ -98,19 +98,14 @@ public:
CodeGenOpt::Level OptLevel,
bool IgnoreChains = false);
- /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
- /// to use for this target when scheduling the DAG.
- virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer();
-
-
// Opcodes used by the DAG state machine:
enum BuiltinOpcodes {
OPC_Scope,
OPC_RecordNode,
- OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3,
+ OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3,
OPC_RecordChild4, OPC_RecordChild5, OPC_RecordChild6, OPC_RecordChild7,
OPC_RecordMemRef,
- OPC_CaptureFlagInput,
+ OPC_CaptureGlueInput,
OPC_MoveChild,
OPC_MoveParent,
OPC_CheckSame,
@@ -129,9 +124,10 @@ public:
OPC_CheckComplexPat,
OPC_CheckAndImm, OPC_CheckOrImm,
OPC_CheckFoldableChainNode,
-
+
OPC_EmitInteger,
OPC_EmitRegister,
+ OPC_EmitRegister2,
OPC_EmitConvertToTarget,
OPC_EmitMergeInputChains,
OPC_EmitMergeInputChains1_0,
@@ -140,15 +136,15 @@ public:
OPC_EmitNodeXForm,
OPC_EmitNode,
OPC_MorphNodeTo,
- OPC_MarkFlagResults,
+ OPC_MarkGlueResults,
OPC_CompleteMatch
};
-
+
enum {
- OPFL_None = 0, // Node has no chain or flag input and isn't variadic.
+ OPFL_None = 0, // Node has no chain or glue input and isn't variadic.
OPFL_Chain = 1, // Node has a chain input.
- OPFL_FlagInput = 2, // Node has a flag input.
- OPFL_FlagOutput = 4, // Node has a flag output.
+ OPFL_GlueInput = 2, // Node has a glue input.
+ OPFL_GlueOutput = 4, // Node has a glue output.
OPFL_MemRefs = 8, // Node gets accumulated MemRefs.
OPFL_Variadic0 = 1<<4, // Node is variadic, root has 0 fixed inputs.
OPFL_Variadic1 = 2<<4, // Node is variadic, root has 1 fixed inputs.
@@ -157,37 +153,37 @@ public:
OPFL_Variadic4 = 5<<4, // Node is variadic, root has 4 fixed inputs.
OPFL_Variadic5 = 6<<4, // Node is variadic, root has 5 fixed inputs.
OPFL_Variadic6 = 7<<4, // Node is variadic, root has 6 fixed inputs.
-
+
OPFL_VariadicInfo = OPFL_Variadic6
};
-
+
/// getNumFixedFromVariadicInfo - Transform an EmitNode flags word into the
/// number of fixed arity values that should be skipped when copying from the
/// root.
static inline int getNumFixedFromVariadicInfo(unsigned Flags) {
return ((Flags&OPFL_VariadicInfo) >> 4)-1;
}
-
-
+
+
protected:
/// DAGSize - Size of DAG being instruction selected.
///
unsigned DAGSize;
-
+
/// ISelPosition - Node iterator marking the current position of
/// instruction selection as it procedes through the topologically-sorted
/// node list.
SelectionDAG::allnodes_iterator ISelPosition;
-
- /// ISelUpdater - helper class to handle updates of the
+
+ /// ISelUpdater - helper class to handle updates of the
/// instruction selection graph.
class ISelUpdater : public SelectionDAG::DAGUpdateListener {
SelectionDAG::allnodes_iterator &ISelPosition;
public:
explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp)
: ISelPosition(isp) {}
-
+
/// NodeDeleted - Handle nodes deleted from the graph. If the
/// node being deleted is the current ISelPosition node, update
/// ISelPosition.
@@ -196,46 +192,46 @@ protected:
if (ISelPosition == SelectionDAG::allnodes_iterator(N))
++ISelPosition;
}
-
+
/// NodeUpdated - Ignore updates for now.
virtual void NodeUpdated(SDNode *N) {}
};
-
+
/// ReplaceUses - replace all uses of the old node F with the use
/// of the new node T.
void ReplaceUses(SDValue F, SDValue T) {
ISelUpdater ISU(ISelPosition);
CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU);
}
-
+
/// ReplaceUses - replace all uses of the old nodes F with the use
/// of the new nodes T.
void ReplaceUses(const SDValue *F, const SDValue *T, unsigned Num) {
ISelUpdater ISU(ISelPosition);
CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU);
}
-
+
/// ReplaceUses - replace all uses of the old node F with the use
/// of the new node T.
void ReplaceUses(SDNode *F, SDNode *T) {
ISelUpdater ISU(ISelPosition);
CurDAG->ReplaceAllUsesWith(F, T, &ISU);
}
-
+
/// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
/// by tblgen. Others should not call it.
void SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops);
-
+
public:
// Calls to these predicates are generated by tblgen.
bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
int64_t DesiredMaskS) const;
bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
int64_t DesiredMaskS) const;
-
-
+
+
/// CheckPatternPredicate - This function is generated by tblgen in the
/// target. It runs the specified pattern predicate and returns true if it
/// succeeds or false if it fails. The number is a private implementation
@@ -253,14 +249,14 @@ public:
assert(0 && "Tblgen should generate the implementation of this!");
return 0;
}
-
+
virtual bool CheckComplexPattern(SDNode *Root, SDNode *Parent, SDValue N,
unsigned PatternNo,
SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) {
assert(0 && "Tblgen should generate the implementation of this!");
return false;
}
-
+
virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {
assert(0 && "Tblgen shoudl generate this!");
return SDValue();
@@ -269,9 +265,9 @@ public:
SDNode *SelectCodeCommon(SDNode *NodeToMatch,
const unsigned char *MatcherTable,
unsigned TableSize);
-
+
private:
-
+
// Calls to these functions are generated by tblgen.
SDNode *Select_INLINEASM(SDNode *N);
SDNode *Select_UNDEF(SDNode *N);
@@ -281,7 +277,7 @@ private:
void DoInstructionSelection();
SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs,
const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo);
-
+
void PrepareEHLandingPad();
void SelectAllBasicBlocks(const Function &Fn);
bool TryToFoldFastISelLoad(const LoadInst *LI, FastISel *FastIS);
@@ -292,7 +288,7 @@ private:
bool &HadTailCall);
void CodeGenAndEmitDAG();
void LowerArguments(const BasicBlock *BB);
-
+
void ComputeLiveOutVRegInfo();
/// Create the scheduler. If a specific scheduler was specified
@@ -300,16 +296,16 @@ private:
/// one preferred by the target.
///
ScheduleDAGSDNodes *CreateScheduler();
-
+
/// OpcodeOffset - This is a cache used to dispatch efficiently into isel
/// state machines that start with a OPC_SwitchOpcode node.
std::vector<unsigned> OpcodeOffset;
-
- void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
- const SmallVectorImpl<SDNode*> &ChainNodesMatched,
- SDValue InputFlag,const SmallVectorImpl<SDNode*> &F,
- bool isMorphNodeTo);
-
+
+ void UpdateChainsAndGlue(SDNode *NodeToMatch, SDValue InputChain,
+ const SmallVectorImpl<SDNode*> &ChainNodesMatched,
+ SDValue InputGlue, const SmallVectorImpl<SDNode*> &F,
+ bool isMorphNodeTo);
+
};
}
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 8fa099ae39..64546394ce 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -29,7 +29,7 @@
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/DebugLoc.h"
#include <cassert>
@@ -524,24 +524,24 @@ public:
return X;
}
- /// getFlaggedNode - If this node has a flag operand, return the node
- /// to which the flag operand points. Otherwise return NULL.
- SDNode *getFlaggedNode() const {
+ /// getGluedNode - If this node has a glue operand, return the node
+ /// to which the glue operand points. Otherwise return NULL.
+ SDNode *getGluedNode() const {
if (getNumOperands() != 0 &&
- getOperand(getNumOperands()-1).getValueType() == MVT::Flag)
+ getOperand(getNumOperands()-1).getValueType() == MVT::Glue)
return getOperand(getNumOperands()-1).getNode();
return 0;
}
// If this is a pseudo op, like copyfromreg, look to see if there is a
- // real target node flagged to it. If so, return the target node.
- const SDNode *getFlaggedMachineNode() const {
+ // real target node glued to it. If so, return the target node.
+ const SDNode *getGluedMachineNode() const {
const SDNode *FoundNode = this;
- // Climb up flag edges until a machine-opcode node is found, or the
+ // Climb up glue edges until a machine-opcode node is found, or the
// end of the chain is reached.
while (!FoundNode->isMachineOpcode()) {
- const SDNode *N = FoundNode->getFlaggedNode();
+ const SDNode *N = FoundNode->getGluedNode();
if (!N) break;
FoundNode = N;
}
@@ -549,11 +549,11 @@ public:
return FoundNode;
}
- /// getFlaggedUser - If this node has a flag value with a user, return
+ /// getGluedUser - If this node has a glue value with a user, return
/// the user (there is at most one). Otherwise return NULL.
- SDNode *getFlaggedUser() const {
+ SDNode *getGluedUser() const {
for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI)
- if (UI.getUse().get().getValueType() == MVT::Flag)
+ if (UI.getUse().get().getValueType() == MVT::Glue)
return *UI;
return 0;
}
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
index c8f26544f0..0e2adb5897 100644
--- a/include/llvm/CodeGen/SlotIndexes.h
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -34,77 +34,35 @@ namespace llvm {
/// SlotIndex & SlotIndexes classes for the public interface to this
/// information.
class IndexListEntry {
- static const unsigned EMPTY_KEY_INDEX = ~0U & ~3U,
- TOMBSTONE_KEY_INDEX = ~0U & ~7U;
-
IndexListEntry *next, *prev;
MachineInstr *mi;
unsigned index;
- protected:
-
- typedef enum { EMPTY_KEY, TOMBSTONE_KEY } ReservedEntryType;
-
- // This constructor is only to be used by getEmptyKeyEntry
- // & getTombstoneKeyEntry. It sets index to the given
- // value and mi to zero.
- IndexListEntry(ReservedEntryType r) : mi(0) {
- switch(r) {
- case EMPTY_KEY: index = EMPTY_KEY_INDEX; break;
- case TOMBSTONE_KEY: index = TOMBSTONE_KEY_INDEX; break;
- default: assert(false && "Invalid value for constructor.");
- }
- next = this;
- prev = this;
- }
-
public:
- IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {
- assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
- "Attempt to create invalid index. "
- "Available indexes may have been exhausted?.");
- }
-
- bool isValid() const {
- return (index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX);
- }
+ IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {}
MachineInstr* getInstr() const { return mi; }
void setInstr(MachineInstr *mi) {
- assert(isValid() && "Attempt to modify reserved index.");
this->mi = mi;
}
unsigned getIndex() const { return index; }
void setIndex(unsigned index) {
- assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
- "Attempt to set index to invalid value.");
- assert(isValid() && "Attempt to reset reserved index value.");
this->index = index;
}
IndexListEntry* getNext() { return next; }
const IndexListEntry* getNext() const { return next; }
void setNext(IndexListEntry *next) {
- assert(isValid() && "Attempt to modify reserved index.");
this->next = next;
}
IndexListEntry* getPrev() { return prev; }
const IndexListEntry* getPrev() const { return prev; }
void setPrev(IndexListEntry *prev) {
- assert(isValid() && "Attempt to modify reserved index.");
this->prev = prev;
}
-
- // This function returns the index list entry that is to be used for empty
- // SlotIndex keys.
- static IndexListEntry* getEmptyKeyEntry();
-
- // This function returns the index list entry that is to be used for
- // tombstone SlotIndex keys.
- static IndexListEntry* getTombstoneKeyEntry();
};
// Specialize PointerLikeTypeTraits for IndexListEntry.
@@ -130,11 +88,10 @@ namespace llvm {
PointerIntPair<IndexListEntry*, 2, unsigned> lie;
SlotIndex(IndexListEntry *entry, unsigned slot)
- : lie(entry, slot) {
- assert(entry != 0 && "Attempt to construct index with 0 pointer.");
- }
+ : lie(entry, slot) {}
IndexListEntry& entry() const {
+ assert(isValid() && "Attempt to compare reserved index.");
return *lie.getPointer();
}
@@ -148,22 +105,27 @@ namespace llvm {
}
static inline unsigned getHashValue(const SlotIndex &v) {
- IndexListEntry *ptrVal = &v.entry();
- return (unsigned((intptr_t)ptrVal) >> 4) ^
- (unsigned((intptr_t)ptrVal) >> 9);
+ void *ptrVal = v.lie.getOpaqueValue();
+ return (unsigned((intptr_t)ptrVal)) ^ (unsigned((intptr_t)ptrVal) >> 9);
}
public:
+ enum {
+ /// The default distance between instructions as returned by distance().
+ /// This may vary as instructions are inserted and removed.
+ InstrDist = 4*NUM
+ };
+
static inline SlotIndex getEmptyKey() {
- return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0);
+ return SlotIndex(0, 1);
}
static inline SlotIndex getTombstoneKey() {
- return SlotIndex(IndexListEntry::getTombstoneKeyEntry(), 0);
+ return SlotIndex(0, 2);
}
/// Construct an invalid index.
- SlotIndex() : lie(IndexListEntry::getEmptyKeyEntry(), 0) {}
+ SlotIndex() : lie(0, 0) {}
// Construct a new slot index from the given one, and set the slot.
SlotIndex(const SlotIndex &li, Slot s)
@@ -175,8 +137,7 @@ namespace llvm {
/// Returns true if this is a valid index. Invalid indicies do
/// not point into an index table, and cannot be compared.
bool isValid() const {
- IndexListEntry *entry = lie.getPointer();
- return ((entry!= 0) && (entry->isValid()));
+ return lie.getPointer();
}
/// Print this index to the given raw_ostream.
@@ -187,11 +148,11 @@ namespace llvm {
/// Compare two SlotIndex objects for equality.
bool operator==(SlotIndex other) const {
- return getIndex() == other.getIndex();
+ return lie == other.lie;
}
/// Compare two SlotIndex objects for inequality.
bool operator!=(SlotIndex other) const {
- return getIndex() != other.getIndex();
+ return lie != other.lie;
}
/// Compare two SlotIndex objects. Return true if the first index
@@ -466,6 +427,9 @@ namespace llvm {
insert(getTail(), val);
}
+ /// Renumber locally after inserting newEntry.
+ void renumberIndexes(IndexListEntry *newEntry);
+
public:
static char ID;
@@ -530,7 +494,7 @@ namespace llvm {
/// Returns the instruction for the given index, or null if the given
/// index has no instruction associated with it.
MachineInstr* getInstructionFromIndex(SlotIndex index) const {
- return index.entry().getInstr();
+ return index.isValid() ? index.entry().getInstr() : 0;
}
/// Returns the next non-null index.
@@ -545,18 +509,22 @@ namespace llvm {
return nextNonNull;
}
- /// Returns the first index in the given basic block.
- SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
+ /// Return the (start,end) range of the given basic block.
+ const std::pair<SlotIndex, SlotIndex> &
+ getMBBRange(const MachineBasicBlock *mbb) const {
MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb);
assert(itr != mbb2IdxMap.end() && "MBB not found in maps.");
- return itr->second.first;
+ return itr->second;
+ }
+
+ /// Returns the first index in the given basic block.
+ SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
+ return getMBBRange(mbb).first;
}
/// Returns the last index in the given basic block.
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
- MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb);
- assert(itr != mbb2IdxMap.end() && "MBB not found in maps.");
- return itr->second.second;
+ return getMBBRange(mbb).second;
}
/// Returns the basic block which the given index falls in.
@@ -618,9 +586,11 @@ namespace llvm {
/// Insert the given machine instruction into the mapping. Returns the
/// assigned index.
- SlotIndex insertMachineInstrInMaps(MachineInstr *mi,
- bool *deferredRenumber = 0) {
+ SlotIndex insertMachineInstrInMaps(MachineInstr *mi) {
assert(mi2iMap.find(mi) == mi2iMap.end() && "Instr already indexed.");
+ // Numbering DBG_VALUE instructions could cause code generation to be
+ // affected by debug information.
+ assert(!mi->isDebugValue() && "Cannot number DBG_VALUE instructions.");
MachineBasicBlock *mbb = mi->getParent();
@@ -632,7 +602,6 @@ namespace llvm {
"Instruction's parent MBB has not been added to SlotIndexes.");
MachineBasicBlock::iterator miItr(mi);
- bool needRenumber = false;
IndexListEntry *newEntry;
// Get previous index, considering that not all instructions are indexed.
IndexListEntry *prevEntry;
@@ -655,55 +624,22 @@ namespace llvm {
// Get a number for the new instr, or 0 if there's no room currently.
// In the latter case we'll force a renumber later.
- unsigned dist = nextEntry->getIndex() - prevEntry->getIndex();
- unsigned newNumber = dist > SlotIndex::NUM ?
- prevEntry->getIndex() + ((dist >> 1) & ~3U) : 0;
-
- if (newNumber == 0) {
- needRenumber = true;
- }
+ unsigned dist = ((nextEntry->getIndex() - prevEntry->getIndex())/2) & ~3u;
+ unsigned newNumber = prevEntry->getIndex() + dist;
// Insert a new list entry for mi.
newEntry = createEntry(mi, newNumber);
insert(nextEntry, newEntry);
-
- SlotIndex newIndex(newEntry, SlotIndex::LOAD);
- mi2iMap.insert(std::make_pair(mi, newIndex));
- if (miItr == mbb->end()) {
- // If this is the last instr in the MBB then we need to fix up the bb
- // range:
- mbbRangeItr->second.second = SlotIndex(newEntry, SlotIndex::STORE);
- }
-
- // Renumber if we need to.
- if (needRenumber) {
- if (deferredRenumber == 0)
- renumberIndexes();
- else
- *deferredRenumber = true;
- }
+ // Renumber locally if we need to.
+ if (dist == 0)
+ renumberIndexes(newEntry);
+ SlotIndex newIndex(newEntry, SlotIndex::LOAD);
+ mi2iMap.insert(std::make_pair(mi, newIndex));
return newIndex;
}
- /// Add all instructions in the vector to the index list. This method will
- /// defer renumbering until all instrs have been added, and should be
- /// preferred when adding multiple instrs.
- void insertMachineInstrsInMaps(SmallVectorImpl<MachineInstr*> &mis) {
- bool renumber = false;
-
- for (SmallVectorImpl<MachineInstr*>::iterator
- miItr = mis.begin(), miEnd = mis.end();
- miItr != miEnd; ++miItr) {
- insertMachineInstrInMaps(*miItr, &renumber);
- }
-
- if (renumber)
- renumberIndexes();
- }
-
-
/// Remove the given machine instruction from the mapping.
void removeMachineInstrFromMaps(MachineInstr *mi) {
// remove index -> MachineInstr and
@@ -773,6 +709,20 @@ namespace llvm {
};
+ // Specialize IntervalMapInfo for half-open slot index intervals.
+ template <typename> struct IntervalMapInfo;
+ template <> struct IntervalMapInfo<SlotIndex> {
+ static inline bool startLess(const SlotIndex &x, const SlotIndex &a) {
+ return x < a;
+ }
+ static inline bool stopLess(const SlotIndex &b, const SlotIndex &x) {
+ return b <= x;
+ }
+ static inline bool adjacent(const SlotIndex &a, const SlotIndex &b) {
+ return a == b;
+ }
+ };
+
}
#endif // LLVM_CODEGEN_LIVEINDEX_H
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index d8f0373859..fba3e48c47 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -57,6 +57,8 @@ public:
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+ virtual const MCSection *getEHFrameSection() const;
+
const MCSection *getDataRelSection() const { return DataRelSection; }
/// getSectionForConstant - Given a constant with the SectionKind, return a
@@ -121,6 +123,8 @@ public:
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+ virtual const MCSection *getEHFrameSection() const;
+
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const;
@@ -184,6 +188,8 @@ public:
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+ virtual const MCSection *getEHFrameSection() const;
+
virtual const MCSection *getDrectveSection() const { return DrectveSection; }
virtual const MCSection *
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index ae6729a205..22d1622207 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -18,7 +18,7 @@
#include <cassert>
#include <string>
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
namespace llvm {
@@ -79,7 +79,7 @@ namespace llvm {
x86mmx = 33, // This is an X86 MMX value
- Flag = 34, // This glues nodes together during pre-RA sched
+ Glue = 34, // This glues nodes together during pre-RA sched
isVoid = 35, // This has no value
diff --git a/include/llvm/CompilerDriver/CompilationGraph.h b/include/llvm/CompilerDriver/CompilationGraph.h
index 619c904f15..e1eea325e3 100644
--- a/include/llvm/CompilerDriver/CompilationGraph.h
+++ b/include/llvm/CompilerDriver/CompilationGraph.h
@@ -21,7 +21,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <cassert>
#include <string>
diff --git a/include/llvm/CompilerDriver/Tool.h b/include/llvm/CompilerDriver/Tool.h
index 7316dfdcab..d0926ba983 100644
--- a/include/llvm/CompilerDriver/Tool.h
+++ b/include/llvm/CompilerDriver/Tool.h
@@ -18,7 +18,7 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <string>
#include <vector>
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index 26a39b224e..b2deb1dccf 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -1,4 +1,3 @@
-
/**************************************
** Created by Kevin from config.h.in **
***************************************/
@@ -6,53 +5,35 @@
#ifndef CONFIG_H
#define CONFIG_H
-/* Define if dlopen(0) will open the symbols of the program */
-#undef CAN_DLOPEN_SELF
-
/* Define if CBE is enabled for printf %a output */
-#undef ENABLE_CBE_PRINTF_A
-
-/* Relative directory for resource files */
-#define CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}"
-
-/* Directories clang will search for headers */
-#define C_INCLUDE_DIRS "${C_INCLUDE_DIRS}"
-
-/* Directory clang will search for libstdc++ headers */
-#define CXX_INCLUDE_ROOT "${CXX_INCLUDE_ROOT}"
-
-/* Architecture of libstdc++ headers */
-#define CXX_INCLUDE_ARCH "${CXX_INCLUDE_ARCH}"
-
-/* 32 bit multilib directory */
-#define CXX_INCLUDE_32BIT_DIR "${CXX_INCLUDE_32BIT_DIR}"
-
-/* 64 bit multilib directory */
-#define CXX_INCLUDE_64BIT_DIR "${CXX_INCLUDE_64BIT_DIR}"
+#cmakedefine ENABLE_CBE_PRINTF_A ${ENABLE_CBE_PRINTF_A}
/* Define if position independent code is enabled */
-#cmakedefine ENABLE_PIC ${ENABLE_PIC}
+#cmakedefine ENABLE_PIC
/* Define if threads enabled */
#cmakedefine ENABLE_THREADS ${ENABLE_THREADS}
+/* Define if timestamp information (e.g., __DATE___) is allowed */
+#cmakedefine ENABLE_TIMESTAMPS ${ENABLE_TIMESTAMPS}
+
/* Define to 1 if you have the `argz_append' function. */
-#undef HAVE_ARGZ_APPEND
+#cmakedefine HAVE_ARGZ_APPEND ${HAVE_ARGZ_APPEND}
/* Define to 1 if you have the `argz_create_sep' function. */
-#undef HAVE_ARGZ_CREATE_SEP
+#cmakedefine HAVE_ARGZ_CREATE_SEP ${HAVE_ARGZ_CREATE_SEP}
/* Define to 1 if you have the <argz.h> header file. */
#cmakedefine HAVE_ARGZ_H ${HAVE_ARGZ_H}
/* Define to 1 if you have the `argz_insert' function. */
-#undef HAVE_ARGZ_INSERT
+#cmakedefine HAVE_ARGZ_INSERT ${HAVE_ARGZ_INSERT}
/* Define to 1 if you have the `argz_next' function. */
-#undef HAVE_ARGZ_NEXT
+#cmakedefine HAVE_ARGZ_NEXT ${HAVE_ARGZ_NEXT}
/* Define to 1 if you have the `argz_stringify' function. */
-#undef HAVE_ARGZ_STRINGIFY
+#cmakedefine HAVE_ARGZ_STRINGIFY ${HAVE_ARGZ_STRINGIFY}
/* Define to 1 if you have the <assert.h> header file. */
#cmakedefine HAVE_ASSERT_H ${HAVE_ASSERT_H}
@@ -63,9 +44,6 @@
/* Define to 1 if you have the `bcopy' function. */
#undef HAVE_BCOPY
-/* Does not have bi-directional iterator */
-#undef HAVE_BI_ITERATOR
-
/* Define to 1 if you have the `ceilf' function. */
#cmakedefine HAVE_CEILF ${HAVE_CEILF}
@@ -73,10 +51,20 @@
#cmakedefine HAVE_CIRCO ${HAVE_CIRCO}
/* Define to 1 if you have the `closedir' function. */
-#undef HAVE_CLOSEDIR
+#cmakedefine HAVE_CLOSEDIR ${HAVE_CLOSEDIR}
+
+/* Define to 1 if you have the <CrashReporterClient.h> header file. */
+#undef HAVE_CRASHREPORTERCLIENT_H
+
+/* Define if __crashreporter_info__ exists. */
+#undef HAVE_CRASHREPORTER_INFO
/* Define to 1 if you have the <ctype.h> header file. */
-#undef HAVE_CTYPE_H
+#cmakedefine HAVE_CTYPE_H ${HAVE_CTYPE_H}
+
+/* Define to 1 if you have the declaration of `strerror_s', and to 0 if you
+ don't. */
+#cmakedefine01 HAVE_DECL_STRERROR_S
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
@@ -89,13 +77,13 @@
#cmakedefine HAVE_DLD_H ${HAVE_DLD_H}
/* Define to 1 if you have the `dlerror' function. */
-#undef HAVE_DLERROR
+#cmakedefine HAVE_DLERROR ${HAVE_DLERROR}
/* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine HAVE_DLFCN_H ${HAVE_DLFCN_H}
/* Define if dlopen() is available on this platform. */
-#undef HAVE_DLOPEN
+#cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN}
/* Define to 1 if you have the <dl.h> header file. */
#cmakedefine HAVE_DL_H ${HAVE_DL_H}
@@ -113,7 +101,7 @@
#cmakedefine HAVE_ERRNO_H ${HAVE_ERRNO_H}
/* Define to 1 if the system has the type `error_t'. */
-#undef HAVE_ERROR_T
+#cmakedefine HAVE_ERROR_T ${HAVE_ERROR_T}
/* Define to 1 if you have the <execinfo.h> header file. */
#cmakedefine HAVE_EXECINFO_H ${HAVE_EXECINFO_H}
@@ -124,41 +112,41 @@
/* Define if the neat program is available */
#cmakedefine HAVE_FDP ${HAVE_FDP}
+/* Define to 1 if you have the <fenv.h> header file. */
+#cmakedefine HAVE_FENV_H ${HAVE_FENV_H}
+
+/* Define if libffi is available on this platform. */
+#cmakedefine HAVE_FFI_CALL ${HAVE_FFI_CALL}
+
+/* Define to 1 if you have the <ffi/ffi.h> header file. */
+#cmakedefine HAVE_FFI_FFI_H ${HAVE_FFI_FFI_H}
+
+/* Define to 1 if you have the <ffi.h> header file. */
+#cmakedefine HAVE_FFI_H ${HAVE_FFI_H}
+
/* Set to 1 if the finite function is found in <ieeefp.h> */
#cmakedefine HAVE_FINITE_IN_IEEEFP_H ${HAVE_FINITE_IN_IEEEFP_H}
/* Define to 1 if you have the `floorf' function. */
#cmakedefine HAVE_FLOORF ${HAVE_FLOORF}
-/* Does not have forward iterator */
-#undef HAVE_FWD_ITERATOR
+/* Define to 1 if you have the `fmodf' function. */
+#cmakedefine HAVE_FMODF ${HAVE_FMODF}
/* Define to 1 if you have the `getcwd' function. */
-#undef HAVE_GETCWD
+#cmakedefine HAVE_GETCWD ${HAVE_GETCWD}
/* Define to 1 if you have the `getpagesize' function. */
#cmakedefine HAVE_GETPAGESIZE ${HAVE_GETPAGESIZE}
/* Define to 1 if you have the `getrlimit' function. */
-#undef HAVE_GETRLIMIT
+#cmakedefine HAVE_GETRLIMIT ${HAVE_GETRLIMIT}
/* Define to 1 if you have the `getrusage' function. */
#cmakedefine HAVE_GETRUSAGE ${HAVE_GETRUSAGE}
/* Define to 1 if you have the `gettimeofday' function. */
-#undef HAVE_GETTIMEOFDAY
-
-/* Does not have <hash_map> */
-#undef HAVE_GLOBAL_HASH_MAP
-
-/* Does not have hash_set in global namespace */
-#undef HAVE_GLOBAL_HASH_SET
-
-/* Does not have ext/hash_map */
-#undef HAVE_GNU_EXT_HASH_MAP
-
-/* Does not have hash_set in gnu namespace */
-#undef HAVE_GNU_EXT_HASH_SET
+#cmakedefine HAVE_GETTIMEOFDAY ${HAVE_GETTIMEOFDAY}
/* Define if the Graphviz program is available */
#undef HAVE_GRAPHVIZ
@@ -167,10 +155,10 @@
#cmakedefine HAVE_GV ${HAVE_GV}
/* Define to 1 if you have the `index' function. */
-#undef HAVE_INDEX
+#cmakedefine HAVE_INDEX ${HAVE_INDEX}
/* Define to 1 if the system has the type `int64_t'. */
-#undef HAVE_INT64_T
+#cmakedefine HAVE_INT64_T ${HAVE_INT64_T}
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
@@ -191,7 +179,7 @@
#cmakedefine HAVE_ISNAN_IN_MATH_H ${HAVE_ISNAN_IN_MATH_H}
/* Define if you have the libdl library or equivalent. */
-#undef HAVE_LIBDL
+#cmakedefine HAVE_LIBDL ${HAVE_LIBDL}
/* Define to 1 if you have the `imagehlp' library (-limagehlp). */
#cmakedefine HAVE_LIBIMAGEHLP ${HAVE_LIBIMAGEHLP}
@@ -211,6 +199,9 @@
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H ${HAVE_LIMITS_H}
+/* Define if you can use -Wl,-export-dynamic. */
+#define HAVE_LINK_EXPORT_DYNAMIC 1
+
/* Define to 1 if you have the <link.h> header file. */
#cmakedefine HAVE_LINK_H ${HAVE_LINK_H}
@@ -219,13 +210,13 @@
#undef HAVE_LINK_R
/* Define to 1 if you have the `longjmp' function. */
-#undef HAVE_LONGJMP
+#cmakedefine HAVE_LONGJMP ${HAVE_LONGJMP}
/* Define to 1 if you have the <mach/mach.h> header file. */
-#undef HAVE_MACH_MACH_H
+#cmakedefine HAVE_MACH_MACH_H ${HAVE_MACH_MACH_H}
/* Define to 1 if you have the <mach-o/dyld.h> header file. */
-#undef HAVE_MACH_O_DYLD_H
+#cmakedefine HAVE_MACH_O_DYLD_H ${HAVE_MACH_O_DYLD_H}
/* Define if mallinfo() is available on this platform. */
#cmakedefine HAVE_MALLINFO ${HAVE_MALLINFO}
@@ -240,10 +231,10 @@
#cmakedefine HAVE_MALLOC_ZONE_STATISTICS ${HAVE_MALLOC_ZONE_STATISTICS}
/* Define to 1 if you have the `memcpy' function. */
-#undef HAVE_MEMCPY
+#cmakedefine HAVE_MEMCPY ${HAVE_MEMCPY}
/* Define to 1 if you have the `memmove' function. */
-#undef HAVE_MEMMOVE
+#cmakedefine HAVE_MEMMOVE ${HAVE_MEMMOVE}
/* Define to 1 if you have the <memory.h> header file. */
#cmakedefine HAVE_MEMORY_H ${HAVE_MEMORY_H}
@@ -267,9 +258,6 @@
/* Define if mmap() can map files into memory */
#undef HAVE_MMAP_FILE
-/* define if the compiler implements namespaces */
-#undef HAVE_NAMESPACES
-
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#cmakedefine HAVE_NDIR_H ${HAVE_NDIR_H}
@@ -280,7 +268,13 @@
#cmakedefine HAVE_NEATO ${HAVE_NEATO}
/* Define to 1 if you have the `opendir' function. */
-#undef HAVE_OPENDIR
+#cmakedefine HAVE_OPENDIR ${HAVE_OPENDIR}
+
+/* Define to 1 if you have the `posix_spawn' function. */
+#cmakedefine HAVE_POSIX_SPAWN ${HAVE_POSIX_SPAWN}
+
+/* Define to 1 if you have the `powf' function. */
+#cmakedefine HAVE_POWF ${HAVE_POWF}
/* Define if libtool can extract symbol lists from object files. */
#undef HAVE_PRELOADED_SYMBOLS
@@ -288,7 +282,10 @@
/* Define to have the %a format string */
#undef HAVE_PRINTF_A
-/* Have pthread.h */
+/* Have pthread_getspecific */
+#cmakedefine HAVE_PTHREAD_GETSPECIFIC ${HAVE_PTHREAD_GETSPECIFIC}
+
+/* Define to 1 if you have the <pthread.h> header file. */
#cmakedefine HAVE_PTHREAD_H ${HAVE_PTHREAD_H}
/* Have pthread_mutex_lock */
@@ -297,30 +294,27 @@
/* Have pthread_rwlock_init */
#cmakedefine HAVE_PTHREAD_RWLOCK_INIT ${HAVE_PTHREAD_RWLOCK_INIT}
-/* Have pthread_getspecific */
-#cmakedefine HAVE_PTHREAD_GETSPECIFIC ${HAVE_PTHREAD_GETSPECIFIC}
-
/* Define to 1 if srand48/lrand48/drand48 exist in <stdlib.h> */
-#undef HAVE_RAND48
+#cmakedefine HAVE_RAND48 ${HAVE_RAND48}
/* Define to 1 if you have the `readdir' function. */
-#undef HAVE_READDIR
+#cmakedefine HAVE_READDIR ${HAVE_READDIR}
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
/* Define to 1 if you have the `rindex' function. */
-#undef HAVE_RINDEX
+#cmakedefine HAVE_RINDEX ${HAVE_RINDEX}
/* Define to 1 if you have the `rintf' function. */
#undef HAVE_RINTF
-/* Define to 1 if you have the `roundf' function. */
-#undef HAVE_ROUNDF
-
/* Define to 1 if you have the `round' function. */
#cmakedefine HAVE_ROUND ${HAVE_ROUND}
+/* Define to 1 if you have the `roundf' function. */
+#undef HAVE_ROUNDF
+
/* Define to 1 if you have the `sbrk' function. */
#cmakedefine HAVE_SBRK ${HAVE_SBRK}
@@ -328,7 +322,7 @@
#cmakedefine HAVE_SETENV ${HAVE_SETENV}
/* Define to 1 if you have the `setjmp' function. */
-#undef HAVE_SETJMP
+#cmakedefine HAVE_SETJMP ${HAVE_SETJMP}
/* Define to 1 if you have the <setjmp.h> header file. */
#cmakedefine HAVE_SETJMP_H ${HAVE_SETJMP_H}
@@ -340,13 +334,13 @@
#undef HAVE_SHL_LOAD
/* Define to 1 if you have the `siglongjmp' function. */
-#undef HAVE_SIGLONGJMP
+#cmakedefine HAVE_SIGLONGJMP ${HAVE_SIGLONGJMP}
/* Define to 1 if you have the <signal.h> header file. */
#cmakedefine HAVE_SIGNAL_H ${HAVE_SIGNAL_H}
/* Define to 1 if you have the `sigsetjmp' function. */
-#undef HAVE_SIGSETJMP
+#cmakedefine HAVE_SIGSETJMP ${HAVE_SIGSETJMP}
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
@@ -357,29 +351,20 @@
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H ${HAVE_STDLIB_H}
-/* Does not have ext/hash_map> */
-#undef HAVE_STD_EXT_HASH_MAP
-
-/* Does not have hash_set in std namespace */
-#undef HAVE_STD_EXT_HASH_SET
-
/* Set to 1 if the std::isinf function is found in <cmath> */
#undef HAVE_STD_ISINF_IN_CMATH
/* Set to 1 if the std::isnan function is found in <cmath> */
#undef HAVE_STD_ISNAN_IN_CMATH
-/* Does not have std namespace iterator */
-#undef HAVE_STD_ITERATOR
-
/* Define to 1 if you have the `strchr' function. */
-#undef HAVE_STRCHR
+#cmakedefine HAVE_STRCHR ${HAVE_STRCHR}
/* Define to 1 if you have the `strcmp' function. */
-#undef HAVE_STRCMP
+#cmakedefine HAVE_STRCMP ${HAVE_STRCMP}
/* Define to 1 if you have the `strdup' function. */
-#undef HAVE_STRDUP
+#cmakedefine HAVE_STRDUP ${HAVE_STRDUP}
/* Define to 1 if you have the `strerror' function. */
#cmakedefine HAVE_STRERROR ${HAVE_STRERROR}
@@ -387,23 +372,23 @@
/* Define to 1 if you have the `strerror_r' function. */
#cmakedefine HAVE_STRERROR_R ${HAVE_STRERROR_R}
-/* Define to 1 if you have the `strerror_s' function. */
-#cmakedefine HAVE_STRERROR_S ${HAVE_STRERROR_S}
-
/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
+#cmakedefine HAVE_STRINGS_H ${HAVE_STRINGS_H}
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H ${HAVE_STRING_H}
/* Define to 1 if you have the `strrchr' function. */
-#undef HAVE_STRRCHR
+#cmakedefine HAVE_STRRCHR ${HAVE_STRRCHR}
+
+/* Define to 1 if you have the `strtof' function. */
+#cmakedefine HAVE_STRTOF ${HAVE_STRTOF}
/* Define to 1 if you have the `strtoll' function. */
#cmakedefine HAVE_STRTOLL ${HAVE_STRTOLL}
/* Define to 1 if you have the `strtoq' function. */
-#undef HAVE_STRTOQ
+#cmakedefine HAVE_STRTOQ ${HAVE_STRTOQ}
/* Define to 1 if you have the `sysconf' function. */
#undef HAVE_SYSCONF
@@ -440,15 +425,12 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#cmakedefine HAVE_SYS_UIO_H ${HAVE_SYS_UIO_H}
+
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#cmakedefine HAVE_SYS_WAIT_H ${HAVE_SYS_WAIT_H}
-/* Define if the neat program is available */
-#cmakedefine HAVE_TWOPI ${HAVE_TWOPI}
-
-/* Define to 1 if the system has the type `uint64_t'. */
-#undef HAVE_UINT64_T
-
/* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H}
@@ -459,17 +441,74 @@
#cmakedefine HAVE_UTIME_H ${HAVE_UTIME_H}
/* Define to 1 if the system has the type `u_int64_t'. */
-#undef HAVE_U_INT64_T
+#cmakedefine HAVE_U_INT64_T ${HAVE_U_INT64_T}
/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
#cmakedefine HAVE_VALGRIND_VALGRIND_H ${HAVE_VALGRIND_VALGRIND_H}
-/* Define to 1 if you have the <fenv.h> header file. */
-#cmakedefine HAVE_FENV_H ${HAVE_FENV_H}
-
/* Define to 1 if you have the <windows.h> header file. */
#cmakedefine HAVE_WINDOWS_H ${HAVE_WINDOWS_H}
+/* Define to 1 if you have the `writev' function. */
+#cmakedefine HAVE_WRITEV ${HAVE_WRITEV}
+
+/* Define if the xdot.py program is available */
+#cmakedefine HAVE_XDOT_PY ${HAVE_XDOT_PY}
+
+/* Have host's _alloca */
+#cmakedefine HAVE__ALLOCA ${HAVE__ALLOCA}
+
+/* Have host's __alloca */
+#cmakedefine HAVE___ALLOCA ${HAVE___ALLOCA}
+
+/* Have host's __ashldi3 */
+#cmakedefine HAVE___ASHLDI3 ${HAVE___ASHLDI3}
+
+/* Have host's __ashrdi3 */
+#cmakedefine HAVE___ASHRDI3 ${HAVE___ASHRDI3}
+
+/* Have host's __chkstk */
+#cmakedefine HAVE___CHKSTK ${HAVE___CHKSTK}
+
+/* Have host's __cmpdi2 */
+#cmakedefine HAVE___CMPDI2 ${HAVE___CMPDI2}
+
+/* Have host's __divdi3 */
+#cmakedefine HAVE___DIVDI3 ${HAVE___DIVDI3}
+
+/* Define to 1 if you have the `__dso_handle' function. */
+#undef HAVE___DSO_HANDLE
+
+/* Have host's __fixdfdi */
+#cmakedefine HAVE___FIXDFDI ${HAVE___FIXDFDI}
+
+/* Have host's __fixsfdi */
+#cmakedefine HAVE___FIXSFDI ${HAVE___FIXSFDI}
+
+/* Have host's __floatdidf */
+#cmakedefine HAVE___FLOATDIDF ${HAVE___FLOATDIDF}
+
+/* Have host's __lshrdi3 */
+#cmakedefine HAVE___LSHRDI3 ${HAVE___LSHRDI3}
+
+/* Have host's __main */
+#cmakedefine HAVE___MAIN ${HAVE___MAIN}
+
+/* Have host's __moddi3 */
+#cmakedefine HAVE___MODDI3 ${HAVE___MODDI3}
+
+/* Have host's __udivdi3 */
+#cmakedefine HAVE___UDIVDI3 ${HAVE___UDIVDI3}
+
+/* Have host's __umoddi3 */
+#cmakedefine HAVE___UMODDI3 ${HAVE___UMODDI3}
+
+/* Have host's ___chkstk */
+#cmakedefine HAVE____CHKSTK ${HAVE____CHKSTK}
+
+/* Linker version detected at compile time. */
+#undef HOST_LINK_VERSION
+
/* Installation directory for binary executables */
#undef LLVM_BINDIR
@@ -479,6 +518,9 @@
/* Installation directory for documentation */
#undef LLVM_DATADIR
+/* Installation directory for documentation */
+#undef LLVM_DOCSDIR
+
/* Installation directory for config files */
#undef LLVM_ETCDIR
@@ -500,15 +542,24 @@
/* Build multithreading support into LLVM */
#cmakedefine LLVM_MULTITHREADED ${LLVM_MULTITHREADED}
+/* LLVM architecture name for the native architecture, if available */
+#cmakedefine LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}
+
+/* LLVM name for the native AsmPrinter init function, if available */
+#cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter
+
+/* LLVM name for the native Target init function, if available */
+#cmakedefine LLVM_NATIVE_TARGET LLVMInitialize${LLVM_NATIVE_ARCH}Target
+
+/* LLVM name for the native TargetInfo init function, if available */
+#cmakedefine LLVM_NATIVE_TARGETINFO LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo
+
/* Define if this is Unixish platform */
#cmakedefine LLVM_ON_UNIX ${LLVM_ON_UNIX}
/* Define if this is Win32ish platform */
#cmakedefine LLVM_ON_WIN32 ${LLVM_ON_WIN32}
-/* Added by Kevin -- Maximum path length */
-#cmakedefine MAXPATHLEN ${MAXPATHLEN}
-
/* Define to path to circo program if found or 'echo circo' otherwise */
#cmakedefine LLVM_PATH_CIRCO "${LLVM_PATH_CIRCO}"
@@ -533,6 +584,9 @@
/* Define to path to twopi program if found or 'echo twopi' otherwise */
#cmakedefine LLVM_PATH_TWOPI "${LLVM_PATH_TWOPI}"
+/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */
+#cmakedefine LLVM_PATH_XDOT_PY "${LLVM_PATH_XDOT_PY}"
+
/* Installation prefix directory */
#cmakedefine LLVM_PREFIX "${LLVM_PREFIX}"
@@ -578,6 +632,9 @@
/* Define as the return type of signal handlers (`int' or `void'). */
#cmakedefine RETSIGTYPE ${RETSIGTYPE}
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+#undef STAT_MACROS_BROKEN
+
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
@@ -598,28 +655,37 @@
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
+/* Define if we have the oprofile JIT-support library */
+#undef USE_OPROFILE
+
/* Define if use udis86 library */
#undef USE_UDIS86
-/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
- `char[]'. */
-#undef YYTEXT_POINTER
-
/* 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. */
#cmakedefine error_t ${error_t}
-/* Define to a type to use for `mode_t' if it is not otherwise available. */
-#cmakedefine mode_t ${mode_t}
-
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
+/* Define if the neat program is available */
+#cmakedefine HAVE_TWOPI ${HAVE_TWOPI}
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#cmakedefine HAVE_UINT64_T ${HAVE_UINT64_T}
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Define to a type to use for `mode_t' if it is not otherwise available. */
+#cmakedefine mode_t ${mode_t}
+
/* Define to a function replacing strtoll */
#cmakedefine strtoll ${strtoll}
@@ -632,16 +698,40 @@
/* Define to a function implementing strdup */
#cmakedefine strdup ${strdup}
-/* LLVM architecture name for the native architecture, if available */
-#cmakedefine LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}
-
-/* LLVM name for the native Target init function, if available */
-#cmakedefine LLVM_NATIVE_TARGET LLVMInitialize${LLVM_NATIVE_ARCH}Target
-
-/* LLVM name for the native TargetInfo init function, if available */
-#cmakedefine LLVM_NATIVE_TARGETINFO LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo
-
-/* LLVM name for the native AsmPrinter init function, if available */
-#cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter
+/* Define to 1 if you have the `_chsize_s' function. */
+#cmakedefine HAVE__CHSIZE_S ${HAVE__CHSIZE_S}
+
+/* define if the compiler implements namespaces */
+#undef HAVE_NAMESPACES
+
+/* Does not have std namespace iterator */
+#undef HAVE_STD_ITERATOR
+
+/* Does not have forward iterator */
+#undef HAVE_FWD_ITERATOR
+
+/* Does not have bi-directional iterator */
+#undef HAVE_BI_ITERATOR
+
+/* Does not have <hash_map> */
+#undef HAVE_GLOBAL_HASH_MAP
+
+/* Does not have hash_set in global namespace */
+#undef HAVE_GLOBAL_HASH_SET
+
+/* Does not have ext/hash_map */
+#undef HAVE_GNU_EXT_HASH_MAP
+
+/* Does not have hash_set in gnu namespace */
+#undef HAVE_GNU_EXT_HASH_SET
+
+/* Does not have ext/hash_map> */
+#undef HAVE_STD_EXT_HASH_MAP
+
+/* Does not have hash_set in std namespace */
+#undef HAVE_STD_EXT_HASH_SET
+
+/* Added by Kevin -- Maximum path length */
+#cmakedefine MAXPATHLEN ${MAXPATHLEN}
#endif
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index 1cc0c7bc76..14c44b4b1e 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -72,9 +72,16 @@
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
#undef HAVE_CRASHREPORTERCLIENT_H
+/* Define if __crashreporter_info__ exists. */
+#undef HAVE_CRASHREPORTER_INFO
+
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
+/* Define to 1 if you have the declaration of `strerror_s', and to 0 if you
+ don't. */
+#undef HAVE_DECL_STRERROR_S
+
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
@@ -381,9 +388,6 @@
/* Define to 1 if you have the `strerror_r' function. */
#undef HAVE_STRERROR_R
-/* Define to 1 if you have the `strerror_s' function. */
-#undef HAVE_STRERROR_S
-
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
@@ -437,6 +441,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
@@ -464,12 +471,63 @@
/* Define to 1 if you have the <windows.h> header file. */
#undef HAVE_WINDOWS_H
+/* Define to 1 if you have the `writev' function. */
+#undef HAVE_WRITEV
+
/* Define if the xdot.py program is available */
#undef HAVE_XDOT_PY
+/* Have host's _alloca */
+#undef HAVE__ALLOCA
+
+/* Have host's __alloca */
+#undef HAVE___ALLOCA
+
+/* Have host's __ashldi3 */
+#undef HAVE___ASHLDI3
+
+/* Have host's __ashrdi3 */
+#undef HAVE___ASHRDI3
+
+/* Have host's __chkstk */
+#undef HAVE___CHKSTK
+
+/* Have host's __cmpdi2 */
+#undef HAVE___CMPDI2
+
+/* Have host's __divdi3 */
+#undef HAVE___DIVDI3
+
/* Define to 1 if you have the `__dso_handle' function. */
#undef HAVE___DSO_HANDLE
+/* Have host's __fixdfdi */
+#undef HAVE___FIXDFDI
+
+/* Have host's __fixsfdi */
+#undef HAVE___FIXSFDI
+
+/* Have host's __floatdidf */
+#undef HAVE___FLOATDIDF
+
+/* Have host's __lshrdi3 */
+#undef HAVE___LSHRDI3
+
+/* Have host's __main */
+#undef HAVE___MAIN
+
+/* Have host's __moddi3 */
+#undef HAVE___MODDI3
+
+/* Have host's __udivdi3 */
+#undef HAVE___UDIVDI3
+
+/* Have host's __umoddi3 */
+#undef HAVE___UMODDI3
+
+/* Have host's ___chkstk */
+#undef HAVE____CHKSTK
+
/* Linker version detected at compile time. */
#undef HOST_LINK_VERSION
diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake
index 8469bcc606..33a40350d5 100644
--- a/include/llvm/Config/llvm-config.h.cmake
+++ b/include/llvm/Config/llvm-config.h.cmake
@@ -47,7 +47,7 @@
#cmakedefine LLVM_MANDIR "${LLVM_MANDIR}"
/* Build multithreading support into LLVM */
-#cmakedefine LLVM_MULTITHREADED
+#cmakedefine LLVM_MULTITHREADED ${LLVM_MULTITHREADED}
/* LLVM architecture name for the native architecture, if available */
#cmakedefine LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}
@@ -62,10 +62,10 @@
#cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter
/* Define if this is Unixish platform */
-#cmakedefine LLVM_ON_UNIX
+#cmakedefine LLVM_ON_UNIX ${LLVM_ON_UNIX}
/* Define if this is Win32ish platform */
-#cmakedefine LLVM_ON_WIN32
+#cmakedefine LLVM_ON_WIN32 ${LLVM_ON_WIN32}
/* Define to path to circo program if found or 'echo circo' otherwise */
#cmakedefine LLVM_PATH_CIRCO "${LLVM_PATH_CIRCO}"
@@ -91,6 +91,9 @@
/* Define to path to twopi program if found or 'echo twopi' otherwise */
#cmakedefine LLVM_PATH_TWOPI "${LLVM_PATH_TWOPI}"
+/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */
+#cmakedefine LLVM_PATH_XDOT_PY "${LLVM_PATH_XDOT.PY}"
+
/* Installation prefix directory */
#cmakedefine LLVM_PREFIX "${LLVM_PREFIX}"
diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h
index defe474fb5..38045fc0c1 100644
--- a/include/llvm/Constant.h
+++ b/include/llvm/Constant.h
@@ -141,16 +141,22 @@ public:
assert(0 && "Constants that do not have operands cannot be using 'From'!");
}
- static Constant* getNullValue(const Type* Ty);
+ static Constant *getNullValue(const Type* Ty);
/// @returns the value for an integer constant of the given type that has all
/// its bits set to true.
/// @brief Get the all ones value
- static Constant* getAllOnesValue(const Type* Ty);
+ static Constant *getAllOnesValue(const Type* Ty);
/// getIntegerValue - Return the value for an integer or pointer constant,
/// or a vector thereof, with the given scalar value.
- static Constant* getIntegerValue(const Type* Ty, const APInt &V);
+ static Constant *getIntegerValue(const Type* Ty, const APInt &V);
+
+ /// removeDeadConstantUsers - If there are any dead constant users dangling
+ /// off of this constant, remove them. This method is useful for clients
+ /// that want to check to see if a global is unused, but don't want to deal
+ /// with potentially dead constants hanging off of the globals.
+ void removeDeadConstantUsers() const;
};
} // End llvm namespace
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index a75aaf72a3..c12b33fae7 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -25,7 +25,7 @@
#include "llvm/OperandTraits.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APFloat.h"
-#include <vector>
+#include "llvm/ADT/ArrayRef.h"
namespace llvm {
@@ -39,8 +39,6 @@ template<class ConstantClass, class TypeClass, class ValType>
struct ConstantCreator;
template<class ConstantClass, class TypeClass>
struct ConvertConstantType;
-template<typename T, unsigned N>
-class SmallVector;
//===----------------------------------------------------------------------===//
/// This is the shared class of boolean and integer constants. This class
@@ -59,6 +57,8 @@ protected:
public:
static ConstantInt *getTrue(LLVMContext &Context);
static ConstantInt *getFalse(LLVMContext &Context);
+ static Constant *getTrue(const Type *Ty);
+ static Constant *getFalse(const Type *Ty);
/// If Ty is a vector type, return a Constant with a splat of the given
/// value. Otherwise return a ConstantInt for the given value.
@@ -266,8 +266,8 @@ public:
inline const APFloat& getValueAPF() const { return Val; }
/// isNullValue - Return true if this is the value that would be returned by
- /// getNullValue. Don't depend on == for doubles to tell us it's zero, it
- /// considers -0.0 to be null as well as 0.0. :(
+ /// getNullValue. For ConstantFP, this is +0.0, but not -0.0. To handle the
+ /// two the same, use isZero().
virtual bool isNullValue() const;
/// isNegativeZeroValue - Return true if the value is what would be returned
@@ -405,7 +405,8 @@ public:
};
template <>
-struct OperandTraits<ConstantArray> : public VariadicOperandTraits<> {
+struct OperandTraits<ConstantArray> :
+ public VariadicOperandTraits<ConstantArray> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantArray, Constant)
@@ -426,6 +427,8 @@ public:
const std::vector<Constant*> &V, bool Packed);
static Constant *get(LLVMContext &Context,
Constant *const *Vals, unsigned NumVals, bool Packed);
+ static Constant *get(LLVMContext &Context, bool Packed,
+ Constant * Val, ...) END_WITH_NULL;
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@@ -454,7 +457,8 @@ public:
};
template <>
-struct OperandTraits<ConstantStruct> : public VariadicOperandTraits<> {
+struct OperandTraits<ConstantStruct> :
+ public VariadicOperandTraits<ConstantStruct> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant)
@@ -471,9 +475,9 @@ protected:
ConstantVector(const VectorType *T, const std::vector<Constant*> &Val);
public:
// ConstantVector accessors
+ static Constant *get(ArrayRef<Constant*> V);
+ // FIXME: Eliminate this constructor form.
static Constant *get(const VectorType *T, const std::vector<Constant*> &V);
- static Constant *get(const std::vector<Constant*> &V);
- static Constant *get(Constant *const *Vals, unsigned NumVals);
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@@ -498,7 +502,7 @@ public:
/// getSplatValue - If this is a splat constant, meaning that all of the
/// elements have the same value, return that value. Otherwise return NULL.
- Constant *getSplatValue();
+ Constant *getSplatValue() const;
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
@@ -511,7 +515,8 @@ public:
};
template <>
-struct OperandTraits<ConstantVector> : public VariadicOperandTraits<> {
+struct OperandTraits<ConstantVector> :
+ public VariadicOperandTraits<ConstantVector> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantVector, Constant)
@@ -592,11 +597,13 @@ public:
};
template <>
-struct OperandTraits<BlockAddress> : public FixedNumOperandTraits<2> {
+struct OperandTraits<BlockAddress> :
+ public FixedNumOperandTraits<BlockAddress, 2> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Value)
+
//===----------------------------------------------------------------------===//
/// ConstantExpr - a constant value that is initialized with an expression using
/// other constant values.
@@ -625,11 +632,10 @@ protected:
Constant *C2);
static Constant *getSelectTy(const Type *Ty,
Constant *C1, Constant *C2, Constant *C3);
+ template<typename IndexTy>
static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
- Value* const *Idxs, unsigned NumIdxs);
- static Constant *getInBoundsGetElementPtrTy(const Type *Ty, Constant *C,
- Value* const *Idxs,
- unsigned NumIdxs);
+ IndexTy const *Idxs, unsigned NumIdxs,
+ bool InBounds);
static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
Constant *Idx);
static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
@@ -641,6 +647,10 @@ protected:
static Constant *getInsertValueTy(const Type *Ty, Constant *Agg,
Constant *Val,
const unsigned *Idxs, unsigned NumIdxs);
+ template<typename IndexTy>
+ static Constant *getGetElementPtrImpl(Constant *C,
+ IndexTy const *IdxList,
+ unsigned NumIdx, bool InBounds);
public:
// Static methods to construct a ConstantExpr of different kinds. Note that
@@ -650,35 +660,38 @@ public:
/// getAlignOf constant expr - computes the alignment of a type in a target
/// independent way (Note: the return type is an i64).
- static Constant *getAlignOf(const Type* Ty);
+ static Constant *getAlignOf(const Type *Ty);
/// getSizeOf constant expr - computes the (alloc) size of a type (in
/// address-units, not bits) in a target independent way (Note: the return
/// type is an i64).
///
- static Constant *getSizeOf(const Type* Ty);
+ static Constant *getSizeOf(const Type *Ty);
/// getOffsetOf constant expr - computes the offset of a struct field in a
/// target independent way (Note: the return type is an i64).
///
- static Constant *getOffsetOf(const StructType* STy, unsigned FieldNo);
+ static Constant *getOffsetOf(const StructType *STy, unsigned FieldNo);
/// getOffsetOf constant expr - This is a generalized form of getOffsetOf,
/// which supports any aggregate type, and any Constant index.
///
- static Constant *getOffsetOf(const Type* Ty, Constant *FieldNo);
+ static Constant *getOffsetOf(const Type *Ty, Constant *FieldNo);
- static Constant *getNeg(Constant *C);
+ static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false);
static Constant *getFNeg(Constant *C);
static Constant *getNot(Constant *C);
- static Constant *getAdd(Constant *C1, Constant *C2);
+ static Constant *getAdd(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
static Constant *getFAdd(Constant *C1, Constant *C2);
- static Constant *getSub(Constant *C1, Constant *C2);
+ static Constant *getSub(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
static Constant *getFSub(Constant *C1, Constant *C2);
- static Constant *getMul(Constant *C1, Constant *C2);
+ static Constant *getMul(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
static Constant *getFMul(Constant *C1, Constant *C2);
- static Constant *getUDiv(Constant *C1, Constant *C2);
- static Constant *getSDiv(Constant *C1, Constant *C2);
+ static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false);
+ static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getFDiv(Constant *C1, Constant *C2);
static Constant *getURem(Constant *C1, Constant *C2);
static Constant *getSRem(Constant *C1, Constant *C2);
@@ -686,9 +699,10 @@ public:
static Constant *getAnd(Constant *C1, Constant *C2);
static Constant *getOr(Constant *C1, Constant *C2);
static Constant *getXor(Constant *C1, Constant *C2);
- static Constant *getShl(Constant *C1, Constant *C2);
- static Constant *getLShr(Constant *C1, Constant *C2);
- static Constant *getAShr(Constant *C1, Constant *C2);
+ static Constant *getShl(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
+ static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false);
+ static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getTrunc (Constant *C, const Type *Ty);
static Constant *getSExt (Constant *C, const Type *Ty);
static Constant *getZExt (Constant *C, const Type *Ty);
@@ -702,15 +716,44 @@ public:
static Constant *getIntToPtr(Constant *C, const Type *Ty);
static Constant *getBitCast (Constant *C, const Type *Ty);
- static Constant *getNSWNeg(Constant *C);
- static Constant *getNUWNeg(Constant *C);
- static Constant *getNSWAdd(Constant *C1, Constant *C2);
- static Constant *getNUWAdd(Constant *C1, Constant *C2);
- static Constant *getNSWSub(Constant *C1, Constant *C2);
- static Constant *getNUWSub(Constant *C1, Constant *C2);
- static Constant *getNSWMul(Constant *C1, Constant *C2);
- static Constant *getNUWMul(Constant *C1, Constant *C2);
- static Constant *getExactSDiv(Constant *C1, Constant *C2);
+ static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
+ static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
+ static Constant *getNSWAdd(Constant *C1, Constant *C2) {
+ return getAdd(C1, C2, false, true);
+ }
+ static Constant *getNUWAdd(Constant *C1, Constant *C2) {
+ return getAdd(C1, C2, true, false);
+ }
+ static Constant *getNSWSub(Constant *C1, Constant *C2) {
+ return getSub(C1, C2, false, true);
+ }
+ static Constant *getNUWSub(Constant *C1, Constant *C2) {
+ return getSub(C1, C2, true, false);
+ }
+ static Constant *getNSWMul(Constant *C1, Constant *C2) {
+ return getMul(C1, C2, false, true);
+ }
+ static Constant *getNUWMul(Constant *C1, Constant *C2) {
+ return getMul(C1, C2, true, false);
+ }
+ static Constant *getNSWShl(Constant *C1, Constant *C2) {
+ return getShl(C1, C2, false, true);
+ }
+ static Constant *getNUWShl(Constant *C1, Constant *C2) {
+ return getShl(C1, C2, true, false);
+ }
+ static Constant *getExactSDiv(Constant *C1, Constant *C2) {
+ return getSDiv(C1, C2, true);
+ }
+ static Constant *getExactUDiv(Constant *C1, Constant *C2) {
+ return getUDiv(C1, C2, true);
+ }
+ static Constant *getExactAShr(Constant *C1, Constant *C2) {
+ return getAShr(C1, C2, true);
+ }
+ static Constant *getExactLShr(Constant *C1, Constant *C2) {
+ return getLShr(C1, C2, true);
+ }
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@@ -802,18 +845,24 @@ public:
/// all elements must be Constant's.
///
static Constant *getGetElementPtr(Constant *C,
- Constant *const *IdxList, unsigned NumIdx);
+ Constant *const *IdxList, unsigned NumIdx,
+ bool InBounds = false);
static Constant *getGetElementPtr(Constant *C,
- Value* const *IdxList, unsigned NumIdx);
+ Value *const *IdxList, unsigned NumIdx,
+ bool InBounds = false);
/// Create an "inbounds" getelementptr. See the documentation for the
/// "inbounds" flag in LangRef.html for details.
static Constant *getInBoundsGetElementPtr(Constant *C,
Constant *const *IdxList,
- unsigned NumIdx);
+ unsigned NumIdx) {
+ return getGetElementPtr(C, IdxList, NumIdx, true);
+ }
static Constant *getInBoundsGetElementPtr(Constant *C,
Value* const *IdxList,
- unsigned NumIdx);
+ unsigned NumIdx) {
+ return getGetElementPtr(C, IdxList, NumIdx, true);
+ }
static Constant *getExtractElement(Constant *Vec, Constant *Idx);
static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
@@ -871,7 +920,8 @@ private:
};
template <>
-struct OperandTraits<ConstantExpr> : public VariadicOperandTraits<1> {
+struct OperandTraits<ConstantExpr> :
+ public VariadicOperandTraits<ConstantExpr, 1> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantExpr, Constant)
diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h
index 721c603314..56d1e3e237 100644
--- a/include/llvm/DerivedTypes.h
+++ b/include/llvm/DerivedTypes.h
@@ -19,7 +19,7 @@
#define LLVM_DERIVED_TYPES_H
#include "llvm/Type.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index 0e51271c6f..dcc9743d69 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -21,8 +21,9 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ValueMap.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/ValueHandle.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
@@ -126,8 +127,8 @@ protected:
virtual char *getMemoryForGV(const GlobalVariable *GV);
// To avoid having libexecutionengine depend on the JIT and interpreter
- // libraries, the JIT and Interpreter set these functions to ctor pointers at
- // startup time if they are linked in.
+ // libraries, the execution engine implementations set these functions to ctor
+ // pointers at startup time if they are linked in.
static ExecutionEngine *(*JITCtor)(
Module *M,
std::string *ErrorStr,
@@ -138,6 +139,16 @@ protected:
StringRef MArch,
StringRef MCPU,
const SmallVectorImpl<std::string>& MAttrs);
+ static ExecutionEngine *(*MCJITCtor)(
+ Module *M,
+ std::string *ErrorStr,
+ JITMemoryManager *JMM,
+ CodeGenOpt::Level OptLevel,
+ bool GVsWithCode,
+ CodeModel::Model CMM,
+ StringRef MArch,
+ StringRef MCPU,
+ const SmallVectorImpl<std::string>& MAttrs);
static ExecutionEngine *(*InterpCtor)(Module *M,
std::string *ErrorStr);
@@ -151,7 +162,9 @@ protected:
typedef void (*EERegisterFn)(void*);
EERegisterFn ExceptionTableRegister;
EERegisterFn ExceptionTableDeregister;
- std::vector<void*> AllExceptionTables;
+ /// This maps functions to their exception tables frames.
+ DenseMap<const Function*, void*> AllExceptionTables;
+
public:
/// lock - This lock protects the ExecutionEngine, JIT, JITResolver and
@@ -400,10 +413,21 @@ public:
/// RegisterTable - Registers the given pointer as an exception table. It
/// uses the ExceptionTableRegister function.
- void RegisterTable(void* res) {
+ void RegisterTable(const Function *fn, void* res) {
if (ExceptionTableRegister) {
ExceptionTableRegister(res);
- AllExceptionTables.push_back(res);
+ AllExceptionTables[fn] = res;
+ }
+ }
+
+ /// DeregisterTable - Deregisters the exception frame previously registered for the given function.
+ void DeregisterTable(const Function *Fn) {
+ if (ExceptionTableDeregister) {
+ DenseMap<const Function*, void*>::iterator frame = AllExceptionTables.find(Fn);
+ if(frame != AllExceptionTables.end()) {
+ ExceptionTableDeregister(frame->second);
+ AllExceptionTables.erase(frame);
+ }
}
}
@@ -447,6 +471,7 @@ private:
std::string MArch;
std::string MCPU;
SmallVector<std::string, 4> MAttrs;
+ bool UseMCJIT;
/// InitEngine - Does the common initialization of default options.
void InitEngine() {
@@ -456,6 +481,7 @@ private:
JMM = NULL;
AllocateGVsWithCode = false;
CMModel = CodeModel::Default;
+ UseMCJIT = false;
}
public:
@@ -526,6 +552,12 @@ public:
return *this;
}
+ /// setUseMCJIT - Set whether the MC-JIT implementation should be used
+ /// (experimental).
+ void setUseMCJIT(bool Value) {
+ UseMCJIT = Value;
+ }
+
/// setMAttrs - Set cpu-specific attributes.
template<typename StringSequence>
EngineBuilder &setMAttrs(const StringSequence &mattrs) {
diff --git a/include/llvm/ExecutionEngine/GenericValue.h b/include/llvm/ExecutionEngine/GenericValue.h
index 1301320c14..a2fed98c15 100644
--- a/include/llvm/ExecutionEngine/GenericValue.h
+++ b/include/llvm/ExecutionEngine/GenericValue.h
@@ -16,7 +16,7 @@
#define GENERIC_VALUE_H
#include "llvm/ADT/APInt.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h
index 1c060793d6..abc063b070 100644
--- a/include/llvm/ExecutionEngine/JITEventListener.h
+++ b/include/llvm/ExecutionEngine/JITEventListener.h
@@ -15,7 +15,7 @@
#ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
#define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/DebugLoc.h"
#include <vector>
diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h
index 78a77ecd32..3841418016 100644
--- a/include/llvm/ExecutionEngine/JITMemoryManager.h
+++ b/include/llvm/ExecutionEngine/JITMemoryManager.h
@@ -10,7 +10,7 @@
#ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
#define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
diff --git a/include/llvm/ExecutionEngine/MCJIT.h b/include/llvm/ExecutionEngine/MCJIT.h
new file mode 100644
index 0000000000..f956a5029b
--- /dev/null
+++ b/include/llvm/ExecutionEngine/MCJIT.h
@@ -0,0 +1,38 @@
+//===-- MCJIT.h - MC-Based Just-In-Time Execution Engine --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file forces the MCJIT to link in on certain operating systems.
+// (Windows).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_MCJIT_H
+#define LLVM_EXECUTION_ENGINE_MCJIT_H
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include <cstdlib>
+
+extern "C" void LLVMLinkInMCJIT();
+
+namespace {
+ struct ForceMCJITLinking {
+ ForceMCJITLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ LLVMLinkInMCJIT();
+ }
+ } ForceMCJITLinking;
+}
+
+#endif
diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h
index 9867c518c8..f4af5b1202 100644
--- a/include/llvm/GlobalAlias.h
+++ b/include/llvm/GlobalAlias.h
@@ -89,7 +89,8 @@ public:
};
template <>
-struct OperandTraits<GlobalAlias> : public FixedNumOperandTraits<1> {
+struct OperandTraits<GlobalAlias> :
+ public FixedNumOperandTraits<GlobalAlias, 1> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Value)
diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h
index 62e84f8335..b184b8e449 100644
--- a/include/llvm/GlobalValue.h
+++ b/include/llvm/GlobalValue.h
@@ -60,7 +60,8 @@ protected:
GlobalValue(const Type *ty, ValueTy vty, Use *Ops, unsigned NumOps,
LinkageTypes linkage, const Twine &Name)
: Constant(ty, vty, Ops, NumOps), Parent(0),
- Linkage(linkage), Visibility(DefaultVisibility), Alignment(0) {
+ Linkage(linkage), Visibility(DefaultVisibility), Alignment(0),
+ UnnamedAddr(0) {
setName(Name);
}
@@ -70,6 +71,7 @@ protected:
LinkageTypes Linkage : 5; // The linkage of this global
unsigned Visibility : 2; // The visibility style of this global
unsigned Alignment : 16; // Alignment of this symbol, must be power of two
+ unsigned UnnamedAddr : 1; // This value's address is not significant
std::string Section; // Section to emit this into, empty mean default
public:
~GlobalValue() {
@@ -81,6 +83,9 @@ public:
}
void setAlignment(unsigned Align);
+ bool hasUnnamedAddr() const { return UnnamedAddr; }
+ void setUnnamedAddr(bool Val) { UnnamedAddr = Val; }
+
VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); }
bool hasDefaultVisibility() const { return Visibility == DefaultVisibility; }
bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
@@ -173,7 +178,9 @@ public:
}
/// isWeakForLinker - Whether the definition of this global may be replaced at
- /// link time.
+ /// link time. NB: Using this method outside of the code generators is almost
+ /// always a mistake: when working at the IR level use mayBeOverridden instead
+ /// as it knows about ODR semantics.
static bool isWeakForLinker(LinkageTypes Linkage) {
return Linkage == AvailableExternallyLinkage ||
Linkage == WeakAnyLinkage ||
@@ -275,12 +282,6 @@ public:
inline Module *getParent() { return Parent; }
inline const Module *getParent() const { return Parent; }
- /// removeDeadConstantUsers - If there are any dead constant users dangling
- /// off of this global value, remove them. This method is useful for clients
- /// that want to check to see if a global is unused, but don't want to deal
- /// with potentially dead constants hanging off of the globals.
- void removeDeadConstantUsers() const;
-
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const GlobalValue *) { return true; }
static inline bool classof(const Value *V) {
diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h
index 597583b2ce..1769c665d0 100644
--- a/include/llvm/GlobalVariable.h
+++ b/include/llvm/GlobalVariable.h
@@ -169,7 +169,8 @@ public:
};
template <>
-struct OperandTraits<GlobalVariable> : public OptionalOperandTraits<> {
+struct OperandTraits<GlobalVariable> :
+ public OptionalOperandTraits<GlobalVariable> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalVariable, Value)
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 50443e2f3f..2758b299ec 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -19,19 +19,19 @@ namespace llvm {
class PassRegistry;
-/// initializeCore - Initialize all passes linked into the
+/// initializeCore - Initialize all passes linked into the
/// TransformUtils library.
void initializeCore(PassRegistry&);
-/// initializeTransformUtils - Initialize all passes linked into the
+/// initializeTransformUtils - Initialize all passes linked into the
/// TransformUtils library.
void initializeTransformUtils(PassRegistry&);
-/// initializeScalarOpts - Initialize all passes linked into the
+/// initializeScalarOpts - Initialize all passes linked into the
/// ScalarOpts library.
void initializeScalarOpts(PassRegistry&);
-/// initializeInstCombine - Initialize all passes linked into the
+/// initializeInstCombine - Initialize all passes linked into the
/// ScalarOpts library.
void initializeInstCombine(PassRegistry&);
@@ -91,11 +91,14 @@ void initializeDomPrinterPass(PassRegistry&);
void initializeDomViewerPass(PassRegistry&);
void initializeDominanceFrontierPass(PassRegistry&);
void initializeDominatorTreePass(PassRegistry&);
+void initializeEdgeBundlesPass(PassRegistry&);
void initializeEdgeProfilerPass(PassRegistry&);
+void initializePathProfilerPass(PassRegistry&);
+void initializeEarlyCSEPass(PassRegistry&);
+void initializeExpandISelPseudosPass(PassRegistry&);
void initializeFindUsedTypesPass(PassRegistry&);
void initializeFunctionAttrsPass(PassRegistry&);
void initializeGCModuleInfoPass(PassRegistry&);
-void initializeGEPSplitterPass(PassRegistry&);
void initializeGVNPass(PassRegistry&);
void initializeGlobalDCEPass(PassRegistry&);
void initializeGlobalOptPass(PassRegistry&);
@@ -116,21 +119,24 @@ void initializeLICMPass(PassRegistry&);
void initializeLazyValueInfoPass(PassRegistry&);
void initializeLibCallAliasAnalysisPass(PassRegistry&);
void initializeLintPass(PassRegistry&);
+void initializeLiveDebugVariablesPass(PassRegistry&);
void initializeLiveIntervalsPass(PassRegistry&);
void initializeLiveStacksPass(PassRegistry&);
-void initializeLiveValuesPass(PassRegistry&);
void initializeLiveVariablesPass(PassRegistry&);
void initializeLoaderPassPass(PassRegistry&);
+void initializePathProfileLoaderPassPass(PassRegistry&);
void initializeLoopDeletionPass(PassRegistry&);
void initializeLoopDependenceAnalysisPass(PassRegistry&);
void initializeLoopExtractorPass(PassRegistry&);
void initializeLoopInfoPass(PassRegistry&);
+void initializeLoopInstSimplifyPass(PassRegistry&);
void initializeLoopRotatePass(PassRegistry&);
void initializeLoopSimplifyPass(PassRegistry&);
void initializeLoopSplitterPass(PassRegistry&);
void initializeLoopStrengthReducePass(PassRegistry&);
void initializeLoopUnrollPass(PassRegistry&);
void initializeLoopUnswitchPass(PassRegistry&);
+void initializeLoopIdiomRecognizePass(PassRegistry&);
void initializeLowerAtomicPass(PassRegistry&);
void initializeLowerIntrinsicsPass(PassRegistry&);
void initializeLowerInvokePass(PassRegistry&);
@@ -140,6 +146,7 @@ void initializeMachineCSEPass(PassRegistry&);
void initializeMachineDominatorTreePass(PassRegistry&);
void initializeMachineLICMPass(PassRegistry&);
void initializeMachineLoopInfoPass(PassRegistry&);
+void initializeMachineLoopRangesPass(PassRegistry&);
void initializeMachineModuleInfoPass(PassRegistry&);
void initializeMachineSinkingPass(PassRegistry&);
void initializeMachineVerifierPassPass(PassRegistry&);
@@ -150,11 +157,11 @@ void initializeMergeFunctionsPass(PassRegistry&);
void initializeModuleDebugInfoPrinterPass(PassRegistry&);
void initializeNoAAPass(PassRegistry&);
void initializeNoProfileInfoPass(PassRegistry&);
+void initializeNoPathProfileInfoPass(PassRegistry&);
void initializeOptimalEdgeProfilerPass(PassRegistry&);
void initializeOptimizePHIsPass(PassRegistry&);
void initializePEIPass(PassRegistry&);
void initializePHIEliminationPass(PassRegistry&);
-void initializePartSpecPass(PassRegistry&);
void initializePartialInlinerPass(PassRegistry&);
void initializePeepholeOptimizerPass(PassRegistry&);
void initializePostDomOnlyPrinterPass(PassRegistry&);
@@ -171,6 +178,8 @@ void initializePrintModulePassPass(PassRegistry&);
void initializeProcessImplicitDefsPass(PassRegistry&);
void initializeProfileEstimatorPassPass(PassRegistry&);
void initializeProfileInfoAnalysisGroup(PassRegistry&);
+void initializePathProfileInfoAnalysisGroup(PassRegistry&);
+void initializePathProfileVerifierPass(PassRegistry&);
void initializeProfileVerifierPassPass(PassRegistry&);
void initializePromotePassPass(PassRegistry&);
void initializePruneEHPass(PassRegistry&);
@@ -186,16 +195,17 @@ void initializeRegisterCoalescerAnalysisGroup(PassRegistry&);
void initializeRenderMachineFunctionPass(PassRegistry&);
void initializeSCCPPass(PassRegistry&);
void initializeSRETPromotionPass(PassRegistry&);
-void initializeSROAPass(PassRegistry&);
+void initializeSROA_DTPass(PassRegistry&);
+void initializeSROA_SSAUpPass(PassRegistry&);
void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&);
void initializeScalarEvolutionPass(PassRegistry&);
void initializeSimpleInlinerPass(PassRegistry&);
void initializeSimpleRegisterCoalescingPass(PassRegistry&);
-void initializeSimplifyHalfPowrLibCallsPass(PassRegistry&);
void initializeSimplifyLibCallsPass(PassRegistry&);
void initializeSingleLoopExtractorPass(PassRegistry&);
void initializeSinkingPass(PassRegistry&);
void initializeSlotIndexesPass(PassRegistry&);
+void initializeSpillPlacementPass(PassRegistry&);
void initializeStackProtectorPass(PassRegistry&);
void initializeStackSlotColoringPass(PassRegistry&);
void initializeStripDeadDebugInfoPass(PassRegistry&);
@@ -207,6 +217,7 @@ void initializeStrongPHIEliminationPass(PassRegistry&);
void initializeTailCallElimPass(PassRegistry&);
void initializeTailDupPass(PassRegistry&);
void initializeTargetDataPass(PassRegistry&);
+void initializeTargetLibraryInfoPass(PassRegistry&);
void initializeTwoAddressInstructionPassPass(PassRegistry&);
void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
void initializeUnifyFunctionExitNodesPass(PassRegistry&);
@@ -214,6 +225,7 @@ void initializeUnreachableBlockElimPass(PassRegistry&);
void initializeUnreachableMachineBlockElimPass(PassRegistry&);
void initializeVerifierPass(PassRegistry&);
void initializeVirtRegMapPass(PassRegistry&);
+void initializeInstSimplifierPass(PassRegistry&);
}
diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h
index 4ca012e974..ed8f0f7f61 100644
--- a/include/llvm/InlineAsm.h
+++ b/include/llvm/InlineAsm.h
@@ -190,8 +190,15 @@ public:
Op_InputChain = 0,
Op_AsmString = 1,
Op_MDNode = 2,
- Op_IsAlignStack = 3,
+ Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack
Op_FirstOperand = 4,
+
+ MIOp_AsmString = 0,
+ MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack
+ MIOp_FirstOperand = 2,
+
+ Extra_HasSideEffects = 1,
+ Extra_IsAlignStack = 2,
Kind_RegUse = 1,
Kind_RegDef = 2,
diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h
index 6715416afa..a166956e1a 100644
--- a/include/llvm/InstrTypes.h
+++ b/include/llvm/InstrTypes.h
@@ -128,7 +128,8 @@ public:
};
template <>
-struct OperandTraits<UnaryInstruction> : public FixedNumOperandTraits<1> {
+struct OperandTraits<UnaryInstruction> :
+ public FixedNumOperandTraits<UnaryInstruction, 1> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value)
@@ -193,154 +194,93 @@ public:
}
#include "llvm/Instruction.def"
-
- /// CreateNSWAdd - Create an Add operator with the NSW flag set.
- ///
- static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateAdd(V1, V2, Name);
+ static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name = "") {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name);
BO->setHasNoSignedWrap(true);
return BO;
}
- static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateAdd(V1, V2, Name, BB);
+ static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, BasicBlock *BB) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
BO->setHasNoSignedWrap(true);
return BO;
}
- static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateAdd(V1, V2, Name, I);
+ static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, Instruction *I) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
BO->setHasNoSignedWrap(true);
return BO;
}
-
- /// CreateNUWAdd - Create an Add operator with the NUW flag set.
- ///
- static BinaryOperator *CreateNUWAdd(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateAdd(V1, V2, Name);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNUWAdd(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateAdd(V1, V2, Name, BB);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNUWAdd(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateAdd(V1, V2, Name, I);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
-
- /// CreateNSWSub - Create an Sub operator with the NSW flag set.
- ///
- static BinaryOperator *CreateNSWSub(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateSub(V1, V2, Name);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNSWSub(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateSub(V1, V2, Name, BB);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNSWSub(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateSub(V1, V2, Name, I);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
-
- /// CreateNUWSub - Create an Sub operator with the NUW flag set.
- ///
- static BinaryOperator *CreateNUWSub(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateSub(V1, V2, Name);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNUWSub(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateSub(V1, V2, Name, BB);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNUWSub(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateSub(V1, V2, Name, I);
- BO->setHasNoUnsignedWrap(true);
- return BO;
- }
-
- /// CreateNSWMul - Create a Mul operator with the NSW flag set.
- ///
- static BinaryOperator *CreateNSWMul(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateMul(V1, V2, Name);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNSWMul(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateMul(V1, V2, Name, BB);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
- static BinaryOperator *CreateNSWMul(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateMul(V1, V2, Name, I);
- BO->setHasNoSignedWrap(true);
- return BO;
- }
-
- /// CreateNUWMul - Create a Mul operator with the NUW flag set.
- ///
- static BinaryOperator *CreateNUWMul(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateMul(V1, V2, Name);
+
+ static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name = "") {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name);
BO->setHasNoUnsignedWrap(true);
return BO;
}
- static BinaryOperator *CreateNUWMul(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateMul(V1, V2, Name, BB);
+ static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, BasicBlock *BB) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
BO->setHasNoUnsignedWrap(true);
return BO;
}
- static BinaryOperator *CreateNUWMul(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateMul(V1, V2, Name, I);
+ static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, Instruction *I) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
BO->setHasNoUnsignedWrap(true);
return BO;
}
-
- /// CreateExactSDiv - Create an SDiv operator with the exact flag set.
- ///
- static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
- const Twine &Name = "") {
- BinaryOperator *BO = CreateSDiv(V1, V2, Name);
+
+ static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name = "") {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name);
BO->setIsExact(true);
return BO;
}
- static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
- const Twine &Name, BasicBlock *BB) {
- BinaryOperator *BO = CreateSDiv(V1, V2, Name, BB);
+ static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, BasicBlock *BB) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
BO->setIsExact(true);
return BO;
}
- static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
- const Twine &Name, Instruction *I) {
- BinaryOperator *BO = CreateSDiv(V1, V2, Name, I);
+ static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, Instruction *I) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
BO->setIsExact(true);
return BO;
}
-
+
+#define DEFINE_HELPERS(OPC, NUWNSWEXACT) \
+ static BinaryOperator *Create ## NUWNSWEXACT ## OPC \
+ (Value *V1, Value *V2, const Twine &Name = "") { \
+ return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name); \
+ } \
+ static BinaryOperator *Create ## NUWNSWEXACT ## OPC \
+ (Value *V1, Value *V2, const Twine &Name, BasicBlock *BB) { \
+ return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, BB); \
+ } \
+ static BinaryOperator *Create ## NUWNSWEXACT ## OPC \
+ (Value *V1, Value *V2, const Twine &Name, Instruction *I) { \
+ return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, I); \
+ }
+
+ DEFINE_HELPERS(Add, NSW) // CreateNSWAdd
+ DEFINE_HELPERS(Add, NUW) // CreateNUWAdd
+ DEFINE_HELPERS(Sub, NSW) // CreateNSWSub
+ DEFINE_HELPERS(Sub, NUW) // CreateNUWSub
+ DEFINE_HELPERS(Mul, NSW) // CreateNSWMul
+ DEFINE_HELPERS(Mul, NUW) // CreateNUWMul
+ DEFINE_HELPERS(Shl, NSW) // CreateNSWShl
+ DEFINE_HELPERS(Shl, NUW) // CreateNUWShl
+
+ DEFINE_HELPERS(SDiv, Exact) // CreateExactSDiv
+ DEFINE_HELPERS(UDiv, Exact) // CreateExactUDiv
+ DEFINE_HELPERS(AShr, Exact) // CreateExactAShr
+ DEFINE_HELPERS(LShr, Exact) // CreateExactLShr
+
+#undef DEFINE_HELPERS
+
/// Helper functions to construct and inspect unary operations (NEG and NOT)
/// via binary operators SUB and XOR:
///
@@ -432,7 +372,8 @@ public:
};
template <>
-struct OperandTraits<BinaryOperator> : public FixedNumOperandTraits<2> {
+struct OperandTraits<BinaryOperator> :
+ public FixedNumOperandTraits<BinaryOperator, 2> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value)
@@ -824,11 +765,11 @@ public:
/// This is just a convenience that dispatches to the subclasses.
/// @brief Determine if this CmpInst is commutative.
- bool isCommutative();
+ bool isCommutative() const;
/// This is just a convenience that dispatches to the subclasses.
/// @brief Determine if this is an equals/not equals predicate.
- bool isEquality();
+ bool isEquality() const;
/// @returns true if the comparison is signed, false otherwise.
/// @brief Determine if this instruction is using a signed comparison.
@@ -903,7 +844,7 @@ private:
// FIXME: these are redundant if CmpInst < BinaryOperator
template <>
-struct OperandTraits<CmpInst> : public FixedNumOperandTraits<2> {
+struct OperandTraits<CmpInst> : public FixedNumOperandTraits<CmpInst, 2> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value)
diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h
index 88f5ce1b26..89bb9fdf42 100644
--- a/include/llvm/Instruction.h
+++ b/include/llvm/Instruction.h
@@ -200,11 +200,10 @@ public:
///
/// Associative operators satisfy: x op (y op z) === (x op y) op z
///
- /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative, when
- /// not applied to floating point types.
+ /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative.
///
- bool isAssociative() const { return isAssociative(getOpcode(), getType()); }
- static bool isAssociative(unsigned op, const Type *Ty);
+ bool isAssociative() const { return isAssociative(getOpcode()); }
+ static bool isAssociative(unsigned op);
/// isCommutative - Return true if the instruction is commutative:
///
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index 91f7729a11..17ff763c52 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -29,7 +29,6 @@ class ConstantInt;
class ConstantRange;
class APInt;
class LLVMContext;
-class DominatorTree;
//===----------------------------------------------------------------------===//
// AllocaInst Class
@@ -263,7 +262,7 @@ private:
};
template <>
-struct OperandTraits<StoreInst> : public FixedNumOperandTraits<2> {
+struct OperandTraits<StoreInst> : public FixedNumOperandTraits<StoreInst, 2> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
@@ -459,6 +458,9 @@ public:
Value* const *Idx, unsigned NumIdx);
static const Type *getIndexedType(const Type *Ptr,
+ Constant* const *Idx, unsigned NumIdx);
+
+ static const Type *getIndexedType(const Type *Ptr,
uint64_t const *Idx, unsigned NumIdx);
static const Type *getIndexedType(const Type *Ptr, Value *Idx);
@@ -525,7 +527,8 @@ public:
};
template <>
-struct OperandTraits<GetElementPtrInst> : public VariadicOperandTraits<1> {
+struct OperandTraits<GetElementPtrInst> :
+ public VariadicOperandTraits<GetElementPtrInst, 1> {
};
template<typename RandomAccessIterator>
@@ -1088,7 +1091,7 @@ private:
};
template <>
-struct OperandTraits<CallInst> : public VariadicOperandTraits<1> {
+struct OperandTraits<CallInst> : public VariadicOperandTraits<CallInst, 1> {
};
template<typename RandomAccessIterator>
@@ -1196,7 +1199,7 @@ public:
};
template <>
-struct OperandTraits<SelectInst> : public FixedNumOperandTraits<3> {
+struct OperandTraits<SelectInst> : public FixedNumOperandTraits<SelectInst, 3> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value)
@@ -1293,7 +1296,8 @@ public:
};
template <>
-struct OperandTraits<ExtractElementInst> : public FixedNumOperandTraits<2> {
+struct OperandTraits<ExtractElementInst> :
+ public FixedNumOperandTraits<ExtractElementInst, 2> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementInst, Value)
@@ -1351,7 +1355,8 @@ public:
};
template <>
-struct OperandTraits<InsertElementInst> : public FixedNumOperandTraits<3> {
+struct OperandTraits<InsertElementInst> :
+ public FixedNumOperandTraits<InsertElementInst, 3> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
@@ -1408,7 +1413,8 @@ public:
};
template <>
-struct OperandTraits<ShuffleVectorInst> : public FixedNumOperandTraits<3> {
+struct OperandTraits<ShuffleVectorInst> :
+ public FixedNumOperandTraits<ShuffleVectorInst, 3> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorInst, Value)
@@ -1451,8 +1457,7 @@ class ExtractValueInst : public UnaryInstruction {
/// getIndexedType - Returns the type of the element that would be extracted
/// with an extractvalue instruction with the specified parameters.
///
- /// Null is returned if the indices are invalid for the specified
- /// pointer type.
+ /// Null is returned if the indices are invalid for the specified type.
///
static const Type *getIndexedType(const Type *Agg,
const unsigned *Idx, unsigned NumIdx);
@@ -1535,8 +1540,7 @@ public:
/// getIndexedType - Returns the type of the element that would be extracted
/// with an extractvalue instruction with the specified parameters.
///
- /// Null is returned if the indices are invalid for the specified
- /// pointer type.
+ /// Null is returned if the indices are invalid for the specified type.
///
template<typename RandomAccessIterator>
static const Type *getIndexedType(const Type *Ptr,
@@ -1754,7 +1758,8 @@ public:
};
template <>
-struct OperandTraits<InsertValueInst> : public FixedNumOperandTraits<2> {
+struct OperandTraits<InsertValueInst> :
+ public FixedNumOperandTraits<InsertValueInst, 2> {
};
template<typename RandomAccessIterator>
@@ -1946,13 +1951,7 @@ public:
/// hasConstantValue - If the specified PHI node always merges together the
/// same value, return the value, otherwise return null.
- ///
- /// If the PHI has undef operands, but all the rest of the operands are
- /// some unique value, return that value if it can be proved that the
- /// value dominates the PHI. If DT is null, use a conservative check,
- /// otherwise use DT to test for dominance.
- ///
- Value *hasConstantValue(const DominatorTree *DT = 0) const;
+ Value *hasConstantValue() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const PHINode *) { return true; }
@@ -2041,7 +2040,7 @@ public:
};
template <>
-struct OperandTraits<ReturnInst> : public VariadicOperandTraits<> {
+struct OperandTraits<ReturnInst> : public VariadicOperandTraits<ReturnInst> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ReturnInst, Value)
@@ -2077,22 +2076,20 @@ protected:
virtual BranchInst *clone_impl() const;
public:
static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = 0) {
- return new(1, true) BranchInst(IfTrue, InsertBefore);
+ return new(1) BranchInst(IfTrue, InsertBefore);
}
static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse,
Value *Cond, Instruction *InsertBefore = 0) {
return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertBefore);
}
static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) {
- return new(1, true) BranchInst(IfTrue, InsertAtEnd);
+ return new(1) BranchInst(IfTrue, InsertAtEnd);
}
static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse,
Value *Cond, BasicBlock *InsertAtEnd) {
return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertAtEnd);
}
- ~BranchInst();
-
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2109,19 +2106,6 @@ public:
Op<-3>() = V;
}
- // setUnconditionalDest - Change the current branch to an unconditional branch
- // targeting the specified block.
- // FIXME: Eliminate this ugly method.
- void setUnconditionalDest(BasicBlock *Dest) {
- Op<-1>() = (Value*)Dest;
- if (isConditional()) { // Convert this to an uncond branch.
- Op<-2>() = 0;
- Op<-3>() = 0;
- NumOperands = 1;
- OperandList = op_begin();
- }
- }
-
unsigned getNumSuccessors() const { return 1+isConditional(); }
BasicBlock *getSuccessor(unsigned i) const {
@@ -2149,7 +2133,8 @@ private:
};
template <>
-struct OperandTraits<BranchInst> : public VariadicOperandTraits<1> {};
+struct OperandTraits<BranchInst> : public VariadicOperandTraits<BranchInst, 1> {
+};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value)
@@ -2168,7 +2153,7 @@ class SwitchInst : public TerminatorInst {
// Operand[2n ] = Value to match
// Operand[2n+1] = BasicBlock to go to on match
SwitchInst(const SwitchInst &SI);
- void init(Value *Value, BasicBlock *Default, unsigned NumCases);
+ void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
void resizeOperands(unsigned No);
// allocate space for exactly zero operands
void *operator new(size_t s) {
@@ -2262,7 +2247,8 @@ public:
/// removeCase - This method removes the specified successor from the switch
/// instruction. Note that this cannot be used to remove the default
- /// destination (successor #0).
+ /// destination (successor #0). Also note that this operation may reorder the
+ /// remaining cases at index idx and above.
///
void removeCase(unsigned idx);
@@ -2640,7 +2626,7 @@ private:
};
template <>
-struct OperandTraits<InvokeInst> : public VariadicOperandTraits<3> {
+struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> {
};
template<typename RandomAccessIterator>
diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h
index a17fa9cc5b..74c30fbddd 100644
--- a/include/llvm/IntrinsicInst.h
+++ b/include/llvm/IntrinsicInst.h
@@ -55,7 +55,7 @@ namespace llvm {
return isa<CallInst>(V) && classof(cast<CallInst>(V));
}
};
-
+
/// DbgInfoIntrinsic - This is the common base class for debug info intrinsics
///
class DbgInfoIntrinsic : public IntrinsicInst {
@@ -139,6 +139,10 @@ namespace llvm {
return !getVolatileCst()->isZero();
}
+ unsigned getAddressSpace() const {
+ return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
+ }
+
/// getDest - This is just like getRawDest, but it strips off any cast
/// instructions that feed it, giving the original input. The returned
/// value is guaranteed to be a pointer.
@@ -297,29 +301,6 @@ namespace llvm {
}
};
- /// MemoryUseIntrinsic - This is the common base class for the memory use
- /// marker intrinsics.
- ///
- class MemoryUseIntrinsic : public IntrinsicInst {
- public:
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const MemoryUseIntrinsic *) { return true; }
- static inline bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::lifetime_start:
- case Intrinsic::lifetime_end:
- case Intrinsic::invariant_start:
- case Intrinsic::invariant_end:
- return true;
- default: return false;
- }
- }
- static inline bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
}
#endif
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td
index 347541f71f..ba66555c4e 100644
--- a/include/llvm/Intrinsics.td
+++ b/include/llvm/Intrinsics.td
@@ -259,7 +259,7 @@ def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>;
// Internal interface for object size checking
def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i1_ty],
- [IntrReadArgMem]>,
+ [IntrNoMem]>,
GCCBuiltin<"__builtin_object_size">;
//===-------------------- Bit Manipulation Intrinsics ---------------------===//
@@ -436,7 +436,7 @@ def int_lifetime_end : Intrinsic<[],
[IntrReadWriteArgMem, NoCapture<1>]>;
def int_invariant_start : Intrinsic<[llvm_descriptor_ty],
[llvm_i64_ty, llvm_ptr_ty],
- [IntrReadArgMem, NoCapture<1>]>;
+ [IntrReadWriteArgMem, NoCapture<1>]>;
def int_invariant_end : Intrinsic<[],
[llvm_descriptor_ty, llvm_i64_ty,
llvm_ptr_ty],
@@ -490,3 +490,4 @@ include "llvm/IntrinsicsARM.td"
include "llvm/IntrinsicsCellSPU.td"
include "llvm/IntrinsicsAlpha.td"
include "llvm/IntrinsicsXCore.td"
+include "llvm/IntrinsicsPTX.td"
diff --git a/include/llvm/IntrinsicsARM.td b/include/llvm/IntrinsicsARM.td
index 6c047718e6..823f095dbd 100644
--- a/include/llvm/IntrinsicsARM.td
+++ b/include/llvm/IntrinsicsARM.td
@@ -1,10 +1,10 @@
//===- IntrinsicsARM.td - Defines ARM intrinsics -----------*- tablegen -*-===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file defines all of the ARM-specific intrinsics.
@@ -286,6 +286,12 @@ def int_arm_neon_vcvtfp2fxu : Neon_CvtFPToFx_Intrinsic;
def int_arm_neon_vcvtfxs2fp : Neon_CvtFxToFP_Intrinsic;
def int_arm_neon_vcvtfxu2fp : Neon_CvtFxToFP_Intrinsic;
+// Vector Conversions Between Half-Precision and Single-Precision.
+def int_arm_neon_vcvtfp2hf
+ : Intrinsic<[llvm_v4i16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_arm_neon_vcvthf2fp
+ : Intrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>;
+
// Narrowing Saturating Vector Moves.
def int_arm_neon_vqmovns : Neon_1Arg_Narrow_Intrinsic;
def int_arm_neon_vqmovnu : Neon_1Arg_Narrow_Intrinsic;
diff --git a/include/llvm/IntrinsicsPTX.td b/include/llvm/IntrinsicsPTX.td
new file mode 100644
index 0000000000..ec291e467e
--- /dev/null
+++ b/include/llvm/IntrinsicsPTX.td
@@ -0,0 +1,32 @@
+//===- IntrinsicsPTX.td - Defines PTX intrinsics -----------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the PTX-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "ptx" in {
+ multiclass PTXReadSpecialRegisterIntrinsic {
+ def _r64 : Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
+ def _v4i16 : Intrinsic<[llvm_v4i16_ty], [], [IntrNoMem]>;
+ }
+
+ multiclass PTXReadSpecialSubRegisterIntrinsic {
+ def _x : Intrinsic<[llvm_i16_ty], [], [IntrNoMem]>;
+ def _y : Intrinsic<[llvm_i16_ty], [], [IntrNoMem]>;
+ def _z : Intrinsic<[llvm_i16_ty], [], [IntrNoMem]>;
+ def _w : Intrinsic<[llvm_i16_ty], [], [IntrNoMem]>;
+ }
+}
+
+defm int_ptx_read_tid : PTXReadSpecialRegisterIntrinsic;
+defm int_ptx_read_tid : PTXReadSpecialSubRegisterIntrinsic;
+
+let TargetPrefix = "ptx" in
+ def int_ptx_bar_sync : Intrinsic<[], [llvm_i32_ty], []>;
diff --git a/include/llvm/IntrinsicsXCore.td b/include/llvm/IntrinsicsXCore.td
index a86cda28a5..944120fc8c 100644
--- a/include/llvm/IntrinsicsXCore.td
+++ b/include/llvm/IntrinsicsXCore.td
@@ -11,4 +11,45 @@
let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.".
def int_xcore_bitrev : Intrinsic<[llvm_i32_ty],[llvm_i32_ty],[IntrNoMem]>;
def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>;
+
+ // Resource instructions.
+ def int_xcore_getr : Intrinsic<[llvm_anyptr_ty],[llvm_i32_ty]>;
+ def int_xcore_freer : Intrinsic<[],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_in : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],[NoCapture<0>]>;
+ def int_xcore_int : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_inct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_out : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_outt : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_outct : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_chkct : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_setd : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_setc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_inshr : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_outshr : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_setpt : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_getts : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_syncr : Intrinsic<[],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_settw : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_setv : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_eeu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>;
+
+ // Intrinsics for events.
+ def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>;
+ def int_xcore_clre : Intrinsic<[],[],[]>;
}
diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h
index e5b77777d9..3502ff73c1 100644
--- a/include/llvm/LLVMContext.h
+++ b/include/llvm/LLVMContext.h
@@ -21,6 +21,7 @@ class LLVMContextImpl;
class StringRef;
class Instruction;
class Module;
+class SMDiagnostic;
template <typename T> class SmallVectorImpl;
/// This is an important class for using LLVM in a threaded context. It
@@ -49,18 +50,23 @@ public:
/// custom metadata IDs registered in this LLVMContext.
void getMDKindNames(SmallVectorImpl<StringRef> &Result) const;
+
+ typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
+ unsigned LocCookie);
+
/// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked
/// when problems with inline asm are detected by the backend. The first
- /// argument is a function pointer (of type SourceMgr::DiagHandlerTy) and the
- /// second is a context pointer that gets passed into the DiagHandler.
+ /// argument is a function pointer and the second is a context pointer that
+ /// gets passed into the DiagHandler.
///
- /// LLVMContext doesn't take ownership or interpreter either of these
+ /// LLVMContext doesn't take ownership or interpret either of these
/// pointers.
- void setInlineAsmDiagnosticHandler(void *DiagHandler, void *DiagContext = 0);
+ void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
+ void *DiagContext = 0);
/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
/// setInlineAsmDiagnosticHandler.
- void *getInlineAsmDiagnosticHandler() const;
+ InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const;
/// getInlineAsmDiagnosticContext - Return the diagnostic context set by
/// setInlineAsmDiagnosticHandler.
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index c260425713..1769ba1ef4 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This header file pulls in all transformation and analysis passes for tools
+// This header file pulls in all transformation and analysis passes for tools
// like opt and bugpoint that need this functionality.
//
//===----------------------------------------------------------------------===//
@@ -70,6 +70,7 @@ namespace {
(void) llvm::createDomViewerPass();
(void) llvm::createEdgeProfilerPass();
(void) llvm::createOptimalEdgeProfilerPass();
+ (void) llvm::createPathProfilerPass();
(void) llvm::createFunctionInliningPass();
(void) llvm::createAlwaysInlinerPass();
(void) llvm::createGlobalDCEPass();
@@ -83,13 +84,13 @@ namespace {
(void) llvm::createLCSSAPass();
(void) llvm::createLICMPass();
(void) llvm::createLazyValueInfoPass();
- (void) llvm::createLiveValuesPass();
(void) llvm::createLoopDependenceAnalysisPass();
(void) llvm::createLoopExtractorPass();
(void) llvm::createLoopSimplifyPass();
(void) llvm::createLoopStrengthReducePass();
(void) llvm::createLoopUnrollPass();
(void) llvm::createLoopUnswitchPass();
+ (void) llvm::createLoopIdiomPass();
(void) llvm::createLoopRotatePass();
(void) llvm::createLowerInvokePass();
(void) llvm::createLowerSetJmpPass();
@@ -98,7 +99,9 @@ namespace {
(void) llvm::createNoProfileInfoPass();
(void) llvm::createProfileEstimatorPass();
(void) llvm::createProfileVerifierPass();
+ (void) llvm::createPathProfileVerifierPass();
(void) llvm::createProfileLoaderPass();
+ (void) llvm::createPathProfileLoaderPass();
(void) llvm::createPromoteMemoryToRegisterPass();
(void) llvm::createDemoteRegisterToMemoryPass();
(void) llvm::createPruneEHPass();
@@ -115,7 +118,6 @@ namespace {
(void) llvm::createSCCPPass();
(void) llvm::createScalarReplAggregatesPass();
(void) llvm::createSimplifyLibCallsPass();
- (void) llvm::createSimplifyHalfPowrLibCallsPass();
(void) llvm::createSingleLoopExtractorPass();
(void) llvm::createStripSymbolsPass();
(void) llvm::createStripNonDebugSymbolsPass();
@@ -127,13 +129,13 @@ namespace {
(void) llvm::createUnifyFunctionExitNodesPass();
(void) llvm::createInstCountPass();
(void) llvm::createCodeGenPreparePass();
+ (void) llvm::createEarlyCSEPass();
(void) llvm::createGVNPass();
(void) llvm::createMemCpyOptPass();
(void) llvm::createLoopDeletionPass();
(void) llvm::createPostDomTree();
(void) llvm::createPostDomFrontier();
(void) llvm::createInstructionNamerPass();
- (void) llvm::createPartialSpecializationPass();
(void) llvm::createFunctionAttrsPass();
(void) llvm::createMergeFunctionsPass();
(void) llvm::createPrintModulePass(0);
@@ -141,12 +143,12 @@ namespace {
(void) llvm::createDbgInfoPrinterPass();
(void) llvm::createModuleDebugInfoPrinterPass();
(void) llvm::createPartialInliningPass();
- (void) llvm::createGEPSplitterPass();
(void) llvm::createLintPass();
(void) llvm::createSinkingPass();
(void) llvm::createLowerAtomicPass();
(void) llvm::createCorrelatedValuePropagationPass();
(void) llvm::createMemDepPrinter();
+ (void) llvm::createInstructionSimplifierPass();
(void)new llvm::IntervalPartition();
(void)new llvm::FindUsedTypes();
diff --git a/include/llvm/LinkAllVMCore.h b/include/llvm/LinkAllVMCore.h
index 6959cb6d1e..83684c0fb6 100644
--- a/include/llvm/LinkAllVMCore.h
+++ b/include/llvm/LinkAllVMCore.h
@@ -22,15 +22,14 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/InlineAsm.h"
#include "llvm/Analysis/Verifier.h"
-#include "llvm/System/Alarm.h"
-#include "llvm/System/DynamicLibrary.h"
-#include "llvm/System/Memory.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Process.h"
-#include "llvm/System/Program.h"
-#include "llvm/System/Signals.h"
-#include "llvm/System/TimeValue.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/TimeValue.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/MathExtras.h"
#include <cstdlib>
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h
index dded25521a..83d9e780fe 100644
--- a/include/llvm/MC/EDInstInfo.h
+++ b/include/llvm/MC/EDInstInfo.h
@@ -9,7 +9,7 @@
#ifndef EDINSTINFO_H
#define EDINSTINFO_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 0c0a942e1b..7e24a3d1d3 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -25,7 +25,9 @@ namespace llvm {
/// MCAsmInfo - This class is intended to be used as a base class for asm
/// properties and features specific to the target.
- namespace ExceptionHandling { enum ExceptionsType { None, Dwarf, SjLj }; }
+ namespace ExceptionHandling {
+ enum ExceptionsType { None, DwarfTable, DwarfCFI, SjLj, ARM };
+ }
class MCAsmInfo {
protected:
@@ -51,6 +53,11 @@ namespace llvm {
/// emitted in Static relocation model.
bool HasStaticCtorDtorReferenceInStaticMode; // Default is false.
+ /// LinkerRequiresNonEmptyDwarfLines - True if the linker has a bug and
+ /// requires that the debug_line section be of a minimum size. In practice
+ /// such a linker requires a non empty line sequence if a file is present.
+ bool LinkerRequiresNonEmptyDwarfLines; // Default to false.
+
/// MaxInstLength - This is the maximum possible length of an instruction,
/// which is needed to compute the size of an inline asm.
unsigned MaxInstLength; // Defaults to 4.
@@ -192,6 +199,13 @@ namespace llvm {
/// HasSetDirective - True if the assembler supports the .set directive.
bool HasSetDirective; // Defaults to true.
+ /// HasAggressiveSymbolFolding - False if the assembler requires that we use
+ /// Lc = a - b
+ /// .long Lc
+ /// instead of
+ /// .long a - b
+ bool HasAggressiveSymbolFolding; // Defaults to true.
+
/// HasLCOMMDirective - This is true if the target supports the .lcomm
/// directive.
bool HasLCOMMDirective; // Defaults to false.
@@ -212,6 +226,10 @@ namespace llvm {
/// directive.
bool HasNoDeadStrip; // Defaults to false.
+ /// HasSymbolResolver - True if this target supports the MachO
+ /// .symbol_resolver directive.
+ bool HasSymbolResolver; // Defaults to false.
+
/// WeakRefDirective - This directive, if non-null, is used to declare a
/// global as being a weak undefined symbol.
const char *WeakRefDirective; // Defaults to NULL.
@@ -228,6 +246,11 @@ namespace llvm {
/// declare a symbol as having hidden visibility.
MCSymbolAttr HiddenVisibilityAttr; // Defaults to MCSA_Hidden.
+ /// HiddenDeclarationVisibilityAttr - This attribute, if not MCSA_Invalid,
+ /// is used to declare an undefined symbol as having hidden visibility.
+ MCSymbolAttr HiddenDeclarationVisibilityAttr; // Defaults to MCSA_Hidden.
+
+
/// ProtectedVisibilityAttr - This attribute, if not MCSA_Invalid, is used
/// to declare a symbol as having protected visibility.
MCSymbolAttr ProtectedVisibilityAttr; // Defaults to MCSA_Protected
@@ -237,10 +260,6 @@ namespace llvm {
/// HasLEB128 - True if target asm supports leb128 directives.
bool HasLEB128; // Defaults to false.
- /// hasDotLocAndDotFile - True if target asm supports .loc and .file
- /// directives for emitting debugging information.
- bool HasDotLocAndDotFile; // Defaults to false.
-
/// SupportsDebugInformation - True if target supports emission of debugging
/// information.
bool SupportsDebugInformation; // Defaults to false.
@@ -322,6 +341,9 @@ namespace llvm {
bool hasStaticCtorDtorReferenceInStaticMode() const {
return HasStaticCtorDtorReferenceInStaticMode;
}
+ bool getLinkerRequiresNonEmptyDwarfLines() const {
+ return LinkerRequiresNonEmptyDwarfLines;
+ }
unsigned getMaxInstLength() const {
return MaxInstLength;
}
@@ -392,6 +414,9 @@ namespace llvm {
return ExternDirective;
}
bool hasSetDirective() const { return HasSetDirective; }
+ bool hasAggressiveSymbolFolding() const {
+ return HasAggressiveSymbolFolding;
+ }
bool hasLCOMMDirective() const { return HasLCOMMDirective; }
bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
bool getCOMMDirectiveAlignmentIsInBytes() const {
@@ -399,20 +424,21 @@ namespace llvm {
}
bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
bool hasNoDeadStrip() const { return HasNoDeadStrip; }
+ bool hasSymbolResolver() const { return HasSymbolResolver; }
const char *getWeakRefDirective() const { return WeakRefDirective; }
const char *getWeakDefDirective() const { return WeakDefDirective; }
const char *getLinkOnceDirective() const { return LinkOnceDirective; }
MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;}
+ MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
+ return HiddenDeclarationVisibilityAttr;
+ }
MCSymbolAttr getProtectedVisibilityAttr() const {
return ProtectedVisibilityAttr;
}
bool hasLEB128() const {
return HasLEB128;
}
- bool hasDotLocAndDotFile() const {
- return HasDotLocAndDotFile;
- }
bool doesSupportDebugInformation() const {
return SupportsDebugInformation;
}
@@ -422,6 +448,13 @@ namespace llvm {
ExceptionHandling::ExceptionsType getExceptionHandlingType() const {
return ExceptionsType;
}
+ bool isExceptionHandlingDwarf() const {
+ return
+ (ExceptionsType == ExceptionHandling::DwarfTable ||
+ ExceptionsType == ExceptionHandling::DwarfCFI ||
+ ExceptionsType == ExceptionHandling::ARM);
+ }
+
bool doesDwarfRequireFrameSection() const {
return DwarfRequiresFrameSection;
}
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index b9565ba061..01cb0006b3 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -39,13 +39,12 @@ private:
/// The last fragment which was layed out, or 0 if nothing has been layed
/// out. Fragments are always layed out in order, so all fragments with a
/// lower ordinal will be up to date.
- mutable MCFragment *LastValidFragment;
+ mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment;
/// \brief Make sure that the layout for the given fragment is valid, lazily
/// computing it if necessary.
void EnsureValid(const MCFragment *F) const;
- bool isSectionUpToDate(const MCSectionData *SD) const;
bool isFragmentUpToDate(const MCFragment *F) const;
public:
@@ -54,27 +53,15 @@ public:
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
- /// \brief Update the layout because a fragment has been resized. The
- /// fragments size should have already been updated, the \arg SlideAmount is
- /// the delta from the old size.
- void UpdateForSlide(MCFragment *F, int SlideAmount);
-
- /// \brief Update the layout because a fragment has been replaced.
- void FragmentReplaced(MCFragment *Src, MCFragment *Dst);
-
- /// \brief Perform a full layout.
- void LayoutFile();
+ /// \brief Invalidate all following fragments because a fragment has been
+ /// resized. The fragments size should have already been updated.
+ void Invalidate(MCFragment *F);
/// \brief Perform layout for a single fragment, assuming that the previous
/// fragment has already been layed out correctly, and the parent section has
/// been initialized.
void LayoutFragment(MCFragment *Fragment);
- /// \brief Performs initial layout for a single section, assuming that the
- /// previous section (including its fragments) has already been layed out
- /// correctly.
- void LayoutSection(MCSectionData *SD);
-
/// @name Section Access (in layout order)
/// @{
@@ -89,28 +76,13 @@ public:
/// @name Fragment Layout Data
/// @{
- /// \brief Get the effective size of the given fragment, as computed in the
- /// current layout.
- uint64_t getFragmentEffectiveSize(const MCFragment *F) const;
-
/// \brief Get the offset of the given fragment inside its containing section.
uint64_t getFragmentOffset(const MCFragment *F) const;
/// @}
- /// @name Section Layout Data
- /// @{
-
- /// \brief Get the computed address of the given section.
- uint64_t getSectionAddress(const MCSectionData *SD) const;
-
- /// @}
/// @name Utility Functions
/// @{
- /// \brief Get the address of the given fragment, as computed in the current
- /// layout.
- uint64_t getFragmentAddress(const MCFragment *F) const;
-
/// \brief Get the address space size of the given section, as it effects
/// layout. This may differ from the size reported by \see getSectionSize() by
/// not including section tail padding.
@@ -120,12 +92,9 @@ public:
/// file. This may include additional padding, or be 0 for virtual sections.
uint64_t getSectionFileSize(const MCSectionData *SD) const;
- /// \brief Get the logical data size of the given section.
- uint64_t getSectionSize(const MCSectionData *SD) const;
-
- /// \brief Get the address of the given symbol, as computed in the current
+ /// \brief Get the offset of the given symbol, as computed in the current
/// layout.
- uint64_t getSymbolAddress(const MCSymbolData *SD) const;
+ uint64_t getSymbolOffset(const MCSymbolData *SD) const;
/// @}
};
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index a757a92208..30971c62a9 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -11,13 +11,14 @@
#define LLVM_MC_MCASSEMBLER_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/Support/Casting.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <vector> // FIXME: Shouldn't be needed.
namespace llvm {
@@ -51,6 +52,7 @@ public:
FT_Inst,
FT_Org,
FT_Dwarf,
+ FT_DwarfFrame,
FT_LEB
};
@@ -74,12 +76,7 @@ private:
/// initialized.
uint64_t Offset;
- /// EffectiveSize - The compute size of this section. This is ~0 until
- /// initialized.
- uint64_t EffectiveSize;
-
- /// LayoutOrder - The global layout order of this fragment. This is the index
- /// across all fragments in the file, not just within the section.
+ /// LayoutOrder - The layout order of this fragment.
unsigned LayoutOrder;
/// @}
@@ -236,19 +233,12 @@ class MCAlignFragment : public MCFragment {
/// target dependent.
bool EmitNops : 1;
- /// OnlyAlignAddress - Flag to indicate that this align is only used to adjust
- /// the address space size of a section and that it should not be included as
- /// part of the section size. This flag can only be used on the last fragment
- /// in a section.
- bool OnlyAlignAddress : 1;
-
public:
MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
: MCFragment(FT_Align, SD), Alignment(_Alignment),
Value(_Value),ValueSize(_ValueSize),
- MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false),
- OnlyAlignAddress(false) {}
+ MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
/// @name Accessors
/// @{
@@ -264,9 +254,6 @@ public:
bool hasEmitNops() const { return EmitNops; }
void setEmitNops(bool Value) { EmitNops = Value; }
- bool hasOnlyAlignAddress() const { return OnlyAlignAddress; }
- void setOnlyAlignAddress(bool Value) { OnlyAlignAddress = Value; }
-
/// @}
static bool classof(const MCFragment *F) {
@@ -319,13 +306,10 @@ class MCOrgFragment : public MCFragment {
/// Value - Value to use for filling bytes.
int8_t Value;
- /// Size - The current estimate of the size.
- unsigned Size;
-
public:
MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
: MCFragment(FT_Org, SD),
- Offset(&_Offset), Value(_Value), Size(0) {}
+ Offset(&_Offset), Value(_Value) {}
/// @name Accessors
/// @{
@@ -334,9 +318,6 @@ public:
uint8_t getValue() const { return Value; }
- unsigned getSize() const { return Size; }
-
- void setSize(unsigned Size_) { Size = Size_; }
/// @}
static bool classof(const MCFragment *F) {
@@ -352,13 +333,11 @@ class MCLEBFragment : public MCFragment {
/// IsSigned - True if this is a sleb128, false if uleb128.
bool IsSigned;
- /// Size - The current size estimate.
- uint64_t Size;
-
+ SmallString<8> Contents;
public:
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
: MCFragment(FT_LEB, SD),
- Value(&Value_), IsSigned(IsSigned_), Size(1) {}
+ Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
/// @name Accessors
/// @{
@@ -367,9 +346,8 @@ public:
bool isSigned() const { return IsSigned; }
- uint64_t getSize() const { return Size; }
-
- void setSize(uint64_t Size_) { Size = Size_; }
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
/// @}
@@ -388,14 +366,13 @@ class MCDwarfLineAddrFragment : public MCFragment {
/// make up the address delta between two .loc dwarf directives.
const MCExpr *AddrDelta;
- /// Size - The current size estimate.
- uint64_t Size;
+ SmallString<8> Contents;
public:
MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
- MCSectionData *SD = 0)
+ MCSectionData *SD)
: MCFragment(FT_Dwarf, SD),
- LineDelta(_LineDelta), AddrDelta(&_AddrDelta), Size(1) {}
+ LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
/// @name Accessors
/// @{
@@ -404,9 +381,8 @@ public:
const MCExpr &getAddrDelta() const { return *AddrDelta; }
- uint64_t getSize() const { return Size; }
-
- void setSize(uint64_t Size_) { Size = Size_; }
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
/// @}
@@ -416,6 +392,34 @@ public:
static bool classof(const MCDwarfLineAddrFragment *) { return true; }
};
+class MCDwarfCallFrameFragment : public MCFragment {
+ /// AddrDelta - The expression for the difference of the two symbols that
+ /// make up the address delta between two .cfi_* dwarf directives.
+ const MCExpr *AddrDelta;
+
+ SmallString<8> Contents;
+
+public:
+ MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD)
+ : MCFragment(FT_DwarfFrame, SD),
+ AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+
+ /// @name Accessors
+ /// @{
+
+ const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_DwarfFrame;
+ }
+ static bool classof(const MCDwarfCallFrameFragment *) { return true; }
+};
+
// FIXME: Should this be a separate class, or just merged into MCSection? Since
// we anticipate the fast path being through an MCAssembler, the only reason to
// keep it out is for API abstraction.
@@ -452,10 +456,6 @@ private:
//
// FIXME: This could all be kept private to the assembler implementation.
- /// Address - The computed address of this section. This is ~0 until
- /// initialized.
- uint64_t Address;
-
/// HasInstructions - Whether this section has had instructions emitted into
/// it.
unsigned HasInstructions : 1;
@@ -664,6 +664,8 @@ private:
MCCodeEmitter &Emitter;
+ MCObjectWriter &Writer;
+
raw_ostream &OS;
iplist<MCSectionData> Sections;
@@ -682,9 +684,18 @@ private:
std::vector<IndirectSymbolData> IndirectSymbols;
+ /// The set of function symbols for which a .thumb_func directive has
+ /// been seen.
+ //
+ // FIXME: We really would like this in target specific code rather than
+ // here. Maybe when the relocation stuff moves to target specific,
+ // this can go with it? The streamer would need some target specific
+ // refactoring too.
+ SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
+
unsigned RelaxAll : 1;
+ unsigned NoExecStack : 1;
unsigned SubsectionsViaSymbols : 1;
- unsigned PadSectionToAlignment : 1;
private:
/// Evaluate a fixup to a relocatable expression and the value which should be
@@ -700,47 +711,44 @@ private:
/// \return Whether the fixup value was fully resolved. This is true if the
/// \arg Value result is fixed, otherwise the value may change due to
/// relocation.
- bool EvaluateFixup(const MCObjectWriter &Writer, const MCAsmLayout &Layout,
+ bool EvaluateFixup(const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
MCValue &Target, uint64_t &Value) const;
/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
- bool FixupNeedsRelaxation(const MCObjectWriter &Writer,
- const MCFixup &Fixup, const MCFragment *DF,
+ bool FixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF,
const MCAsmLayout &Layout) const;
/// Check whether the given fragment needs relaxation.
- bool FragmentNeedsRelaxation(const MCObjectWriter &Writer,
- const MCInstFragment *IF,
+ bool FragmentNeedsRelaxation(const MCInstFragment *IF,
const MCAsmLayout &Layout) const;
- /// Compute the effective fragment size assuming it is layed out at the given
- /// \arg SectionAddress and \arg FragmentOffset.
- uint64_t ComputeFragmentSize(MCAsmLayout &Layout, const MCFragment &F,
- uint64_t SectionAddress,
- uint64_t FragmentOffset) const;
-
/// LayoutOnce - Perform one layout iteration and return true if any offsets
/// were adjusted.
- bool LayoutOnce(const MCObjectWriter &Writer, MCAsmLayout &Layout);
+ bool LayoutOnce(MCAsmLayout &Layout);
- bool RelaxInstruction(const MCObjectWriter &Writer, MCAsmLayout &Layout,
- MCInstFragment &IF);
+ bool LayoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
- bool RelaxOrg(const MCObjectWriter &Writer, MCAsmLayout &Layout,
- MCOrgFragment &OF);
+ bool RelaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF);
- bool RelaxLEB(const MCObjectWriter &Writer, MCAsmLayout &Layout,
- MCLEBFragment &IF);
+ bool RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
- bool RelaxDwarfLineAddr(const MCObjectWriter &Writer, MCAsmLayout &Layout,
- MCDwarfLineAddrFragment &DF);
+ bool RelaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
+ bool RelaxDwarfCallFrameFragment(MCAsmLayout &Layout,
+ MCDwarfCallFrameFragment &DF);
/// FinishLayout - Finalize a layout, including fragment lowering.
void FinishLayout(MCAsmLayout &Layout);
+ uint64_t HandleFixup(const MCAsmLayout &Layout,
+ MCFragment &F, const MCFixup &Fixup);
+
public:
+ /// Compute the effective fragment size assuming it is layed out at the given
+ /// \arg SectionAddress and \arg FragmentOffset.
+ uint64_t ComputeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const;
+
/// Find the symbol which defines the atom containing the given symbol, or
/// null if there is no such symbol.
const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
@@ -752,13 +760,16 @@ public:
bool isSymbolLinkerVisible(const MCSymbol &SD) const;
/// Emit the section contents using the given object writer.
- //
- // FIXME: Should MCAssembler always have a reference to the object writer?
- void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout,
- MCObjectWriter *OW) const;
+ void WriteSectionData(const MCSectionData *Section,
+ const MCAsmLayout &Layout) const;
+
+ /// Check whether a given symbol has been flagged with .thumb_func.
+ bool isThumbFunc(const MCSymbol *Func) const {
+ return ThumbFuncs.count(Func);
+ }
- void AddSectionToTheEnd(const MCObjectWriter &Writer, MCSectionData &SD,
- MCAsmLayout &Layout);
+ /// Flag a function symbol as the target of a .thumb_func directive.
+ void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
public:
/// Construct a new assembler instance.
@@ -769,8 +780,8 @@ public:
// concrete and require clients to pass in a target like object. The other
// option is to make this abstract, and have targets provide concrete
// implementations as we do with AsmParser.
- MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend,
- MCCodeEmitter &_Emitter, bool _PadSectionToAlignment,
+ MCAssembler(MCContext &Context_, TargetAsmBackend &Backend_,
+ MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
raw_ostream &OS);
~MCAssembler();
@@ -780,10 +791,12 @@ public:
MCCodeEmitter &getEmitter() const { return Emitter; }
+ MCObjectWriter &getWriter() const { return Writer; }
+
/// Finish - Do final processing and write the object to the output stream.
/// \arg Writer is used for custom object writer (as the MCJIT does),
/// if not specified it is automatically created from backend.
- void Finish(MCObjectWriter *Writer = 0);
+ void Finish();
// FIXME: This does not belong here.
bool getSubsectionsViaSymbols() const {
@@ -796,6 +809,9 @@ public:
bool getRelaxAll() const { return RelaxAll; }
void setRelaxAll(bool Value) { RelaxAll = Value; }
+ bool getNoExecStack() const { return NoExecStack; }
+ void setNoExecStack(bool Value) { NoExecStack = Value; }
+
/// @name Section List Access
/// @{
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
index eac06ede2a..bc63241bec 100644
--- a/include/llvm/MC/MCCodeEmitter.h
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -20,33 +20,6 @@ class MCInst;
class raw_ostream;
template<typename T> class SmallVectorImpl;
-/// MCFixupKindInfo - Target independent information on a fixup kind.
-struct MCFixupKindInfo {
- enum FixupKindFlags {
- /// Is this fixup kind PCrelative? This is used by the assembler backend to
- /// evaluate fixup values in a target independent manner when possible.
- FKF_IsPCRel = (1 << 0)
- };
-
- /// A target specific name for the fixup kind. The names will be unique for
- /// distinct kinds on any given target.
- const char *Name;
-
- /// The bit offset to write the relocation into.
- //
- // FIXME: These two fields are under-specified and not general enough, but it
- // covers many things. It's enough to let the AsmStreamer pretty-print
- // the encoding.
- unsigned TargetOffset;
-
- /// The number of bits written by this fixup. The bits are assumed to be
- /// contiguous.
- unsigned TargetSize;
-
- /// Flags describing additional information on this fixup kind.
- unsigned Flags;
-};
-
/// MCCodeEmitter - Generic instruction encoding interface.
class MCCodeEmitter {
private:
@@ -58,17 +31,6 @@ protected: // Can only create subclasses.
public:
virtual ~MCCodeEmitter();
- /// @name Target Independent Fixup Information
- /// @{
-
- /// getNumFixupKinds - Get the number of target specific fixup kinds.
- virtual unsigned getNumFixupKinds() const = 0;
-
- /// getFixupKindInfo - Get information on a fixup kind.
- virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
-
- /// @}
-
/// EncodeInstruction - Encode the given \arg Inst to bytes on the output
/// stream \arg OS.
virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index cec29fad63..7b26d54937 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -29,6 +29,7 @@ namespace llvm {
class MCLineSection;
class StringRef;
class Twine;
+ class TargetAsmInfo;
class MCSectionMachO;
class MCSectionELF;
@@ -42,9 +43,15 @@ namespace llvm {
/// The MCAsmInfo for this target.
const MCAsmInfo &MAI;
+ const TargetAsmInfo *TAI;
+
/// Symbols - Bindings of names to symbols.
StringMap<MCSymbol*> Symbols;
+ /// UsedNames - Keeps tracks of names that were used both for used declared
+ /// and artificial symbols.
+ StringMap<bool> UsedNames;
+
/// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
/// symbol.
unsigned NextUniqueID;
@@ -57,8 +64,8 @@ namespace llvm {
/// GetInstance() gets the current instance of the directional local label
/// for the LocalLabelVal and adds it to the map if needed.
unsigned GetInstance(int64_t LocalLabelVal);
-
- /// The file name of the log file from the enviromment variable
+
+ /// The file name of the log file from the environment variable
/// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique
/// directive is used or it is an error.
char *SecureLogFile;
@@ -80,29 +87,37 @@ namespace llvm {
/// 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;
/// Allocator - Allocator object used for creating machine code objects.
///
/// We use a bump pointer allocator to avoid the need to track all allocated
/// objects.
BumpPtrAllocator Allocator;
-
+
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
+
+ MCSymbol *CreateSymbol(StringRef Name);
+
public:
- explicit MCContext(const MCAsmInfo &MAI);
+ explicit MCContext(const MCAsmInfo &MAI, const TargetAsmInfo *TAI);
~MCContext();
-
+
const MCAsmInfo &getAsmInfo() const { return MAI; }
- /// @name Symbol Managment
+ const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; }
+
+ /// @name Symbol Management
/// @{
-
+
/// CreateTempSymbol - Create and return a new assembler temporary symbol
/// with a unique but unspecified name.
MCSymbol *CreateTempSymbol();
- /// CreateDirectionalLocalSymbol - Create the defintion of a directional
- /// local symbol for numbered label (used for "1:" defintions).
+ /// CreateDirectionalLocalSymbol - Create the definition of a directional
+ /// local symbol for numbered label (used for "1:" definitions).
MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal);
/// GetDirectionalLocalSymbol - Create and return a directional local
@@ -121,8 +136,8 @@ namespace llvm {
MCSymbol *LookupSymbol(StringRef Name) const;
/// @}
-
- /// @name Section Managment
+
+ /// @name Section Management
/// @{
/// getMachOSection - Return the MCSection for the specified mach-o section.
@@ -156,10 +171,10 @@ namespace llvm {
return getCOFFSection (Section, Characteristics, 0, Kind);
}
-
+
/// @}
- /// @name Dwarf Managment
+ /// @name Dwarf Management
/// @{
/// GetDwarfFile - creates an entry in the dwarf file and directory tables.
@@ -167,8 +182,8 @@ namespace llvm {
bool isValidDwarfFileNumber(unsigned FileNumber);
- bool hasDwarfFiles(void) {
- return MCDwarfFiles.size() != 0;
+ bool hasDwarfFiles() const {
+ return !MCDwarfFiles.empty();
}
const std::vector<MCDwarfFile *> &getMCDwarfFiles() {
@@ -177,9 +192,18 @@ namespace llvm {
const std::vector<StringRef> &getMCDwarfDirs() {
return MCDwarfDirs;
}
- DenseMap<const MCSection *, MCLineSection *> &getMCLineSections() {
+
+ const DenseMap<const MCSection *, MCLineSection *>
+ &getMCLineSections() const {
return MCLineSections;
}
+ const std::vector<const MCSection *> &getMCLineSectionOrder() const {
+ return MCLineSectionOrder;
+ }
+ void addMCLineSection(const MCSection *Sec, MCLineSection *Line) {
+ MCLineSections[Sec] = Line;
+ MCLineSectionOrder.push_back(Sec);
+ }
/// setCurrentDwarfLoc - saves the information from the currently parsed
/// dwarf .loc directive and sets DwarfLocSeen. When the next instruction
diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h
index 03337a9f52..1df55dc252 100644
--- a/include/llvm/MC/MCDirectives.h
+++ b/include/llvm/MC/MCDirectives.h
@@ -34,6 +34,7 @@ enum MCSymbolAttr {
MCSA_LazyReference, ///< .lazy_reference (MachO)
MCSA_Local, ///< .local (ELF)
MCSA_NoDeadStrip, ///< .no_dead_strip (MachO)
+ MCSA_SymbolResolver, ///< .symbol_resolver (MachO)
MCSA_PrivateExtern, ///< .private_extern (MachO)
MCSA_Protected, ///< .protected (ELF)
MCSA_Reference, ///< .reference (MachO)
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h
index dfb8ed5e8a..c9e42eb6c7 100644
--- a/include/llvm/MC/MCDisassembler.h
+++ b/include/llvm/MC/MCDisassembler.h
@@ -9,7 +9,7 @@
#ifndef MCDISASSEMBLER_H
#define MCDISASSEMBLER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index 609d819626..07a7bad15b 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -16,16 +16,19 @@
#define LLVM_MC_MCDWARF_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/CodeGen/MachineLocation.h" // FIXME
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Dwarf.h"
#include <vector>
namespace llvm {
+ class MachineMove;
class MCContext;
+ class MCExpr;
class MCSection;
+ class MCSectionData;
+ class MCStreamer;
class MCSymbol;
class MCObjectStreamer;
class raw_ostream;
@@ -107,22 +110,22 @@ namespace llvm {
public:
/// getFileNum - Get the FileNum of this MCDwarfLoc.
- unsigned getFileNum() { return FileNum; }
+ unsigned getFileNum() const { return FileNum; }
/// getLine - Get the Line of this MCDwarfLoc.
- unsigned getLine() { return Line; }
+ unsigned getLine() const { return Line; }
/// getColumn - Get the Column of this MCDwarfLoc.
- unsigned getColumn() { return Column; }
+ unsigned getColumn() const { return Column; }
/// getFlags - Get the Flags of this MCDwarfLoc.
- unsigned getFlags() { return Flags; }
+ unsigned getFlags() const { return Flags; }
/// getIsa - Get the Isa of this MCDwarfLoc.
- unsigned getIsa() { return Isa; }
+ unsigned getIsa() const { return Isa; }
/// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
- unsigned getDiscriminator() { return Discriminator; }
+ unsigned getDiscriminator() const { return Discriminator; }
/// setFileNum - Set the FileNum of this MCDwarfLoc.
void setFileNum(unsigned fileNum) { FileNum = fileNum; }
@@ -162,12 +165,12 @@ namespace llvm {
MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc),
Label(label) {}
- MCSymbol *getLabel() { return Label; }
+ MCSymbol *getLabel() const { return Label; }
// This is called when an instruction is assembled into the specified
// section and if there is information from the last .loc directive that
// has yet to have a line entry made for it is made.
- static void Make(MCObjectStreamer *MCOS, const MCSection *Section);
+ static void Make(MCStreamer *MCOS, const MCSection *Section);
};
/// MCLineSection - Instances of this class represent the line information
@@ -192,12 +195,15 @@ namespace llvm {
typedef std::vector<MCLineEntry> MCLineEntryCollection;
typedef MCLineEntryCollection::iterator iterator;
+ typedef MCLineEntryCollection::const_iterator const_iterator;
private:
MCLineEntryCollection MCLineEntries;
public:
- MCLineEntryCollection *getMCLineEntries() { return &MCLineEntries; }
+ const MCLineEntryCollection *getMCLineEntries() const {
+ return &MCLineEntries;
+ }
};
class MCDwarfFileTable {
@@ -205,7 +211,7 @@ namespace llvm {
//
// This emits the Dwarf file and the line tables.
//
- static void Emit(MCObjectStreamer *MCOS, const MCSection *DwarfLineSection);
+ static void Emit(MCStreamer *MCOS);
};
class MCDwarfLineAddr {
@@ -214,16 +220,60 @@ namespace llvm {
static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
/// Utility function to emit the encoding to a streamer.
- static void Emit(MCObjectStreamer *MCOS,
+ static void Emit(MCStreamer *MCOS,
int64_t LineDelta,uint64_t AddrDelta);
- /// Utility function to compute the size of the encoding.
- static uint64_t ComputeSize(int64_t LineDelta, uint64_t AddrDelta);
-
/// Utility function to write the encoding to an object writer.
static void Write(MCObjectWriter *OW,
int64_t LineDelta, uint64_t AddrDelta);
};
+
+ class MCCFIInstruction {
+ public:
+ enum OpType { Remember, Restore, Move };
+ private:
+ OpType Operation;
+ MCSymbol *Label;
+ // Move to & from location.
+ MachineLocation Destination;
+ MachineLocation Source;
+ public:
+ MCCFIInstruction(OpType Op, MCSymbol *L)
+ : Operation(Op), Label(L) {
+ assert(Op == Remember || Op == Restore);
+ }
+ MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
+ const MachineLocation &S)
+ : Operation(Move), Label(L), Destination(D), Source(S) {
+ }
+ OpType getOperation() const { return Operation; }
+ MCSymbol *getLabel() const { return Label; }
+ const MachineLocation &getDestination() const { return Destination; }
+ const MachineLocation &getSource() const { return Source; }
+ };
+
+ struct MCDwarfFrameInfo {
+ MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
+ Instructions(), PersonalityEncoding(0),
+ LsdaEncoding(0) {}
+ MCSymbol *Begin;
+ MCSymbol *End;
+ const MCSymbol *Personality;
+ const MCSymbol *Lsda;
+ std::vector<MCCFIInstruction> Instructions;
+ unsigned PersonalityEncoding;
+ unsigned LsdaEncoding;
+ };
+
+ class MCDwarfFrameEmitter {
+ public:
+ //
+ // This emits the frame info section.
+ //
+ static void Emit(MCStreamer &streamer);
+ static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
+ static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS);
+ };
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
new file mode 100644
index 0000000000..3c150dca9e
--- /dev/null
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -0,0 +1,47 @@
+//===-- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELFOBJECTWRITER_H
+#define LLVM_MC_MCELFOBJECTWRITER_H
+
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class MCELFObjectTargetWriter {
+ const Triple::OSType OSType;
+ const uint16_t EMachine;
+ const unsigned HasRelocationAddend : 1;
+ const unsigned Is64Bit : 1;
+protected:
+ MCELFObjectTargetWriter(bool Is64Bit_, Triple::OSType OSType_,
+ uint16_t EMachine_, bool HasRelocationAddend_);
+
+public:
+ virtual ~MCELFObjectTargetWriter();
+
+ /// @name Accessors
+ /// @{
+ Triple::OSType getOSType() { return OSType; }
+ uint16_t getEMachine() { return EMachine; }
+ bool hasRelocationAddend() { return HasRelocationAddend; }
+ bool is64Bit() { return Is64Bit; }
+ /// @}
+};
+
+/// \brief Construct a new ELF writer instance.
+///
+/// \param MOTW - The target specific ELF writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+ raw_ostream &OS, bool IsLittleEndian);
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index e8b15284f2..fea5249eab 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -10,17 +10,21 @@
#ifndef LLVM_MC_MCEXPR_H
#define LLVM_MC_MCEXPR_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Casting.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCAsmInfo;
class MCAsmLayout;
+class MCAssembler;
class MCContext;
+class MCSectionData;
class MCSymbol;
class MCValue;
class raw_ostream;
class StringRef;
+typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap;
/// MCExpr - Base class for the full range of assembler expressions which are
/// needed for parsing.
@@ -40,10 +44,15 @@ private:
MCExpr(const MCExpr&); // DO NOT IMPLEMENT
void operator=(const MCExpr&); // DO NOT IMPLEMENT
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs) const;
protected:
explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {}
- bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
+ bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs,
bool InSet) const;
public:
/// @name Accessors
@@ -69,7 +78,11 @@ public:
/// values. If not given, then only non-symbolic expressions will be
/// evaluated.
/// @result - True on success.
- bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout = 0) const;
+ bool EvaluateAsAbsolute(int64_t &Res) const;
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
+ const SectionAddrMap &Addrs) const;
/// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
/// value, i.e. an expression of the fixed form (a - b + constant).
@@ -77,7 +90,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 = 0) const;
+ bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const;
/// @}
@@ -142,8 +155,6 @@ public:
VK_TPOFF,
VK_DTPOFF,
VK_TLVP, // Mach-O thread local variable relocation
- VK_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the .s file)
- VK_ARM_LO16, // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the .w file)
// FIXME: We'd really like to use the generic Kinds listed above for these.
VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT
VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF
@@ -151,7 +162,7 @@ public:
VK_ARM_GOTOFF,
VK_ARM_TPOFF,
VK_ARM_GOTTPOFF,
-
+
VK_PPC_TOC,
VK_PPC_HA16, // ha16(symbol)
VK_PPC_LO16 // lo16(symbol)
@@ -179,7 +190,7 @@ public:
MCContext &Ctx);
static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind,
MCContext &Ctx);
-
+
/// @}
/// @name Accessors
/// @{
@@ -408,7 +419,7 @@ public:
virtual void PrintImpl(raw_ostream &OS) const = 0;
virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const = 0;
-
+ virtual void AddValueSymbols(MCAssembler *) const = 0;
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h
index eed4c349e8..6fde797e40 100644
--- a/include/llvm/MC/MCFixup.h
+++ b/include/llvm/MC/MCFixup.h
@@ -10,7 +10,7 @@
#ifndef LLVM_MC_MCFIXUP_H
#define LLVM_MC_MCFIXUP_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
@@ -22,6 +22,10 @@ enum MCFixupKind {
FK_Data_2, ///< A two-byte fixup.
FK_Data_4, ///< A four-byte fixup.
FK_Data_8, ///< A eight-byte fixup.
+ FK_PCRel_1, ///< A one-byte pc relative fixup.
+ FK_PCRel_2, ///< A two-byte pc relative fixup.
+ FK_PCRel_4, ///< A four-byte pc relative fixup.
+ FK_PCRel_8, ///< A eight-byte pc relative fixup.
FirstTargetFixupKind = 128,
@@ -77,13 +81,13 @@ public:
/// getKindForSize - Return the generic fixup kind for a value with the given
/// size. It is an error to pass an unsupported size.
- static MCFixupKind getKindForSize(unsigned Size) {
+ static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) {
switch (Size) {
default: assert(0 && "Invalid generic fixup size!");
- case 1: return FK_Data_1;
- case 2: return FK_Data_2;
- case 4: return FK_Data_4;
- case 8: return FK_Data_8;
+ case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1;
+ case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2;
+ case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4;
+ case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8;
}
}
};
diff --git a/include/llvm/MC/MCFixupKindInfo.h b/include/llvm/MC/MCFixupKindInfo.h
new file mode 100644
index 0000000000..1961687146
--- /dev/null
+++ b/include/llvm/MC/MCFixupKindInfo.h
@@ -0,0 +1,43 @@
+//===-- llvm/MC/MCFixupKindInfo.h - Fixup Descriptors -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCFIXUPKINDINFO_H
+#define LLVM_MC_MCFIXUPKINDINFO_H
+
+namespace llvm {
+
+/// MCFixupKindInfo - Target independent information on a fixup kind.
+struct MCFixupKindInfo {
+ enum FixupKindFlags {
+ /// Is this fixup kind PCrelative? This is used by the assembler backend to
+ /// evaluate fixup values in a target independent manner when possible.
+ FKF_IsPCRel = (1 << 0),
+
+ /// Should this fixup kind force a 4-byte aligned effective PC value?
+ FKF_IsAlignedDownTo32Bits = (1 << 1)
+ };
+
+ /// A target specific name for the fixup kind. The names will be unique for
+ /// distinct kinds on any given target.
+ const char *Name;
+
+ /// The bit offset to write the relocation into.
+ unsigned TargetOffset;
+
+ /// The number of bits written by this fixup. The bits are assumed to be
+ /// contiguous.
+ unsigned TargetSize;
+
+ /// Flags describing additional information on this fixup kind.
+ unsigned Flags;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h
index 2b337e3624..d6ef7b4c33 100644
--- a/include/llvm/MC/MCInst.h
+++ b/include/llvm/MC/MCInst.h
@@ -18,7 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class raw_ostream;
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
index 96716c775f..92f06ed09c 100644
--- a/include/llvm/MC/MCInstPrinter.h
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -41,6 +41,9 @@ public:
/// getOpcodeName - Return the name of the specified opcode enum (e.g.
/// "MOV32ri") or empty if we can't resolve it.
virtual StringRef getOpcodeName(unsigned Opcode) const;
+
+ /// getRegName - Return the assembler register name.
+ virtual StringRef getRegName(unsigned RegNo) const;
};
} // namespace llvm
diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h
index c938c81f69..696436dffa 100644
--- a/include/llvm/MC/MCMachOSymbolFlags.h
+++ b/include/llvm/MC/MCMachOSymbolFlags.h
@@ -34,9 +34,11 @@ namespace llvm {
SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
// Other 'desc' flags.
+ SF_ThumbFunc = 0x0008,
SF_NoDeadStrip = 0x0020,
SF_WeakReference = 0x0040,
- SF_WeakDefinition = 0x0080
+ SF_WeakDefinition = 0x0080,
+ SF_SymbolResolver = 0x0100
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
new file mode 100644
index 0000000000..ec51031d0b
--- /dev/null
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -0,0 +1,65 @@
+//===-- llvm/MC/MCMachObjectWriter.h - Mach Object Writer -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCMACHOBJECTWRITER_H
+#define LLVM_MC_MCMACHOBJECTWRITER_H
+
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class MCMachObjectTargetWriter {
+ const unsigned Is64Bit : 1;
+ const uint32_t CPUType;
+ const uint32_t CPUSubtype;
+ // FIXME: Remove this, we should just always use it once we no longer care
+ // about Darwin 'as' compatibility.
+ const unsigned UseAggressiveSymbolFolding : 1;
+ unsigned LocalDifference_RIT;
+
+protected:
+ MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_,
+ uint32_t CPUSubtype_,
+ bool UseAggressiveSymbolFolding_ = false);
+
+ void setLocalDifferenceRelocationType(unsigned Type) {
+ LocalDifference_RIT = Type;
+ }
+
+public:
+ virtual ~MCMachObjectTargetWriter();
+
+ /// @name Accessors
+ /// @{
+
+ bool is64Bit() const { return Is64Bit; }
+ bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; }
+ uint32_t getCPUType() const { return CPUType; }
+ uint32_t getCPUSubtype() const { return CPUSubtype; }
+ unsigned getLocalDifferenceRelocationType() const {
+ return LocalDifference_RIT;
+ }
+
+ /// @}
+};
+
+/// \brief Construct a new Mach-O writer instance.
+///
+/// This routine takes ownership of the target writer subclass.
+///
+/// \param MOTW - The target specific Mach-O writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
+ raw_ostream &OS, bool IsLittleEndian);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCObjectFormat.h b/include/llvm/MC/MCObjectFormat.h
deleted file mode 100644
index 5c3f003696..0000000000
--- a/include/llvm/MC/MCObjectFormat.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===-- llvm/MC/MCObjectFormat.h - Object Format Info -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MC_MCOBJECTFORMAT_H
-#define LLVM_MC_MCOBJECTFORMAT_H
-
-namespace llvm {
-class MCSymbol;
-
-class MCObjectFormat {
-public:
- virtual ~MCObjectFormat();
-
- /// isAbsolute - Check if A - B is an absolute value
- ///
- /// \param InSet - True if this expression is in a set. For example:
- /// a:
- /// ...
- /// b:
- /// tmp = a - b
- /// .long tmp
- /// \param A - LHS
- /// \param B - RHS
- virtual bool isAbsolute(bool InSet, const MCSymbol &A,
- const MCSymbol &B) const = 0;
-};
-
-class MCELFObjectFormat : public MCObjectFormat {
-public:
- virtual bool isAbsolute(bool InSet, const MCSymbol &A,
- const MCSymbol &B) const;
-};
-
-class MCMachOObjectFormat : public MCObjectFormat {
-public:
- virtual bool isAbsolute(bool InSet, const MCSymbol &A,
- const MCSymbol &B) const;
-};
-
-class MCCOFFObjectFormat : public MCObjectFormat {
-public:
- virtual bool isAbsolute(bool InSet, const MCSymbol &A,
- const MCSymbol &B) const;
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 8c21c10522..833341eb97 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -33,13 +33,11 @@ class MCObjectStreamer : public MCStreamer {
MCAssembler *Assembler;
MCSectionData *CurSectionData;
- virtual void EmitInstToFragment(const MCInst &Inst) = 0;
virtual void EmitInstToData(const MCInst &Inst) = 0;
protected:
MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
- raw_ostream &_OS, MCCodeEmitter *_Emitter,
- bool _PadSectionToAlignment);
+ raw_ostream &_OS, MCCodeEmitter *_Emitter);
~MCObjectStreamer();
MCSectionData *getCurrentSectionData() const {
@@ -60,11 +58,21 @@ public:
/// @name MCStreamer Interface
/// @{
+ virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ bool isPCRel, unsigned AddrSpace);
virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
- virtual void SwitchSection(const MCSection *Section);
+ virtual void ChangeSection(const MCSection *Section);
virtual void EmitInstruction(const MCInst &Inst);
+ virtual void EmitInstToFragment(const MCInst &Inst);
+ virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
+ virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
+ const MCSymbol *LastLabel,
+ const MCSymbol *Label);
+ virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label);
virtual void Finish();
/// @}
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 77ab6abed2..782d844598 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -12,7 +12,7 @@
#include "llvm/ADT/Triple.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
@@ -20,6 +20,9 @@ class MCAsmLayout;
class MCAssembler;
class MCFixup;
class MCFragment;
+class MCSymbol;
+class MCSymbolData;
+class MCSymbolRefExpr;
class MCValue;
class raw_ostream;
@@ -62,7 +65,8 @@ public:
///
/// This routine is called by the assembler after layout and relaxation is
/// complete.
- virtual void ExecutePostLayoutBinding(MCAssembler &Asm) = 0;
+ virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) = 0;
/// Record a relocation entry.
///
@@ -76,15 +80,24 @@ public:
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue) = 0;
- /// Check if a fixup is fully resolved.
+ /// \brief Check whether the difference (A - B) between two symbol
+ /// references is fully resolved.
///
- /// This routine is used by the assembler to let the file format decide
- /// if a fixup is not fully resolved. For example, one that crosses
- /// two sections on ELF.
- virtual bool IsFixupFullyResolved(const MCAssembler &Asm,
- const MCValue Target,
- bool IsPCRel,
- const MCFragment *DF) const = 0;
+ /// Clients are not required to answer precisely and may conservatively return
+ /// false, even when a difference is fully resolved.
+ bool
+ IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
+ const MCSymbolRefExpr *A,
+ const MCSymbolRefExpr *B,
+ bool InSet) const;
+
+ virtual bool
+ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
+
/// Write the object file.
///
@@ -178,13 +191,6 @@ public:
static void EncodeULEB128(uint64_t Value, raw_ostream &OS);
};
-MCObjectWriter *createMachObjectWriter(raw_ostream &OS, bool is64Bit,
- uint32_t CPUType, uint32_t CPUSubtype,
- bool IsLittleEndian);
-MCObjectWriter *createELFObjectWriter(raw_ostream &OS, bool is64Bit,
- Triple::OSType OSType, uint16_t EMachine,
- bool IsLittleEndian,
- bool HasRelocationAddend);
MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit);
} // End llvm namespace
diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h
index 439ecb91e5..252696bec3 100644
--- a/include/llvm/MC/MCParser/AsmLexer.h
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -17,7 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
#include <cassert>
@@ -29,10 +29,10 @@ class MCAsmInfo;
/// AsmLexer - Lexer class for assembly files.
class AsmLexer : public MCAsmLexer {
const MCAsmInfo &MAI;
-
+
const char *CurPtr;
const MemoryBuffer *CurBuf;
-
+
void operator=(const AsmLexer&); // DO NOT IMPLEMENT
AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT
@@ -43,13 +43,13 @@ protected:
public:
AsmLexer(const MCAsmInfo &MAI);
~AsmLexer();
-
+
void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL);
-
+
virtual StringRef LexUntilEndOfStatement();
bool isAtStartOfComment(char Char);
-
+
const MCAsmInfo &getMAI() const { return MAI; }
private:
@@ -60,10 +60,11 @@ private:
AsmToken LexSlash();
AsmToken LexLineComment();
AsmToken LexDigit();
+ AsmToken LexSingleQuote();
AsmToken LexQuote();
AsmToken LexFloatLiteral();
};
-
+
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index b0039fe2ba..606725a985 100644
--- a/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -11,7 +11,7 @@
#define LLVM_MC_MCASMLEXER_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
namespace llvm {
@@ -29,16 +29,16 @@ public:
// String values.
Identifier,
String,
-
+
// Integer values.
Integer,
-
+
// Real values.
Real,
-
+
// Register values (stored in IntVal). Only used by TargetAsmLexer.
Register,
-
+
// No-value.
EndOfStatement,
Colon,
@@ -46,8 +46,8 @@ public:
Slash, // '/'
LParen, RParen, LBrac, RBrac, LCurly, RCurly,
Star, Dot, Comma, Dollar, Equal, EqualEqual,
-
- Pipe, PipePipe, Caret,
+
+ Pipe, PipePipe, Caret,
Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
Less, LessEqual, LessLess, LessGreater,
Greater, GreaterEqual, GreaterGreater, At
@@ -73,7 +73,7 @@ public:
SMLoc getLoc() const;
/// getStringContents - Get the contents of a string token (without quotes).
- StringRef getStringContents() const {
+ StringRef getStringContents() const {
assert(Kind == String && "This token isn't a string!");
return Str.slice(1, Str.size() - 1);
}
@@ -98,11 +98,11 @@ public:
// FIXME: Don't compute this in advance, it makes every token larger, and is
// also not generally what we want (it is nicer for recovery etc. to lex 123br
// as a single token, then diagnose as an invalid number).
- int64_t getIntVal() const {
+ int64_t getIntVal() const {
assert(Kind == Integer && "This token isn't an integer!");
- return IntVal;
+ return IntVal;
}
-
+
/// getRegVal - Get the register number for the current token, which should
/// be a register.
unsigned getRegVal() const {
@@ -116,7 +116,7 @@ public:
class MCAsmLexer {
/// The current token, stored in the base class for faster access.
AsmToken CurTok;
-
+
/// The location and description of the current error
SMLoc ErrLoc;
std::string Err;
@@ -129,12 +129,12 @@ protected: // Can only create subclasses.
MCAsmLexer();
virtual AsmToken LexToken() = 0;
-
+
void SetError(const SMLoc &errLoc, const std::string &err) {
ErrLoc = errLoc;
Err = err;
}
-
+
public:
virtual ~MCAsmLexer();
@@ -155,12 +155,12 @@ public:
const AsmToken &getTok() {
return CurTok;
}
-
+
/// getErrLoc - Get the current error location
const SMLoc &getErrLoc() {
return ErrLoc;
}
-
+
/// getErr - Get the current error string
const std::string &getErr() {
return Err;
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index 6e1e2e3ece..54979d977d 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -10,7 +10,7 @@
#ifndef LLVM_MC_MCASMPARSER_H
#define LLVM_MC_MCASMPARSER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class AsmToken;
@@ -102,7 +102,7 @@ public:
/// EatToEndOfStatement - Skip to the end of the current statement, for error
/// recovery.
virtual void EatToEndOfStatement() = 0;
-
+
/// ParseExpression - Parse an arbitrary expression.
///
/// @param Res - The value of the expression. The result is undefined
diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h
index 95184cdfcf..ceb57f57e9 100644
--- a/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -38,6 +38,8 @@ protected:
return (Obj->*Handler)(Directive, DirectiveLoc);
}
+ bool BracketExpressionsSupported;
+
public:
virtual ~MCAsmParserExtension();
@@ -68,6 +70,8 @@ public:
const AsmToken &getTok() { return getParser().getTok(); }
+ bool HasBracketExpressions() const { return BracketExpressionsSupported; }
+
/// @}
};
diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index 99fa5adae9..91f5773b8d 100644
--- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -19,10 +19,10 @@ class raw_ostream;
/// base class is used by target-independent clients and is the interface
/// between parsing an asm instruction and recognizing it.
class MCParsedAsmOperand {
-public:
+public:
MCParsedAsmOperand() {}
virtual ~MCParsedAsmOperand() {}
-
+
/// getStartLoc - Get the location of the first token of this operand.
virtual SMLoc getStartLoc() const = 0;
/// getEndLoc - Get the location of the last token of this operand.
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index b741216f94..1c01b2f8f3 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -64,6 +64,10 @@ namespace llvm {
// "optimized nops" to fill instead of 0s.
virtual bool UseCodeAlign() const = 0;
+ /// isVirtualSection - Check whether this section is "virtual", that is
+ /// has no actual object file contents.
+ virtual bool isVirtualSection() const = 0;
+
static bool classof(const MCSection *) { return true; }
};
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index 8bf7f448ec..b154cf59d1 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -56,6 +56,7 @@ namespace llvm {
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;
virtual bool UseCodeAlign() const;
+ virtual bool isVirtualSection() const;
static bool classof(const MCSection *S) {
return S->getVariant() == SV_COFF;
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 5af538557e..c82de71282 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -15,6 +15,7 @@
#define LLVM_MC_MCSECTIONELF_H
#include "llvm/MC/MCSection.h"
+#include "llvm/Support/ELF.h"
namespace llvm {
@@ -54,131 +55,6 @@ public:
/// should be printed before the section name
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
- /// HasCommonSymbols - True if this section holds common symbols, this is
- /// indicated on the ELF object file by a symbol with SHN_COMMON section
- /// header index.
- bool HasCommonSymbols() const;
-
- /// These are the section type and flags fields. An ELF section can have
- /// only one Type, but can have more than one of the flags specified.
- ///
- /// Valid section types.
- enum {
- // This value marks the section header as inactive.
- SHT_NULL = 0x00U,
-
- // Holds information defined by the program, with custom format and meaning.
- SHT_PROGBITS = 0x01U,
-
- // This section holds a symbol table.
- SHT_SYMTAB = 0x02U,
-
- // The section holds a string table.
- SHT_STRTAB = 0x03U,
-
- // The section holds relocation entries with explicit addends.
- SHT_RELA = 0x04U,
-
- // The section holds a symbol hash table.
- SHT_HASH = 0x05U,
-
- // Information for dynamic linking.
- SHT_DYNAMIC = 0x06U,
-
- // The section holds information that marks the file in some way.
- SHT_NOTE = 0x07U,
-
- // A section of this type occupies no space in the file.
- SHT_NOBITS = 0x08U,
-
- // The section holds relocation entries without explicit addends.
- SHT_REL = 0x09U,
-
- // This section type is reserved but has unspecified semantics.
- SHT_SHLIB = 0x0AU,
-
- // This section holds a symbol table.
- SHT_DYNSYM = 0x0BU,
-
- // This section contains an array of pointers to initialization functions.
- SHT_INIT_ARRAY = 0x0EU,
-
- // This section contains an array of pointers to termination functions.
- SHT_FINI_ARRAY = 0x0FU,
-
- // This section contains an array of pointers to functions that are invoked
- // before all other initialization functions.
- SHT_PREINIT_ARRAY = 0x10U,
-
- // A section group is a set of sections that are related and that must be
- // treated specially by the linker.
- SHT_GROUP = 0x11U,
-
- // This section is associated with a section of type SHT_SYMTAB, when the
- // referenced symbol table contain the escape value SHN_XINDEX
- SHT_SYMTAB_SHNDX = 0x12U,
-
- // Start of target-specific flags.
-
- // Exception Index table
- SHT_ARM_EXIDX = 0x70000001U,
- // BPABI DLL dynamic linking pre-emption map
- SHT_ARM_PREEMPTMAP = 0x70000002U,
- // Object file compatibility attributes
- SHT_ARM_ATTRIBUTES = 0x70000003U,
- SHT_ARM_DEBUGOVERLAY = 0x70000004U,
- SHT_ARM_OVERLAYSECTION = 0x70000005U,
-
- LAST_KNOWN_SECTION_TYPE = SHT_ARM_OVERLAYSECTION
- };
-
- /// Valid section flags.
- enum {
- // The section contains data that should be writable.
- SHF_WRITE = 0x1U,
-
- // The section occupies memory during execution.
- SHF_ALLOC = 0x2U,
-
- // The section contains executable machine instructions.
- SHF_EXECINSTR = 0x4U,
-
- // The data in the section may be merged to eliminate duplication.
- SHF_MERGE = 0x10U,
-
- // Elements in the section consist of null-terminated character strings.
- SHF_STRINGS = 0x20U,
-
- // A field in this section holds a section header table index.
- SHF_INFO_LINK = 0x40U,
-
- // Adds special ordering requirements for link editors.
- SHF_LINK_ORDER = 0x80U,
-
- // This section requires special OS-specific processing to avoid incorrect
- // behavior.
- SHF_OS_NONCONFORMING = 0x100U,
-
- // This section is a member of a section group.
- SHF_GROUP = 0x200U,
-
- // This section holds Thread-Local Storage.
- SHF_TLS = 0x400U,
-
-
- // Start of target-specific flags.
-
- /// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped
- /// together by the linker to form the constant pool and the cp register is
- /// set to the start of the constant pool by the boot code.
- XCORE_SHF_CP_SECTION = 0x800U,
-
- /// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped
- /// together by the linker to form the data section and the dp register is
- /// set to the start of the section by the boot code.
- XCORE_SHF_DP_SECTION = 0x1000U
- };
-
StringRef getSectionName() const { return SectionName; }
unsigned getType() const { return Type; }
unsigned getFlags() const { return Flags; }
@@ -188,11 +64,12 @@ public:
void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;
virtual bool UseCodeAlign() const;
+ virtual bool isVirtualSection() const;
/// isBaseAddressKnownZero - We know that non-allocatable sections (like
/// debug info) have a base of zero.
virtual bool isBaseAddressKnownZero() const {
- return (getFlags() & SHF_ALLOC) == 0;
+ return (getFlags() & ELF::SHF_ALLOC) == 0;
}
static bool classof(const MCSection *S) {
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index f409f3253b..7633515f27 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -166,6 +166,7 @@ public:
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;
virtual bool UseCodeAlign() const;
+ virtual bool isVirtualSection() const;
static bool classof(const MCSection *S) {
return S->getVariant() == SV_MachO;
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 089650cb88..4fdbc44b25 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -14,8 +14,10 @@
#ifndef LLVM_MC_MCSTREAMER_H
#define LLVM_MC_MCSTREAMER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDwarf.h"
namespace llvm {
class MCAsmInfo;
@@ -28,6 +30,7 @@ namespace llvm {
class MCSymbol;
class StringRef;
class TargetAsmBackend;
+ class TargetLoweringObjectFile;
class Twine;
class raw_ostream;
class formatted_raw_ostream;
@@ -47,22 +50,34 @@ namespace llvm {
MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT
MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT
- protected:
- MCStreamer(MCContext &Ctx);
+ void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
+ bool isPCRel, unsigned AddrSpace);
- /// CurSection - This is the current section code is being emitted to, it is
- /// kept up to date by SwitchSection.
- const MCSection *CurSection;
+ std::vector<MCDwarfFrameInfo> FrameInfos;
+ MCDwarfFrameInfo *getCurrentFrameInfo();
+ void EnsureValidFrame();
- /// PrevSection - This is the previous section code is being emitted to, it
- /// is kept up to date by SwitchSection.
- const MCSection *PrevSection;
+ /// SectionStack - This is stack of current and previous section
+ /// values saved by PushSection.
+ SmallVector<std::pair<const MCSection *,
+ const MCSection *>, 4> SectionStack;
+
+ protected:
+ MCStreamer(MCContext &Ctx);
public:
virtual ~MCStreamer();
MCContext &getContext() const { return Context; }
+ unsigned getNumFrameInfos() {
+ return FrameInfos.size();
+ }
+
+ const MCDwarfFrameInfo &getFrameInfo(unsigned i) {
+ return FrameInfos[i];
+ }
+
/// @name Assembly File Formatting.
/// @{
@@ -98,17 +113,61 @@ namespace llvm {
/// getCurrentSection - Return the current section that the streamer is
/// emitting code to.
- const MCSection *getCurrentSection() const { return CurSection; }
+ const MCSection *getCurrentSection() const {
+ if (!SectionStack.empty())
+ return SectionStack.back().first;
+ return NULL;
+ }
/// getPreviousSection - Return the previous section that the streamer is
/// emitting code to.
- const MCSection *getPreviousSection() const { return PrevSection; }
+ const MCSection *getPreviousSection() const {
+ if (!SectionStack.empty())
+ return SectionStack.back().second;
+ return NULL;
+ }
+
+ /// ChangeSection - Update streamer for a new active section.
+ ///
+ /// This is called by PopSection and SwitchSection, if the current
+ /// section changes.
+ virtual void ChangeSection(const MCSection *) = 0;
+
+ /// pushSection - Save the current and previous section on the
+ /// section stack.
+ void PushSection() {
+ SectionStack.push_back(std::make_pair(getCurrentSection(),
+ getPreviousSection()));
+ }
+
+ /// popSection - Restore the current and previous section from
+ /// the section stack. Calls ChangeSection as needed.
+ ///
+ /// Returns false if the stack was empty.
+ bool PopSection() {
+ if (SectionStack.size() <= 1)
+ return false;
+ const MCSection *oldSection = SectionStack.pop_back_val().first;
+ const MCSection *curSection = SectionStack.back().first;
+
+ if (oldSection != curSection)
+ ChangeSection(curSection);
+ return true;
+ }
/// SwitchSection - Set the current section where code is being emitted to
/// @p Section. This is required to update CurSection.
///
/// This corresponds to assembler directives like .section, .text, etc.
- virtual void SwitchSection(const MCSection *Section) = 0;
+ void SwitchSection(const MCSection *Section) {
+ assert(Section && "Cannot switch to a null section!");
+ const MCSection *curSection = SectionStack.back().first;
+ SectionStack.back().second = curSection;
+ if (Section != curSection) {
+ SectionStack.back().first = Section;
+ ChangeSection(Section);
+ }
+ }
/// InitSections - Create the default sections and set the initial one.
virtual void InitSections() = 0;
@@ -240,14 +299,25 @@ namespace llvm {
/// @param Value - The value to emit.
/// @param Size - The size of the integer (in bytes) to emit. This must
/// match a native machine width.
- virtual void EmitValue(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace = 0) = 0;
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ bool isPCRel, unsigned AddrSpace) = 0;
+
+ void EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0);
+
+ void EmitPCRelValue(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace = 0);
/// EmitIntValue - Special case of EmitValue that avoids the client having
/// to pass in a MCExpr for constant integers.
virtual void EmitIntValue(uint64_t Value, unsigned Size,
unsigned AddrSpace = 0);
+ /// EmitAbsValue - Emit the Value, but try to avoid relocations. On MachO
+ /// this is done by producing
+ /// foo = value
+ /// .long foo
+ void EmitAbsValue(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace = 0);
virtual void EmitULEB128Value(const MCExpr *Value,
unsigned AddrSpace = 0) = 0;
@@ -257,23 +327,26 @@ namespace llvm {
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
- virtual void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0);
+ void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0);
/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
- virtual void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0);
+ void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0);
/// EmitSymbolValue - Special case of EmitValue that avoids the client
/// having to pass in a MCExpr for MCSymbols.
- virtual void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
- unsigned AddrSpace = 0);
+ void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
+ unsigned AddrSpace = 0);
+
+ void EmitPCRelSymbolValue(const MCSymbol *Sym, unsigned Size,
+ unsigned AddrSpace = 0);
/// EmitGPRel32Value - Emit the expression @p Value into the output as a
/// gprel32 (32-bit GP relative) value.
///
/// This is used to implement assembler directives such as .gprel32 on
/// targets that support them.
- virtual void EmitGPRel32Value(const MCExpr *Value) = 0;
+ virtual void EmitGPRel32Value(const MCExpr *Value);
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
@@ -342,7 +415,37 @@ namespace llvm {
/// EmitDwarfFileDirective - Associate a filename with a specified logical
/// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler
/// directive.
- virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) = 0;
+ virtual bool EmitDwarfFileDirective(unsigned FileNo,StringRef Filename);
+
+ /// EmitDwarfLocDirective - This implements the DWARF2
+ // '.loc fileno lineno ...' assembler directive.
+ virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+ unsigned Column, unsigned Flags,
+ unsigned Isa,
+ unsigned Discriminator);
+
+ virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
+ const MCSymbol *LastLabel,
+ const MCSymbol *Label) = 0;
+
+ virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label) {
+ }
+
+ void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label,
+ int PointerSize);
+
+ virtual bool EmitCFIStartProc();
+ virtual bool EmitCFIEndProc();
+ virtual bool EmitCFIDefCfa(int64_t Register, int64_t Offset);
+ virtual bool EmitCFIDefCfaOffset(int64_t Offset);
+ virtual bool EmitCFIDefCfaRegister(int64_t Register);
+ virtual bool EmitCFIOffset(int64_t Register, int64_t Offset);
+ virtual bool EmitCFIPersonality(const MCSymbol *Sym,
+ unsigned Encoding);
+ virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
+ virtual bool EmitCFIRememberState();
+ virtual bool EmitCFIRestoreState();
/// EmitInstruction - Emit the given @p Instruction into the current
/// section.
@@ -354,6 +457,19 @@ namespace llvm {
virtual void EmitRawText(StringRef String);
void EmitRawText(const Twine &String);
+ /// ARM-related methods.
+ /// FIXME: Eventually we should have some "target MC streamer" and move
+ /// these methods there.
+ virtual void EmitFnStart();
+ virtual void EmitFnEnd();
+ virtual void EmitCantUnwind();
+ virtual void EmitPersonality(const MCSymbol *Personality);
+ virtual void EmitHandlerData();
+ virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
+ virtual void EmitPad(int64_t Offset);
+ virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
+ bool isVector);
+
/// Finish - Finish emission of machine code.
virtual void Finish() = 0;
};
@@ -373,12 +489,18 @@ namespace llvm {
/// \param CE - If given, a code emitter to use to show the instruction
/// encoding inline with the assembly. This method takes ownership of \arg CE.
///
+ /// \param TAB - If given, a target asm backend to use to show the fixup
+ /// information in conjunction with encoding information. This method takes
+ /// ownership of \arg TAB.
+ ///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
- bool isLittleEndian, bool isVerboseAsm,
+ bool isVerboseAsm,
+ bool useLoc,
MCInstPrinter *InstPrint = 0,
MCCodeEmitter *CE = 0,
+ TargetAsmBackend *TAB = 0,
bool ShowInst = false);
/// createMachOStreamer - Create a machine code streamer which will generate
@@ -402,7 +524,7 @@ namespace llvm {
/// ELF format object files.
MCStreamer *createELFStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll = false);
+ bool RelaxAll, bool NoExecStack);
/// createLoggingStreamer - Create a machine code streamer which just logs the
/// API calls and then dispatches to another streamer.
@@ -410,6 +532,13 @@ namespace llvm {
/// The new streamer takes ownership of the \arg Child.
MCStreamer *createLoggingStreamer(MCStreamer *Child, raw_ostream &OS);
+ /// createPureStreamer - Create a machine code streamer which will generate
+ /// "pure" MC object files, for use with MC-JIT and testing tools.
+ ///
+ /// Takes ownership of \arg TAB and \arg CE.
+ MCStreamer *createPureStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *CE);
+
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h
index 11b6c2a17b..df8dbd930b 100644
--- a/include/llvm/MC/MCValue.h
+++ b/include/llvm/MC/MCValue.h
@@ -14,7 +14,7 @@
#ifndef LLVM_MC_MCVALUE_H
#define LLVM_MC_MCVALUE_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/MC/MCSymbol.h"
#include <cassert>
diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h
index a6c3f039a1..6a61996ff7 100644
--- a/include/llvm/Metadata.h
+++ b/include/llvm/Metadata.h
@@ -17,6 +17,7 @@
#define LLVM_METADATA_H
#include "llvm/Value.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ilist_node.h"
@@ -117,6 +118,8 @@ class MDNode : public Value, public FoldingSetNode {
FunctionLocalness FL, bool Insert = true);
public:
// Constructors and destructors.
+ static MDNode *get(LLVMContext &Context, ArrayRef<Value*> V);
+ // FIXME: Eliminate this constructor form.
static MDNode *get(LLVMContext &Context, Value *const *Vals,
unsigned NumVals);
// getWhenValsUnresolved - Construct MDNode determining function-localness
diff --git a/include/llvm/Module.h b/include/llvm/Module.h
index b7880ca2cb..c7063f5e1c 100644
--- a/include/llvm/Module.h
+++ b/include/llvm/Module.h
@@ -20,7 +20,7 @@
#include "llvm/GlobalAlias.h"
#include "llvm/Metadata.h"
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <vector>
namespace llvm {
@@ -211,15 +211,20 @@ public:
void setTargetTriple(StringRef T) { TargetTriple = T; }
/// Set the module-scope inline assembly blocks.
- void setModuleInlineAsm(StringRef Asm) { GlobalScopeAsm = Asm; }
+ void setModuleInlineAsm(StringRef Asm) {
+ GlobalScopeAsm = Asm;
+ if (!GlobalScopeAsm.empty() &&
+ GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n')
+ GlobalScopeAsm += '\n';
+ }
/// Append to the module-scope inline assembly blocks, automatically inserting
/// a separating newline if necessary.
void appendModuleInlineAsm(StringRef Asm) {
+ GlobalScopeAsm += Asm;
if (!GlobalScopeAsm.empty() &&
GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n')
GlobalScopeAsm += '\n';
- GlobalScopeAsm += Asm;
}
/// @}
diff --git a/include/llvm/Object/MachOFormat.h b/include/llvm/Object/MachOFormat.h
new file mode 100644
index 0000000000..31cd523ea2
--- /dev/null
+++ b/include/llvm/Object/MachOFormat.h
@@ -0,0 +1,367 @@
+//===- MachOFormat.h - Mach-O Format Structures And Constants ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares various structures and constants which are platform
+// independent and can be shared by any client which wishes to interact with
+// Mach object files.
+//
+// The definitions here are purposely chosen to match the LLVM style as opposed
+// to following the platform specific definition of the format.
+//
+// On a Mach system, see the <mach-o/...> includes for more information, in
+// particular <mach-o/loader.h>.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHOFORMAT_H
+#define LLVM_OBJECT_MACHOFORMAT_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+namespace object {
+
+/// General Mach platform information.
+namespace mach {
+ /// @name CPU Type and Subtype Information
+ /// {
+
+ /// \brief Capability bits used in CPU type encoding.
+ enum CPUTypeFlagsMask {
+ CTFM_ArchMask = 0xFF000000,
+ CTFM_ArchABI64 = 0x01000000
+ };
+
+ /// \brief Machine type IDs used in CPU type encoding.
+ enum CPUTypeMachine {
+ CTM_i386 = 7,
+ CTM_x86_64 = CTM_i386 | CTFM_ArchABI64,
+ CTM_ARM = 12,
+ CTM_SPARC = 14,
+ CTM_PowerPC = 18,
+ CTM_PowerPC64 = CTM_PowerPC | CTFM_ArchABI64
+ };
+
+ /// \brief Capability bits used in CPU subtype encoding.
+ enum CPUSubtypeFlagsMask {
+ CSFM_SubtypeMask = 0xFF000000,
+ CSFM_SubtypeLib64 = 0x80000000
+ };
+
+ /// \brief ARM Machine Subtypes.
+ enum CPUSubtypeARM {
+ CSARM_ALL = 0,
+ CSARM_V4T = 5,
+ CSARM_V6 = 6,
+ CSARM_V5TEJ = 7,
+ CSARM_XSCALE = 8,
+ CSARM_V7 = 9
+ };
+
+ /// \brief PowerPC Machine Subtypes.
+ enum CPUSubtypePowerPC {
+ CSPPC_ALL = 0
+ };
+
+ /// \brief SPARC Machine Subtypes.
+ enum CPUSubtypeSPARC {
+ CSSPARC_ALL = 0
+ };
+
+ /// \brief x86 Machine Subtypes.
+ enum CPUSubtypeX86 {
+ CSX86_ALL = 3
+ };
+
+ /// @}
+
+} // end namespace mach
+
+/// Format information for Mach object files.
+namespace macho {
+ /// \brief Constants for structure sizes.
+ enum StructureSizes {
+ Header32Size = 28,
+ Header64Size = 32,
+ SegmentLoadCommand32Size = 56,
+ SegmentLoadCommand64Size = 72,
+ Section32Size = 68,
+ Section64Size = 80,
+ SymtabLoadCommandSize = 24,
+ DysymtabLoadCommandSize = 80,
+ Nlist32Size = 12,
+ Nlist64Size = 16,
+ RelocationInfoSize = 8
+ };
+
+ /// \brief Constants for header magic field.
+ enum HeaderMagic {
+ HM_Object32 = 0xFEEDFACE, ///< 32-bit mach object file
+ HM_Object64 = 0xFEEDFACF, ///< 64-bit mach object file
+ HM_Universal = 0xCAFEBABE ///< Universal object file
+ };
+
+ /// \brief Header common to all Mach object files.
+ struct Header {
+ uint32_t Magic;
+ uint32_t CPUType;
+ uint32_t CPUSubtype;
+ uint32_t FileType;
+ uint32_t NumLoadCommands;
+ uint32_t SizeOfLoadCommands;
+ uint32_t Flags;
+ };
+
+ /// \brief Extended header for 64-bit object files.
+ struct Header64Ext {
+ uint32_t Reserved;
+ };
+
+ // See <mach-o/loader.h>.
+ enum HeaderFileType {
+ HFT_Object = 0x1
+ };
+
+ enum HeaderFlags {
+ HF_SubsectionsViaSymbols = 0x2000
+ };
+
+ enum LoadCommandType {
+ LCT_Segment = 0x1,
+ LCT_Symtab = 0x2,
+ LCT_Dysymtab = 0xb,
+ LCT_Segment64 = 0x19,
+ LCT_UUID = 0x1b
+ };
+
+ /// \brief Load command structure.
+ struct LoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+ };
+
+ /// @name Load Command Structures
+ /// @{
+
+ struct SegmentLoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+ char Name[16];
+ uint32_t VMAddress;
+ uint32_t VMSize;
+ uint32_t FileOffset;
+ uint32_t FileSize;
+ uint32_t MaxVMProtection;
+ uint32_t InitialVMProtection;
+ uint32_t NumSections;
+ uint32_t Flags;
+ };
+
+ struct Segment64LoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+ char Name[16];
+ uint64_t VMAddress;
+ uint64_t VMSize;
+ uint64_t FileOffset;
+ uint64_t FileSize;
+ uint32_t MaxVMProtection;
+ uint32_t InitialVMProtection;
+ uint32_t NumSections;
+ uint32_t Flags;
+ };
+
+ struct SymtabLoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+ uint32_t SymbolTableOffset;
+ uint32_t NumSymbolTableEntries;
+ uint32_t StringTableOffset;
+ uint32_t StringTableSize;
+ };
+
+ struct DysymtabLoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+
+ uint32_t LocalSymbolsIndex;
+ uint32_t NumLocalSymbols;
+
+ uint32_t ExternalSymbolsIndex;
+ uint32_t NumExternalSymbols;
+
+ uint32_t UndefinedSymbolsIndex;
+ uint32_t NumUndefinedSymbols;
+
+ uint32_t TOCOffset;
+ uint32_t NumTOCEntries;
+
+ uint32_t ModuleTableOffset;
+ uint32_t NumModuleTableEntries;
+
+ uint32_t ReferenceSymbolTableOffset;
+ uint32_t NumReferencedSymbolTableEntries;
+
+ uint32_t IndirectSymbolTableOffset;
+ uint32_t NumIndirectSymbolTableEntries;
+
+ uint32_t ExternalRelocationTableOffset;
+ uint32_t NumExternalRelocationTableEntries;
+
+ uint32_t LocalRelocationTableOffset;
+ uint32_t NumLocalRelocationTableEntries;
+ };
+
+ /// @}
+ /// @name Section Data
+ /// @{
+
+ struct Section {
+ char Name[16];
+ char SegmentName[16];
+ uint32_t Address;
+ uint32_t Size;
+ uint32_t Offset;
+ uint32_t Align;
+ uint32_t RelocationTableOffset;
+ uint32_t NumRelocationTableEntries;
+ uint32_t Flags;
+ uint32_t Reserved1;
+ uint32_t Reserved2;
+ };
+ struct Section64 {
+ char Name[16];
+ char SegmentName[16];
+ uint64_t Address;
+ uint64_t Size;
+ uint32_t Offset;
+ uint32_t Align;
+ uint32_t RelocationTableOffset;
+ uint32_t NumRelocationTableEntries;
+ uint32_t Flags;
+ uint32_t Reserved1;
+ uint32_t Reserved2;
+ uint32_t Reserved3;
+ };
+
+ /// @}
+ /// @name Symbol Table Entries
+ /// @{
+
+ struct SymbolTableEntry {
+ uint32_t StringIndex;
+ uint8_t Type;
+ uint8_t SectionIndex;
+ uint16_t Flags;
+ uint32_t Value;
+ };
+ struct Symbol64TableEntry {
+ uint32_t StringIndex;
+ uint8_t Type;
+ uint8_t SectionIndex;
+ uint16_t Flags;
+ uint64_t Value;
+ };
+
+ /// @}
+ /// @name Indirect Symbol Table
+ /// @{
+
+ struct IndirectSymbolTableEntry {
+ uint32_t Index;
+ };
+
+ /// @}
+ /// @name Relocation Data
+ /// @{
+
+ struct RelocationEntry {
+ uint32_t Word0;
+ uint32_t Word1;
+ };
+
+ /// @}
+
+ // See <mach-o/nlist.h>.
+ enum SymbolTypeType {
+ STT_Undefined = 0x00,
+ STT_Absolute = 0x02,
+ STT_Section = 0x0e
+ };
+
+ enum SymbolTypeFlags {
+ // If any of these bits are set, then the entry is a stab entry number (see
+ // <mach-o/stab.h>. Otherwise the other masks apply.
+ STF_StabsEntryMask = 0xe0,
+
+ STF_TypeMask = 0x0e,
+ STF_External = 0x01,
+ STF_PrivateExtern = 0x10
+ };
+
+ /// IndirectSymbolFlags - Flags for encoding special values in the indirect
+ /// symbol entry.
+ enum IndirectSymbolFlags {
+ ISF_Local = 0x80000000,
+ ISF_Absolute = 0x40000000
+ };
+
+ /// RelocationFlags - Special flags for addresses.
+ enum RelocationFlags {
+ RF_Scattered = 0x80000000
+ };
+
+ /// Common relocation info types.
+ enum RelocationInfoType {
+ RIT_Vanilla = 0,
+ RIT_Pair = 1,
+ RIT_Difference = 2
+ };
+
+ /// Generic relocation info types, which are shared by some (but not all)
+ /// platforms.
+ enum RelocationInfoType_Generic {
+ RIT_Generic_PreboundLazyPointer = 3,
+ RIT_Generic_LocalDifference = 4,
+ RIT_Generic_TLV = 5
+ };
+
+ /// X86_64 uses its own relocation types.
+ enum RelocationInfoTypeX86_64 {
+ // Note that x86_64 doesn't even share the common relocation types.
+ RIT_X86_64_Unsigned = 0,
+ RIT_X86_64_Signed = 1,
+ RIT_X86_64_Branch = 2,
+ RIT_X86_64_GOTLoad = 3,
+ RIT_X86_64_GOT = 4,
+ RIT_X86_64_Subtractor = 5,
+ RIT_X86_64_Signed1 = 6,
+ RIT_X86_64_Signed2 = 7,
+ RIT_X86_64_Signed4 = 8,
+ RIT_X86_64_TLV = 9
+ };
+
+ /// ARM uses its own relocation types.
+ enum RelocationInfoTypeARM {
+ RIT_ARM_LocalDifference = 3,
+ RIT_ARM_PreboundLazyPointer = 4,
+ RIT_ARM_Branch24Bit = 5,
+ RIT_ARM_ThumbBranch22Bit = 6,
+ RIT_ARM_ThumbBranch32Bit = 7,
+ RIT_ARM_Half = 8,
+ RIT_ARM_HalfDifference = 9
+
+ };
+
+} // end namespace macho
+
+} // end namespace object
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h
new file mode 100644
index 0000000000..03d9c147b4
--- /dev/null
+++ b/include/llvm/Object/MachOObject.h
@@ -0,0 +1,180 @@
+//===- MachOObject.h - Mach-O Object File Wrapper ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHOOBJECT_H
+#define LLVM_OBJECT_MACHOOBJECT_H
+
+#include <string>
+#include "llvm/ADT/InMemoryStruct.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/MachOFormat.h"
+
+namespace llvm {
+
+class MemoryBuffer;
+
+namespace object {
+
+/// \brief Wrapper object for manipulating Mach-O object files.
+///
+/// This class is designed to implement a full-featured, efficient, portable,
+/// and robust Mach-O interface to Mach-O object files. It does not attempt to
+/// smooth over rough edges in the Mach-O format or generalize access to object
+/// independent features.
+///
+/// The class is designed around accessing the Mach-O object which is expected
+/// to be fully loaded into memory.
+///
+/// This class is *not* suitable for concurrent use. For efficient operation,
+/// the class uses APIs which rely on the ability to cache the results of
+/// certain calls in internal objects which are not safe for concurrent
+/// access. This allows the API to be zero-copy on the common paths.
+//
+// FIXME: It would be cool if we supported a "paged" MemoryBuffer
+// implementation. This would allow us to implement a more sensible version of
+// MemoryObject which can work like a MemoryBuffer, but be more efficient for
+// objects which are in the current address space.
+class MachOObject {
+public:
+ struct LoadCommandInfo {
+ /// The load command information.
+ macho::LoadCommand Command;
+
+ /// The offset to the start of the load command in memory.
+ uint64_t Offset;
+ };
+
+private:
+ OwningPtr<MemoryBuffer> Buffer;
+
+ /// Whether the object is little endian.
+ bool IsLittleEndian;
+ /// Whether the object is 64-bit.
+ bool Is64Bit;
+ /// Whether the object is swapped endianness from the host.
+ bool IsSwappedEndian;
+ /// Whether the string table has been registered.
+ bool HasStringTable;
+
+ /// The cached information on the load commands.
+ LoadCommandInfo *LoadCommands;
+ mutable unsigned NumLoadedCommands;
+
+ /// The cached copy of the header.
+ macho::Header Header;
+ macho::Header64Ext Header64Ext;
+
+ /// Cache string table information.
+ StringRef StringTable;
+
+private:
+ MachOObject(MemoryBuffer *Buffer, bool IsLittleEndian, bool Is64Bit);
+
+public:
+ ~MachOObject();
+
+ /// \brief Load a Mach-O object from a MemoryBuffer object.
+ ///
+ /// \param Buffer - The buffer to load the object from. This routine takes
+ /// exclusive ownership of the buffer (which is passed to the returned object
+ /// on success).
+ /// \param ErrorStr [out] - If given, will be set to a user readable error
+ /// message on failure.
+ /// \returns The loaded object, or null on error.
+ static MachOObject *LoadFromBuffer(MemoryBuffer *Buffer,
+ std::string *ErrorStr = 0);
+
+ /// @name File Information
+ /// @{
+
+ bool isLittleEndian() const { return IsLittleEndian; }
+ bool isSwappedEndian() const { return IsSwappedEndian; }
+ bool is64Bit() const { return Is64Bit; }
+
+ unsigned getHeaderSize() const {
+ return Is64Bit ? macho::Header64Size : macho::Header32Size;
+ }
+
+ StringRef getData(size_t Offset, size_t Size) const;
+
+ /// @}
+ /// @name String Table Data
+ /// @{
+
+ StringRef getStringTableData() const {
+ assert(HasStringTable && "String table has not been registered!");
+ return StringTable;
+ }
+
+ StringRef getStringAtIndex(unsigned Index) const {
+ size_t End = getStringTableData().find('\0', Index);
+ return getStringTableData().slice(Index, End);
+ }
+
+ void RegisterStringTable(macho::SymtabLoadCommand &SLC);
+
+ /// @}
+ /// @name Object Header Access
+ /// @{
+
+ const macho::Header &getHeader() const { return Header; }
+ const macho::Header64Ext &getHeader64Ext() const {
+ assert(is64Bit() && "Invalid access!");
+ return Header64Ext;
+ }
+
+ /// @}
+ /// @name Object Structure Access
+ /// @{
+
+ /// \brief Retrieve the information for the given load command.
+ const LoadCommandInfo &getLoadCommandInfo(unsigned Index) const;
+
+ void ReadSegmentLoadCommand(
+ const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::SegmentLoadCommand> &Res) const;
+ void ReadSegment64LoadCommand(
+ const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::Segment64LoadCommand> &Res) const;
+ void ReadSymtabLoadCommand(
+ const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::SymtabLoadCommand> &Res) const;
+ void ReadDysymtabLoadCommand(
+ const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::DysymtabLoadCommand> &Res) const;
+ void ReadIndirectSymbolTableEntry(
+ const macho::DysymtabLoadCommand &DLC,
+ unsigned Index,
+ InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const;
+ void ReadSection(
+ const LoadCommandInfo &LCI,
+ unsigned Index,
+ InMemoryStruct<macho::Section> &Res) const;
+ void ReadSection64(
+ const LoadCommandInfo &LCI,
+ unsigned Index,
+ InMemoryStruct<macho::Section64> &Res) const;
+ void ReadRelocationEntry(
+ uint64_t RelocationTableOffset, unsigned Index,
+ InMemoryStruct<macho::RelocationEntry> &Res) const;
+ void ReadSymbolTableEntry(
+ uint64_t SymbolTableOffset, unsigned Index,
+ InMemoryStruct<macho::SymbolTableEntry> &Res) const;
+ void ReadSymbol64TableEntry(
+ uint64_t SymbolTableOffset, unsigned Index,
+ InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
+
+ /// @}
+};
+
+} // end namespace object
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index ca51581434..eee9d447cd 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -15,7 +15,8 @@
#define LLVM_OBJECT_OBJECT_FILE_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
+#include <cstring>
namespace llvm {
@@ -25,7 +26,19 @@ class StringRef;
namespace object {
class ObjectFile;
-typedef uint64_t DataRefImpl;
+
+union DataRefImpl {
+ struct {
+ uint32_t a, b;
+ } d;
+ intptr_t p;
+};
+
+static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
+ // Check bitwise identical. This is the only legal way to compare a union w/o
+ // knowing which member is in use.
+ return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
+}
/// SymbolRef - This is a value type class that represents a single symbol in
/// the list of symbols in the object file.
diff --git a/include/llvm/OperandTraits.h b/include/llvm/OperandTraits.h
index b614ccbc37..f0df5fa9bd 100644
--- a/include/llvm/OperandTraits.h
+++ b/include/llvm/OperandTraits.h
@@ -27,27 +27,17 @@ namespace llvm {
/// when it is a prefix to the User object, and the number of Use objects is
/// known at compile time.
-template <unsigned ARITY>
+template <typename SubClass, unsigned ARITY>
struct FixedNumOperandTraits {
- static Use *op_begin(User* U) {
+ static Use *op_begin(SubClass* U) {
return reinterpret_cast<Use*>(U) - ARITY;
}
- static Use *op_end(User* U) {
+ static Use *op_end(SubClass* U) {
return reinterpret_cast<Use*>(U);
}
static unsigned operands(const User*) {
return ARITY;
}
- struct prefix {
- Use Ops[ARITY];
- prefix(); // DO NOT IMPLEMENT
- };
- template <class U>
- struct Layout {
- struct overlay : public prefix, public U {
- overlay(); // DO NOT IMPLEMENT
- };
- };
};
//===----------------------------------------------------------------------===//
@@ -57,8 +47,8 @@ struct FixedNumOperandTraits {
/// OptionalOperandTraits - when the number of operands may change at runtime.
/// Naturally it may only decrease, because the allocations may not change.
-template <unsigned ARITY = 1>
-struct OptionalOperandTraits : public FixedNumOperandTraits<ARITY> {
+template <typename SubClass, unsigned ARITY = 1>
+struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> {
static unsigned operands(const User *U) {
return U->getNumOperands();
}
@@ -72,12 +62,12 @@ struct OptionalOperandTraits : public FixedNumOperandTraits<ARITY> {
/// when it is a prefix to the User object, and the number of Use objects is
/// only known at allocation time.
-template <unsigned MINARITY = 0>
+template <typename SubClass, unsigned MINARITY = 0>
struct VariadicOperandTraits {
- static Use *op_begin(User* U) {
- return reinterpret_cast<Use*>(U) - U->getNumOperands();
+ static Use *op_begin(SubClass* U) {
+ return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands();
}
- static Use *op_end(User* U) {
+ static Use *op_end(SubClass* U) {
return reinterpret_cast<Use*>(U);
}
static unsigned operands(const User *U) {
diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h
index 3aae586f14..ff2a0ad5e4 100644
--- a/include/llvm/Operator.h
+++ b/include/llvm/Operator.h
@@ -106,12 +106,14 @@ public:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Add ||
I->getOpcode() == Instruction::Sub ||
- I->getOpcode() == Instruction::Mul;
+ I->getOpcode() == Instruction::Mul ||
+ I->getOpcode() == Instruction::Shl;
}
static inline bool classof(const ConstantExpr *CE) {
return CE->getOpcode() == Instruction::Add ||
CE->getOpcode() == Instruction::Sub ||
- CE->getOpcode() == Instruction::Mul;
+ CE->getOpcode() == Instruction::Mul ||
+ CE->getOpcode() == Instruction::Shl;
}
static inline bool classof(const Value *V) {
return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
@@ -119,105 +121,97 @@ public:
}
};
-/// AddOperator - Utility class for integer addition operators.
-///
-class AddOperator : public OverflowingBinaryOperator {
- ~AddOperator(); // do not implement
-public:
- static inline bool classof(const AddOperator *) { return true; }
- static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::Add;
- }
- static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::Add;
- }
- static inline bool classof(const Value *V) {
- return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
- (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
- }
-};
-
-/// SubOperator - Utility class for integer subtraction operators.
-///
-class SubOperator : public OverflowingBinaryOperator {
- ~SubOperator(); // do not implement
-public:
- static inline bool classof(const SubOperator *) { return true; }
- static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::Sub;
- }
- static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::Sub;
- }
- static inline bool classof(const Value *V) {
- return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
- (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
- }
-};
-
-/// MulOperator - Utility class for integer multiplication operators.
-///
-class MulOperator : public OverflowingBinaryOperator {
- ~MulOperator(); // do not implement
-public:
- static inline bool classof(const MulOperator *) { return true; }
- static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::Mul;
- }
- static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::Mul;
- }
- static inline bool classof(const Value *V) {
- return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
- (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
- }
-};
-
-/// SDivOperator - An Operator with opcode Instruction::SDiv.
-///
-class SDivOperator : public Operator {
+/// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as
+/// "exact", indicating that no bits are destroyed.
+class PossiblyExactOperator : public Operator {
public:
enum {
IsExact = (1 << 0)
};
-
-private:
- ~SDivOperator(); // do not implement
-
+
friend class BinaryOperator;
friend class ConstantExpr;
void setIsExact(bool B) {
SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
}
-
+
+private:
+ ~PossiblyExactOperator(); // do not implement
public:
/// isExact - Test whether this division is known to be exact, with
/// zero remainder.
bool isExact() const {
return SubclassOptionalData & IsExact;
}
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const SDivOperator *) { return true; }
+
+ static bool isPossiblyExactOpcode(unsigned OpC) {
+ return OpC == Instruction::SDiv ||
+ OpC == Instruction::UDiv ||
+ OpC == Instruction::AShr ||
+ OpC == Instruction::LShr;
+ }
static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::SDiv;
+ return isPossiblyExactOpcode(CE->getOpcode());
}
static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::SDiv;
+ return isPossiblyExactOpcode(I->getOpcode());
}
static inline bool classof(const Value *V) {
return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
(isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
}
};
+
-class GEPOperator : public Operator {
+
+/// ConcreteOperator - A helper template for defining operators for individual
+/// opcodes.
+template<typename SuperClass, unsigned Opc>
+class ConcreteOperator : public SuperClass {
+ ~ConcreteOperator(); // DO NOT IMPLEMENT
+public:
+ static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) {
+ return true;
+ }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Opc;
+ }
+ static inline bool classof(const ConstantExpr *CE) {
+ return CE->getOpcode() == Opc;
+ }
+ static inline bool classof(const Value *V) {
+ return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
+ (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+ }
+};
+
+class AddOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {};
+class SubOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {};
+class MulOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {};
+class ShlOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {};
+
+
+class SDivOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {};
+class UDivOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {};
+class AShrOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {};
+class LShrOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {};
+
+
+
+class GEPOperator
+ : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
enum {
IsInBounds = (1 << 0)
};
- ~GEPOperator(); // do not implement
-
friend class GetElementPtrInst;
friend class ConstantExpr;
void setIsInBounds(bool B) {
@@ -266,8 +260,8 @@ public:
/// value, just potentially different types.
bool hasAllZeroIndices() const {
for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
- if (Constant *C = dyn_cast<Constant>(I))
- if (C->isNullValue())
+ if (ConstantInt *C = dyn_cast<ConstantInt>(I))
+ if (C->isZero())
continue;
return false;
}
@@ -284,21 +278,6 @@ public:
}
return true;
}
-
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const GEPOperator *) { return true; }
- static inline bool classof(const GetElementPtrInst *) { return true; }
- static inline bool classof(const ConstantExpr *CE) {
- return CE->getOpcode() == Instruction::GetElementPtr;
- }
- static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Instruction::GetElementPtr;
- }
- static inline bool classof(const Value *V) {
- return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
- (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
- }
};
} // End llvm namespace
diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h
index d00d0c0d6d..082790956c 100644
--- a/include/llvm/PassSupport.h
+++ b/include/llvm/PassSupport.h
@@ -24,7 +24,7 @@
#include "Pass.h"
#include "llvm/PassRegistry.h"
#include "llvm/InitializePasses.h"
-#include "llvm/System/Atomic.h"
+#include "llvm/Support/Atomic.h"
#include <vector>
namespace llvm {
diff --git a/include/llvm/System/AIXDataTypesFix.h b/include/llvm/Support/AIXDataTypesFix.h
index 8dbf02f282..a9a9147de2 100644
--- a/include/llvm/System/AIXDataTypesFix.h
+++ b/include/llvm/Support/AIXDataTypesFix.h
@@ -1,4 +1,4 @@
-//===-- llvm/System/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
+//===-- llvm/Support/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
index 979e5975aa..cebfa7982d 100644
--- a/include/llvm/Support/AlignOf.h
+++ b/include/llvm/Support/AlignOf.h
@@ -49,7 +49,7 @@ struct AlignOf {
};
-/// alignOf - A templated function that returns the mininum alignment of
+/// alignOf - A templated function that returns the minimum alignment of
/// of a type. This provides no extra functionality beyond the AlignOf
/// class besides some cosmetic cleanliness. Example usage:
/// alignOf<int>() returns the alignment of an int.
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index f3c53d14e5..c6807099f8 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -16,13 +16,15 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <cstddef>
namespace llvm {
+template <typename T> struct ReferenceAdder { typedef T& result; };
+template <typename T> struct ReferenceAdder<T&> { typedef T result; };
class MallocAllocator {
public:
diff --git a/include/llvm/System/Atomic.h b/include/llvm/Support/Atomic.h
index fc19369d11..1a6c606aa5 100644
--- a/include/llvm/System/Atomic.h
+++ b/include/llvm/Support/Atomic.h
@@ -1,4 +1,4 @@
-//===- llvm/System/Atomic.h - Atomic Operations -----------------*- C++ -*-===//
+//===- llvm/Support/Atomic.h - Atomic Operations -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,7 +14,7 @@
#ifndef LLVM_SYSTEM_ATOMIC_H
#define LLVM_SYSTEM_ATOMIC_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
namespace sys {
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
index 9ba71fcca8..d2ea12364e 100644
--- a/include/llvm/Support/CFG.h
+++ b/include/llvm/Support/CFG.h
@@ -41,6 +41,7 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
public:
typedef typename super::pointer pointer;
+ PredIterator() {}
explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) {
advancePastNonTerminators();
}
@@ -64,6 +65,12 @@ public:
inline Self operator++(int) { // Postincrement
Self tmp = *this; ++*this; return tmp;
}
+
+ /// getOperandNo - Return the operand number in the predecessor's
+ /// terminator of the successor.
+ unsigned getOperandNo() const {
+ return It.getOperandNo();
+ }
};
typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 46fe269a23..673925593e 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -23,7 +23,7 @@
#ifndef LLVM_SUPPORT_WIN_COFF_H
#define LLVM_SUPPORT_WIN_COFF_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cstring>
namespace llvm {
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index 571a04924d..8a998a8cd0 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -52,11 +52,6 @@ public:
CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); }
CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); }
CallSiteBase(ValTy *II) { *this = get(II); }
- CallSiteBase(InstrTy *II) {
- assert(II && "Null instruction given?");
- *this = get(II);
- assert(I.getPointer() && "Not a call?");
- }
protected:
/// CallSiteBase::get - This static method is sort of like a constructor. It
/// will create an appropriate call site for a Call or Invoke instruction, but
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 6ac7f9c0b0..67f0fd7e0d 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -15,6 +15,10 @@
#ifndef LLVM_SUPPORT_COMPILER_H
#define LLVM_SUPPORT_COMPILER_H
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
/// into a shared library, then the class should be private to the library and
/// not accessible from outside it. Can also be used to mark variables and
@@ -107,4 +111,19 @@
#define LLVM_ATTRIBUTE_NORETURN
#endif
+// LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
+#if __has_feature(attribute_deprecated_with_message)
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+ decl __attribute__((deprecated(message)))
+#elif defined(__GNUC__)
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+ decl __attribute__((deprecated))
+#elif defined(_MSC_VER)
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+ __declspec(deprecated(message)) decl
+#else
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+ decl
+#endif
+
#endif
diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h
index ea6c5fd82a..bd3765d592 100644
--- a/include/llvm/Support/ConstantFolder.h
+++ b/include/llvm/Support/ConstantFolder.h
@@ -33,50 +33,34 @@ public:
// Binary Operators
//===--------------------------------------------------------------------===//
- Constant *CreateAdd(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getAdd(LHS, RHS);
- }
- Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getNSWAdd(LHS, RHS);
- }
- Constant *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getNUWAdd(LHS, RHS);
+ Constant *CreateAdd(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW);
}
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFAdd(LHS, RHS);
}
- Constant *CreateSub(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getSub(LHS, RHS);
- }
- Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getNSWSub(LHS, RHS);
- }
- Constant *CreateNUWSub(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getNUWSub(LHS, RHS);
+ Constant *CreateSub(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW);
}
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFSub(LHS, RHS);
}
- Constant *CreateMul(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getMul(LHS, RHS);
- }
- Constant *CreateNSWMul(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getNSWMul(LHS, RHS);
- }
- Constant *CreateNUWMul(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getNUWMul(LHS, RHS);
+ Constant *CreateMul(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW);
}
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFMul(LHS, RHS);
}
- Constant *CreateUDiv(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getUDiv(LHS, RHS);
- }
- Constant *CreateSDiv(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getSDiv(LHS, RHS);
+ Constant *CreateUDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ return ConstantExpr::getUDiv(LHS, RHS, isExact);
}
- Constant *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getExactSDiv(LHS, RHS);
+ Constant *CreateSDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ return ConstantExpr::getSDiv(LHS, RHS, isExact);
}
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFDiv(LHS, RHS);
@@ -90,14 +74,17 @@ public:
Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFRem(LHS, RHS);
}
- Constant *CreateShl(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getShl(LHS, RHS);
+ Constant *CreateShl(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW);
}
- Constant *CreateLShr(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getLShr(LHS, RHS);
+ Constant *CreateLShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ return ConstantExpr::getLShr(LHS, RHS, isExact);
}
- Constant *CreateAShr(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getAShr(LHS, RHS);
+ Constant *CreateAShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ return ConstantExpr::getAShr(LHS, RHS, isExact);
}
Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getAnd(LHS, RHS);
@@ -118,14 +105,9 @@ public:
// Unary Operators
//===--------------------------------------------------------------------===//
- Constant *CreateNeg(Constant *C) const {
- return ConstantExpr::getNeg(C);
- }
- Constant *CreateNSWNeg(Constant *C) const {
- return ConstantExpr::getNSWNeg(C);
- }
- Constant *CreateNUWNeg(Constant *C) const {
- return ConstantExpr::getNUWNeg(C);
+ Constant *CreateNeg(Constant *C,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return ConstantExpr::getNeg(C, HasNUW, HasNSW);
}
Constant *CreateFNeg(Constant *C) const {
return ConstantExpr::getFNeg(C);
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
index 792b4107b1..ced3a2cf2d 100644
--- a/include/llvm/Support/ConstantRange.h
+++ b/include/llvm/Support/ConstantRange.h
@@ -33,7 +33,7 @@
#define LLVM_SUPPORT_CONSTANT_RANGE_H
#include "llvm/ADT/APInt.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -54,7 +54,7 @@ public:
/// @brief Initialize a range of values explicitly. This will assert out if
/// Lower==Upper and Lower != Min or Max value for its type. It will also
/// assert out if the two APInt's are not the same bit width.
- ConstantRange(const APInt& Lower, const APInt& Upper);
+ ConstantRange(const APInt &Lower, const APInt &Upper);
/// makeICmpRegion - Produce the smallest range that contains all values that
/// might satisfy the comparison specified by Pred when compared to any value
diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h
index 796c74a21c..3cb8164c3c 100644
--- a/include/llvm/Support/DOTGraphTraits.h
+++ b/include/llvm/Support/DOTGraphTraits.h
@@ -89,8 +89,9 @@ public:
/// If you want to override the dot attributes printed for a particular edge,
/// override this method.
- template<typename EdgeIter>
- static std::string getEdgeAttributes(const void *Node, EdgeIter EI) {
+ template<typename EdgeIter, typename GraphType>
+ static std::string getEdgeAttributes(const void *Node, EdgeIter EI,
+ const GraphType& Graph) {
return "";
}
diff --git a/include/llvm/System/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
index 9efe75a56e..72c451873c 100644
--- a/include/llvm/System/DataTypes.h.cmake
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -1,4 +1,4 @@
-/*===-- include/System/DataTypes.h - Define fixed size types -----*- C -*-===*\
+/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
@@ -43,12 +43,12 @@
happening when system headers or C++ STL headers include stdint.h before we
define it here, we define it on the g++ command line (in Makefile.rules). */
#if !defined(__STDC_LIMIT_MACROS)
-# error "Must #define __STDC_LIMIT_MACROS before #including System/DataTypes.h"
+# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
#endif
#if !defined(__STDC_CONSTANT_MACROS)
# error "Must #define __STDC_CONSTANT_MACROS before " \
- "#including System/DataTypes.h"
+ "#including Support/DataTypes.h"
#endif
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
@@ -65,7 +65,7 @@
#endif
#ifdef _AIX
-#include "llvm/System/AIXDataTypesFix.h"
+#include "llvm/Support/AIXDataTypesFix.h"
#endif
/* Handle incorrect definition of uint64_t as u_int64_t */
diff --git a/include/llvm/System/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
index 6537f3010f..5965e8c0b2 100644
--- a/include/llvm/System/DataTypes.h.in
+++ b/include/llvm/Support/DataTypes.h.in
@@ -63,7 +63,7 @@
#endif
#ifdef _AIX
-#include "llvm/System/AIXDataTypesFix.h"
+#include "llvm/Support/AIXDataTypesFix.h"
#endif
/* Handle incorrect definition of uint64_t as u_int64_t */
diff --git a/include/llvm/System/Disassembler.h b/include/llvm/Support/Disassembler.h
index e11e792de8..6d1cc0fdcb 100644
--- a/include/llvm/System/Disassembler.h
+++ b/include/llvm/Support/Disassembler.h
@@ -15,7 +15,7 @@
#ifndef LLVM_SYSTEM_DISASSEMBLER_H
#define LLVM_SYSTEM_DISASSEMBLER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index 1b5d2a4538..5d0b5a943d 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -45,11 +45,9 @@ enum llvm_dwarf_constants {
// llvm mock tags
DW_TAG_invalid = ~0U, // Tag for invalid results.
- DW_TAG_anchor = 0, // Tag for descriptor anchors.
DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
DW_TAG_arg_variable = 0x101, // Tag for argument variables.
DW_TAG_return_variable = 0x102, // Tag for return variables.
-
DW_TAG_vector_type = 0x103, // Tag for vector types.
DW_TAG_user_base = 0x1000, // Recommended base for user tags.
@@ -119,6 +117,7 @@ enum dwarf_constants {
DW_TAG_imported_unit = 0x3d,
DW_TAG_condition = 0x3f,
DW_TAG_shared_type = 0x40,
+ DW_TAG_rvalue_reference_type = 0x41,
DW_TAG_lo_user = 0x4080,
DW_TAG_hi_user = 0xffff,
diff --git a/include/llvm/System/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h
index 745b8f8b5b..e6d9ff57ae 100644
--- a/include/llvm/System/DynamicLibrary.h
+++ b/include/llvm/Support/DynamicLibrary.h
@@ -1,4 +1,4 @@
-//===-- llvm/System/DynamicLibrary.h - Portable Dynamic Library -*- C++ -*-===//
+//===-- llvm/Support/DynamicLibrary.h - Portable Dynamic Library -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/llvm/Support/DynamicLinker.h b/include/llvm/Support/DynamicLinker.h
deleted file mode 100644
index b60ffa875c..0000000000
--- a/include/llvm/Support/DynamicLinker.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===-- llvm/Support/DynamicLinker.h - Portable Dynamic Linker --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Lightweight interface to dynamic library linking and loading, and dynamic
-// symbol lookup functionality, in whatever form the operating system
-// provides it.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_DYNAMICLINKER_H
-#define LLVM_SUPPORT_DYNAMICLINKER_H
-
-#include <string>
-
-namespace llvm {
-
-/// LinkDynamicObject - Load the named file as a dynamic library
-/// and link it with the currently running process. Returns false
-/// on success, true if there is an error (and sets ErrorMessage
-/// if it is not NULL). Analogous to dlopen().
-///
-bool LinkDynamicObject (const char *filename, std::string *ErrorMessage);
-
-/// GetAddressOfSymbol - Returns the address of the named symbol in
-/// the currently running process, as reported by the dynamic linker,
-/// or NULL if the symbol does not exist or some other error has
-/// occurred.
-///
-void *GetAddressOfSymbol (const char *symbolName);
-void *GetAddressOfSymbol (const std::string &symbolName);
-
-} // End llvm namespace
-
-#endif // SUPPORT_DYNAMICLINKER_H
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index c6304aa34b..cc72bd59cb 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -20,7 +20,7 @@
#ifndef LLVM_SUPPORT_ELF_H
#define LLVM_SUPPORT_ELF_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cstring>
namespace llvm {
@@ -146,6 +146,7 @@ enum {
// Object file classes.
enum {
+ ELFCLASSNONE = 0,
ELFCLASS32 = 1, // 32-bit object file
ELFCLASS64 = 2 // 64-bit object file
};
@@ -263,6 +264,175 @@ enum {
R_386_NUM = 43
};
+// MBlaze relocations.
+enum {
+ R_MICROBLAZE_NONE = 0,
+ R_MICROBLAZE_32 = 1,
+ R_MICROBLAZE_32_PCREL = 2,
+ R_MICROBLAZE_64_PCREL = 3,
+ R_MICROBLAZE_32_PCREL_LO = 4,
+ R_MICROBLAZE_64 = 5,
+ R_MICROBLAZE_32_LO = 6,
+ R_MICROBLAZE_SRO32 = 7,
+ R_MICROBLAZE_SRW32 = 8,
+ R_MICROBLAZE_64_NONE = 9,
+ R_MICROBLAZE_32_SYM_OP_SYM = 10,
+ R_MICROBLAZE_GNU_VTINHERIT = 11,
+ R_MICROBLAZE_GNU_VTENTRY = 12,
+ R_MICROBLAZE_GOTPC_64 = 13,
+ R_MICROBLAZE_GOT_64 = 14,
+ R_MICROBLAZE_PLT_64 = 15,
+ R_MICROBLAZE_REL = 16,
+ R_MICROBLAZE_JUMP_SLOT = 17,
+ R_MICROBLAZE_GLOB_DAT = 18,
+ R_MICROBLAZE_GOTOFF_64 = 19,
+ R_MICROBLAZE_GOTOFF_32 = 20,
+ R_MICROBLAZE_COPY = 21
+};
+
+
+// ARM Specific e_flags
+enum { EF_ARM_EABIMASK = 0xFF000000U };
+
+// ELF Relocation types for ARM
+// Meets 2.08 ABI Specs.
+
+enum {
+ R_ARM_NONE = 0x00,
+ R_ARM_PC24 = 0x01,
+ R_ARM_ABS32 = 0x02,
+ R_ARM_REL32 = 0x03,
+ R_ARM_LDR_PC_G0 = 0x04,
+ R_ARM_ABS16 = 0x05,
+ R_ARM_ABS12 = 0x06,
+ R_ARM_THM_ABS5 = 0x07,
+ R_ARM_ABS8 = 0x08,
+ R_ARM_SBREL32 = 0x09,
+ R_ARM_THM_CALL = 0x0a,
+ R_ARM_THM_PC8 = 0x0b,
+ R_ARM_BREL_ADJ = 0x0c,
+ R_ARM_TLS_DESC = 0x0d,
+ R_ARM_THM_SWI8 = 0x0e,
+ R_ARM_XPC25 = 0x0f,
+ R_ARM_THM_XPC22 = 0x10,
+ R_ARM_TLS_DTPMOD32 = 0x11,
+ R_ARM_TLS_DTPOFF32 = 0x12,
+ R_ARM_TLS_TPOFF32 = 0x13,
+ R_ARM_COPY = 0x14,
+ R_ARM_GLOB_DAT = 0x15,
+ R_ARM_JUMP_SLOT = 0x16,
+ R_ARM_RELATIVE = 0x17,
+ R_ARM_GOTOFF32 = 0x18,
+ R_ARM_BASE_PREL = 0x19,
+ R_ARM_GOT_BREL = 0x1a,
+ R_ARM_PLT32 = 0x1b,
+ R_ARM_CALL = 0x1c,
+ R_ARM_JUMP24 = 0x1d,
+ R_ARM_THM_JUMP24 = 0x1e,
+ R_ARM_BASE_ABS = 0x1f,
+ R_ARM_ALU_PCREL_7_0 = 0x20,
+ R_ARM_ALU_PCREL_15_8 = 0x21,
+ R_ARM_ALU_PCREL_23_15 = 0x22,
+ R_ARM_LDR_SBREL_11_0_NC = 0x23,
+ R_ARM_ALU_SBREL_19_12_NC = 0x24,
+ R_ARM_ALU_SBREL_27_20_CK = 0x25,
+ R_ARM_TARGET1 = 0x26,
+ R_ARM_SBREL31 = 0x27,
+ R_ARM_V4BX = 0x28,
+ R_ARM_TARGET2 = 0x29,
+ R_ARM_PREL31 = 0x2a,
+ R_ARM_MOVW_ABS_NC = 0x2b,
+ R_ARM_MOVT_ABS = 0x2c,
+ R_ARM_MOVW_PREL_NC = 0x2d,
+ R_ARM_MOVT_PREL = 0x2e,
+ R_ARM_THM_MOVW_ABS_NC = 0x2f,
+ R_ARM_THM_MOVT_ABS = 0x30,
+ R_ARM_THM_MOVW_PREL_NC = 0x31,
+ R_ARM_THM_MOVT_PREL = 0x32,
+ R_ARM_THM_JUMP19 = 0x33,
+ R_ARM_THM_JUMP6 = 0x34,
+ R_ARM_THM_ALU_PREL_11_0 = 0x35,
+ R_ARM_THM_PC12 = 0x36,
+ R_ARM_ABS32_NOI = 0x37,
+ R_ARM_REL32_NOI = 0x38,
+ R_ARM_ALU_PC_G0_NC = 0x39,
+ R_ARM_ALU_PC_G0 = 0x3a,
+ R_ARM_ALU_PC_G1_NC = 0x3b,
+ R_ARM_ALU_PC_G1 = 0x3c,
+ R_ARM_ALU_PC_G2 = 0x3d,
+ R_ARM_LDR_PC_G1 = 0x3e,
+ R_ARM_LDR_PC_G2 = 0x3f,
+ R_ARM_LDRS_PC_G0 = 0x40,
+ R_ARM_LDRS_PC_G1 = 0x41,
+ R_ARM_LDRS_PC_G2 = 0x42,
+ R_ARM_LDC_PC_G0 = 0x43,
+ R_ARM_LDC_PC_G1 = 0x44,
+ R_ARM_LDC_PC_G2 = 0x45,
+ R_ARM_ALU_SB_G0_NC = 0x46,
+ R_ARM_ALU_SB_G0 = 0x47,
+ R_ARM_ALU_SB_G1_NC = 0x48,
+ R_ARM_ALU_SB_G1 = 0x49,
+ R_ARM_ALU_SB_G2 = 0x4a,
+ R_ARM_LDR_SB_G0 = 0x4b,
+ R_ARM_LDR_SB_G1 = 0x4c,
+ R_ARM_LDR_SB_G2 = 0x4d,
+ R_ARM_LDRS_SB_G0 = 0x4e,
+ R_ARM_LDRS_SB_G1 = 0x4f,
+ R_ARM_LDRS_SB_G2 = 0x50,
+ R_ARM_LDC_SB_G0 = 0x51,
+ R_ARM_LDC_SB_G1 = 0x52,
+ R_ARM_LDC_SB_G2 = 0x53,
+ R_ARM_MOVW_BREL_NC = 0x54,
+ R_ARM_MOVT_BREL = 0x55,
+ R_ARM_MOVW_BREL = 0x56,
+ R_ARM_THM_MOVW_BREL_NC = 0x57,
+ R_ARM_THM_MOVT_BREL = 0x58,
+ R_ARM_THM_MOVW_BREL = 0x59,
+ R_ARM_TLS_GOTDESC = 0x5a,
+ R_ARM_TLS_CALL = 0x5b,
+ R_ARM_TLS_DESCSEQ = 0x5c,
+ R_ARM_THM_TLS_CALL = 0x5d,
+ R_ARM_PLT32_ABS = 0x5e,
+ R_ARM_GOT_ABS = 0x5f,
+ R_ARM_GOT_PREL = 0x60,
+ R_ARM_GOT_BREL12 = 0x61,
+ R_ARM_GOTOFF12 = 0x62,
+ R_ARM_GOTRELAX = 0x63,
+ R_ARM_GNU_VTENTRY = 0x64,
+ R_ARM_GNU_VTINHERIT = 0x65,
+ R_ARM_THM_JUMP11 = 0x66,
+ R_ARM_THM_JUMP8 = 0x67,
+ R_ARM_TLS_GD32 = 0x68,
+ R_ARM_TLS_LDM32 = 0x69,
+ R_ARM_TLS_LDO32 = 0x6a,
+ R_ARM_TLS_IE32 = 0x6b,
+ R_ARM_TLS_LE32 = 0x6c,
+ R_ARM_TLS_LDO12 = 0x6d,
+ R_ARM_TLS_LE12 = 0x6e,
+ R_ARM_TLS_IE12GP = 0x6f,
+ R_ARM_PRIVATE_0 = 0x70,
+ R_ARM_PRIVATE_1 = 0x71,
+ R_ARM_PRIVATE_2 = 0x72,
+ R_ARM_PRIVATE_3 = 0x73,
+ R_ARM_PRIVATE_4 = 0x74,
+ R_ARM_PRIVATE_5 = 0x75,
+ R_ARM_PRIVATE_6 = 0x76,
+ R_ARM_PRIVATE_7 = 0x77,
+ R_ARM_PRIVATE_8 = 0x78,
+ R_ARM_PRIVATE_9 = 0x79,
+ R_ARM_PRIVATE_10 = 0x7a,
+ R_ARM_PRIVATE_11 = 0x7b,
+ R_ARM_PRIVATE_12 = 0x7c,
+ R_ARM_PRIVATE_13 = 0x7d,
+ R_ARM_PRIVATE_14 = 0x7e,
+ R_ARM_PRIVATE_15 = 0x7f,
+ R_ARM_ME_TOO = 0x80,
+ R_ARM_THM_TLS_DESCSEQ16 = 0x81,
+ R_ARM_THM_TLS_DESCSEQ32 = 0x82
+};
+
+
+
// Section header.
struct Elf32_Shdr {
Elf32_Word sh_name; // Section name (index into string table)
@@ -335,6 +505,8 @@ enum {
SHT_ARM_DEBUGOVERLAY = 0x70000004U,
SHT_ARM_OVERLAYSECTION = 0x70000005U,
+ SHT_X86_64_UNWIND = 0x70000001, // Unwind information
+
SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type.
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
@@ -342,10 +514,51 @@ enum {
// Section flags.
enum {
- SHF_WRITE = 0x1, // Section data should be writable during execution.
- SHF_ALLOC = 0x2, // Section occupies memory during program execution.
- SHF_EXECINSTR = 0x4, // Section contains executable machine instructions.
- SHF_MASKPROC = 0xf0000000 // Bits indicating processor-specific flags.
+ // Section data should be writable during execution.
+ SHF_WRITE = 0x1,
+
+ // Section occupies memory during program execution.
+ SHF_ALLOC = 0x2,
+
+ // Section contains executable machine instructions.
+ SHF_EXECINSTR = 0x4,
+
+ // The data in this section may be merged.
+ SHF_MERGE = 0x10,
+
+ // The data in this section is null-terminated strings.
+ SHF_STRINGS = 0x20,
+
+ // A field in this section holds a section header table index.
+ SHF_INFO_LINK = 0x40U,
+
+ // Adds special ordering requirements for link editors.
+ SHF_LINK_ORDER = 0x80U,
+
+ // This section requires special OS-specific processing to avoid incorrect
+ // behavior.
+ SHF_OS_NONCONFORMING = 0x100U,
+
+ // This section is a member of a section group.
+ SHF_GROUP = 0x200U,
+
+ // This section holds Thread-Local Storage.
+ SHF_TLS = 0x400U,
+
+ // Start of target-specific flags.
+
+ /// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped
+ /// together by the linker to form the constant pool and the cp register is
+ /// set to the start of the constant pool by the boot code.
+ XCORE_SHF_CP_SECTION = 0x800U,
+
+ /// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped
+ /// together by the linker to form the data section and the dp register is
+ /// set to the start of the section by the boot code.
+ XCORE_SHF_DP_SECTION = 0x1000U,
+
+ // Bits indicating processor-specific flags.
+ SHF_MASKPROC = 0xf0000000
};
// Section Group Flags
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index dc88a129e1..f62eab0702 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -15,8 +15,8 @@
#define LLVM_SUPPORT_ENDIAN_H
#include "llvm/Config/config.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/SwapByteOrder.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/type_traits.h"
namespace llvm {
diff --git a/include/llvm/System/Errno.h b/include/llvm/Support/Errno.h
index 6e292ba626..150bdb7016 100644
--- a/include/llvm/System/Errno.h
+++ b/include/llvm/Support/Errno.h
@@ -1,4 +1,4 @@
-//===- llvm/System/Errno.h - Portable+convenient errno handling -*- C++ -*-===//
+//===- llvm/Support/Errno.h - Portable+convenient errno handling -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/llvm/System/FEnv.h b/include/llvm/Support/FEnv.h
index 042e43928b..f6f43337bd 100644
--- a/include/llvm/System/FEnv.h
+++ b/include/llvm/Support/FEnv.h
@@ -1,4 +1,4 @@
-//===- llvm/System/FEnv.h - Host floating-point exceptions ------*- C++ -*-===//
+//===- llvm/Support/FEnv.h - Host floating-point exceptions ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
new file mode 100644
index 0000000000..4f013f89e8
--- /dev/null
+++ b/include/llvm/Support/FileSystem.h
@@ -0,0 +1,690 @@
+//===- llvm/Support/FileSystem.h - File System OS Concept -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::fs namespace. It is designed after
+// TR2/boost filesystem (v3), but modified to remove exception handling and the
+// path class.
+//
+// All functions return an error_code and their actual work via the last out
+// argument. The out argument is defined if and only if errc::success is
+// returned. A function may return any error code in the generic or system
+// category. However, they shall be equivalent to any error conditions listed
+// in each functions respective documentation if the condition applies. [ note:
+// this does not guarantee that error_code will be in the set of explicitly
+// listed codes, but it does guarantee that if any of the explicitly listed
+// errors occur, the correct error_code will be used ]. All functions may
+// return errc::not_enough_memory if there is not enough memory to complete the
+// operation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILE_SYSTEM_H
+#define LLVM_SUPPORT_FILE_SYSTEM_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/PathV1.h"
+#include "llvm/Support/system_error.h"
+#include <ctime>
+#include <iterator>
+#include <string>
+
+namespace llvm {
+namespace sys {
+namespace fs {
+
+/// file_type - An "enum class" enumeration for the file system's view of the
+/// type.
+struct file_type {
+ enum _ {
+ status_error,
+ file_not_found,
+ regular_file,
+ directory_file,
+ symlink_file,
+ block_file,
+ character_file,
+ fifo_file,
+ socket_file,
+ type_unknown
+ };
+
+ file_type(_ v) : v_(v) {}
+ explicit file_type(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+
+private:
+ int v_;
+};
+
+/// copy_option - An "enum class" enumeration of copy semantics for copy
+/// operations.
+struct copy_option {
+ enum _ {
+ fail_if_exists,
+ overwrite_if_exists
+ };
+
+ copy_option(_ v) : v_(v) {}
+ explicit copy_option(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+
+private:
+ int v_;
+};
+
+/// space_info - Self explanatory.
+struct space_info {
+ uint64_t capacity;
+ uint64_t free;
+ uint64_t available;
+};
+
+/// file_status - Represents the result of a call to stat and friends. It has
+/// a platform specific member to store the result.
+class file_status
+{
+ // implementation defined status field.
+ file_type Type;
+public:
+ explicit file_status(file_type v=file_type::status_error)
+ : Type(v) {}
+
+ file_type type() const { return Type; }
+ void type(file_type v) { Type = v; }
+};
+
+/// @}
+/// @name Physical Operators
+/// @{
+
+/// @brief Make \a path an absolute path.
+///
+/// Makes \a path absolute using the current directory if it is not already. An
+/// empty \a path will result in the current directory.
+///
+/// /absolute/path => /absolute/path
+/// relative/../path => <current-directory>/relative/../path
+///
+/// @param path A path that is modified to be an absolute path.
+/// @returns errc::success if \a path has been made absolute, otherwise a
+/// platform specific error_code.
+error_code make_absolute(SmallVectorImpl<char> &path);
+
+/// @brief Copy the file at \a from to the path \a to.
+///
+/// @param from The path to copy the file from.
+/// @param to The path to copy the file to.
+/// @param copt Behavior if \a to already exists.
+/// @returns errc::success if the file has been successfully copied.
+/// errc::file_exists if \a to already exists and \a copt ==
+/// copy_option::fail_if_exists. Otherwise a platform specific
+/// error_code.
+error_code copy_file(const Twine &from, const Twine &to,
+ copy_option copt = copy_option::fail_if_exists);
+
+/// @brief Create all the non-existent directories in path.
+///
+/// @param path Directories to create.
+/// @param existed Set to true if \a path already existed, false otherwise.
+/// @returns errc::success if is_directory(path) and existed have been set,
+/// otherwise a platform specific error_code.
+error_code create_directories(const Twine &path, bool &existed);
+
+/// @brief Create the directory in path.
+///
+/// @param path Directory to create.
+/// @param existed Set to true if \a path already existed, false otherwise.
+/// @returns errc::success if is_directory(path) and existed have been set,
+/// otherwise a platform specific error_code.
+error_code create_directory(const Twine &path, bool &existed);
+
+/// @brief Create a hard link from \a from to \a to.
+///
+/// @param to The path to hard link to.
+/// @param from The path to hard link from. This is created.
+/// @returns errc::success if exists(to) && exists(from) && equivalent(to, from)
+/// , otherwise a platform specific error_code.
+error_code create_hard_link(const Twine &to, const Twine &from);
+
+/// @brief Create a symbolic link from \a from to \a to.
+///
+/// @param to The path to symbolically link to.
+/// @param from The path to symbolically link from. This is created.
+/// @returns errc::success if exists(to) && exists(from) && is_symlink(from),
+/// otherwise a platform specific error_code.
+error_code create_symlink(const Twine &to, const Twine &from);
+
+/// @brief Get the current path.
+///
+/// @param result Holds the current path on return.
+/// @results errc::success if the current path has been stored in result,
+/// otherwise a platform specific error_code.
+error_code current_path(SmallVectorImpl<char> &result);
+
+/// @brief Remove path. Equivalent to POSIX remove().
+///
+/// @param path Input path.
+/// @param existed Set to true if \a path existed, false if it did not.
+/// undefined otherwise.
+/// @results errc::success if path has been removed and existed has been
+/// successfully set, otherwise a platform specific error_code.
+error_code remove(const Twine &path, bool &existed);
+
+/// @brief Recursively remove all files below \a path, then \a path. Files are
+/// removed as if by POSIX remove().
+///
+/// @param path Input path.
+/// @param num_removed Number of files removed.
+/// @results errc::success if path has been removed and num_removed has been
+/// successfully set, otherwise a platform specific error_code.
+error_code remove_all(const Twine &path, uint32_t &num_removed);
+
+/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
+///
+/// @param from The path to rename from.
+/// @param to The path to rename to. This is created.
+error_code rename(const Twine &from, const Twine &to);
+
+/// @brief Resize path to size. File is resized as if by POSIX truncate().
+///
+/// @param path Input path.
+/// @param size Size to resize to.
+/// @returns errc::success if \a path has been resized to \a size, otherwise a
+/// platform specific error_code.
+error_code resize_file(const Twine &path, uint64_t size);
+
+/// @brief Make file readable.
+///
+/// @param path Input path.
+/// @param value If true, make readable, else, make unreadable.
+/// @results errc::success if readability has been successfully set, otherwise a
+/// platform specific error_code.
+error_code set_read(const Twine &path, bool value);
+
+/// @brief Make file writeable.
+///
+/// @param path Input path.
+/// @param value If true, make writeable, else, make unwriteable.
+/// @results errc::success if writeability has been successfully set, otherwise
+/// a platform specific error_code.
+error_code set_write(const Twine &path, bool value);
+
+/// @brief Make file executable.
+///
+/// @param path Input path.
+/// @param value If true, make executable, else, make unexecutable.
+/// @results errc::success if executability has been successfully set, otherwise
+/// a platform specific error_code.
+error_code set_execute(const Twine &path, bool value);
+
+/// @}
+/// @name Physical Observers
+/// @{
+
+/// @brief Does file exist?
+///
+/// @param status A file_status previously returned from stat.
+/// @results True if the file represented by status exists, false if it does
+/// not.
+bool exists(file_status status);
+
+/// @brief Does file exist?
+///
+/// @param path Input path.
+/// @param result Set to true if the file represented by status exists, false if
+/// it does not. Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code exists(const Twine &path, bool &result);
+
+/// @brief Do file_status's represent the same thing?
+///
+/// @param A Input file_status.
+/// @param B Input file_status.
+///
+/// assert(status_known(A) || status_known(B));
+///
+/// @results True if A and B both represent the same file system entity, false
+/// otherwise.
+bool equivalent(file_status A, file_status B);
+
+/// @brief Do paths represent the same thing?
+///
+/// @param A Input path A.
+/// @param B Input path B.
+/// @param result Set to true if stat(A) and stat(B) have the same device and
+/// inode (or equivalent).
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code equivalent(const Twine &A, const Twine &B, bool &result);
+
+/// @brief Get file size.
+///
+/// @param path Input path.
+/// @param result Set to the size of the file in \a path.
+/// @returns errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code file_size(const Twine &path, uint64_t &result);
+
+/// @brief Does status represent a directory?
+///
+/// @param status A file_status previously returned from status.
+/// @results status.type() == file_type::directory_file.
+bool is_directory(file_status status);
+
+/// @brief Is path a directory?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a directory, false if it is not.
+/// Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_directory(const Twine &path, bool &result);
+
+/// @brief Is path an empty file?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a an empty file, false if it is not.
+/// Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_empty(const Twine &path, bool &result);
+
+/// @brief Does status represent a regular file?
+///
+/// @param status A file_status previously returned from status.
+/// @results status_known(status) && status.type() == file_type::regular_file.
+bool is_regular_file(file_status status);
+
+/// @brief Is path a regular file?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a regular file, false if it is not.
+/// Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_regular_file(const Twine &path, bool &result);
+
+/// @brief Does this status represent something that exists but is not a
+/// directory, regular file, or symlink?
+///
+/// @param status A file_status previously returned from status.
+/// @results exists(s) && !is_regular_file(s) && !is_directory(s) &&
+/// !is_symlink(s)
+bool is_other(file_status status);
+
+/// @brief Is path something that exists but is not a directory,
+/// regular file, or symlink?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path exists, but is not a directory, regular
+/// file, or a symlink, false if it does not. Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_other(const Twine &path, bool &result);
+
+/// @brief Does status represent a symlink?
+///
+/// @param status A file_status previously returned from stat.
+/// @param result status.type() == symlink_file.
+bool is_symlink(file_status status);
+
+/// @brief Is path a symlink?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a symlink, false if it is not.
+/// Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_symlink(const Twine &path, bool &result);
+
+/// @brief Get last write time without changing it.
+///
+/// @param path Input path.
+/// @param result Set to the last write time (UNIX time) of \a path if it
+/// exists.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code last_write_time(const Twine &path, std::time_t &result);
+
+/// @brief Set last write time.
+///
+/// @param path Input path.
+/// @param value Time to set (UNIX time) \a path's last write time to.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code set_last_write_time(const Twine &path, std::time_t value);
+
+/// @brief Read a symlink's value.
+///
+/// @param path Input path.
+/// @param result Set to the value of the symbolic link \a path.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code read_symlink(const Twine &path, SmallVectorImpl<char> &result);
+
+/// @brief Get disk space usage information.
+///
+/// @param path Input path.
+/// @param result Set to the capacity, free, and available space on the device
+/// \a path is on.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code disk_space(const Twine &path, space_info &result);
+
+/// @brief Get file status as if by POSIX stat().
+///
+/// @param path Input path.
+/// @param result Set to the file status.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code status(const Twine &path, file_status &result);
+
+/// @brief Is status available?
+///
+/// @param path Input path.
+/// @results True if status() != status_error.
+bool status_known(file_status s);
+
+/// @brief Is status available?
+///
+/// @param path Input path.
+/// @param result Set to true if status() != status_error.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code status_known(const Twine &path, bool &result);
+
+/// @brief Get file status as if by POSIX lstat().
+///
+/// Does not resolve symlinks.
+///
+/// @param path Input path.
+/// @param result Set to the file status.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code symlink_status(const Twine &path, file_status &result);
+
+/// @brief Generate a unique path and open it as a file.
+///
+/// Generates a unique path suitable for a temporary file and then opens it as a
+/// file. The name is based on \a model with '%' replaced by a random char in
+/// [0-9a-f]. If \a model is not an absolute path, a suitable temporary
+/// directory will be prepended.
+///
+/// This is an atomic operation. Either the file is created and opened, or the
+/// file system is left untouched.
+///
+/// clang-%%-%%-%%-%%-%%.s => /tmp/clang-a0-b1-c2-d3-e4.s
+///
+/// @param model Name to base unique path off of.
+/// @param result_fs Set to the opened file's file descriptor.
+/// @param result_path Set to the opened file's absolute path.
+/// @results errc::success if result_{fd,path} have been successfully set,
+/// otherwise a platform specific error_code.
+error_code unique_file(const Twine &model, int &result_fd,
+ SmallVectorImpl<char> &result_path);
+
+/// @brief Canonicalize path.
+///
+/// Sets result to the file system's idea of what path is. The result is always
+/// absolute and has the same capitalization as the file system.
+///
+/// @param path Input path.
+/// @param result Set to the canonicalized version of \a path.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result);
+
+/// @brief Are \a path's first bytes \a magic?
+///
+/// @param path Input path.
+/// @param magic Byte sequence to compare \a path's first len(magic) bytes to.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code has_magic(const Twine &path, const Twine &magic, bool &result);
+
+/// @brief Get \a path's first \a len bytes.
+///
+/// @param path Input path.
+/// @param len Number of magic bytes to get.
+/// @param result Set to the first \a len bytes in the file pointed to by
+/// \a path. Or the entire file if file_size(path) < len, in which
+/// case result.size() returns the size of the file.
+/// @results errc::success if result has been successfully set,
+/// errc::value_too_large if len is larger then the file pointed to by
+/// \a path, otherwise a platform specific error_code.
+error_code get_magic(const Twine &path, uint32_t len,
+ SmallVectorImpl<char> &result);
+
+/// @brief Get and identify \a path's type based on its content.
+///
+/// @param path Input path.
+/// @param result Set to the type of file, or LLVMFileType::Unknown_FileType.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code identify_magic(const Twine &path, LLVMFileType &result);
+
+/// @brief Is file bitcode?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a bitcode file, false if it is not,
+/// undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_bitcode(const Twine &path, bool &result);
+
+/// @brief Is file a dynamic library?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a dynamic library, false if it is
+/// not, undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_dynamic_library(const Twine &path, bool &result);
+
+/// @brief Is an object file?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is an object file, false if it is not,
+/// undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_object_file(const Twine &path, bool &result);
+
+/// @brief Can file be read?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is readable, false it it is not,
+/// undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code can_read(const Twine &path, bool &result);
+
+/// @brief Can file be written?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is writeable, false it it is not,
+/// undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code can_write(const Twine &path, bool &result);
+
+/// @brief Can file be executed?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is executable, false it it is not,
+/// undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code can_execute(const Twine &path, bool &result);
+
+/// @brief Get library paths the system linker uses.
+///
+/// @param result Set to the list of system library paths.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result);
+
+/// @brief Get bitcode library paths the system linker uses
+/// + LLVM_LIB_SEARCH_PATH + LLVM_LIBDIR.
+///
+/// @param result Set to the list of bitcode library paths.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result);
+
+/// @brief Find a library.
+///
+/// Find the path to a library using its short name. Use the system
+/// dependent library paths to locate the library.
+///
+/// c => /usr/lib/libc.so
+///
+/// @param short_name Library name one would give to the system linker.
+/// @param result Set to the absolute path \a short_name represents.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
+
+/// @brief Get absolute path of main executable.
+///
+/// @param argv0 The program name as it was spelled on the command line.
+/// @param MainAddr Address of some symbol in the executable (not in a library).
+/// @param result Set to the absolute path of the current executable.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code GetMainExecutable(const char *argv0, void *MainAddr,
+ SmallVectorImpl<char> &result);
+
+/// @}
+/// @name Iterators
+/// @{
+
+/// directory_entry - A single entry in a directory. Caches the status either
+/// from the result of the iteration syscall, or the first time status or
+/// symlink_status is called.
+class directory_entry {
+ std::string Path;
+ mutable file_status Status;
+ mutable file_status SymlinkStatus;
+
+public:
+ explicit directory_entry(const Twine &path, file_status st = file_status(),
+ file_status symlink_st = file_status())
+ : Path(path.str())
+ , Status(st)
+ , SymlinkStatus(symlink_st) {}
+
+ directory_entry() {}
+
+ void assign(const Twine &path, file_status st = file_status(),
+ file_status symlink_st = file_status()) {
+ Path = path.str();
+ Status = st;
+ SymlinkStatus = symlink_st;
+ }
+
+ void replace_filename(const Twine &filename, file_status st = file_status(),
+ file_status symlink_st = file_status());
+
+ const std::string &path() const { return Path; }
+ error_code status(file_status &result) const;
+ error_code symlink_status(file_status &result) const;
+
+ bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; }
+ bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); }
+ bool operator< (const directory_entry& rhs) const;
+ bool operator<=(const directory_entry& rhs) const;
+ bool operator> (const directory_entry& rhs) const;
+ bool operator>=(const directory_entry& rhs) const;
+};
+
+/// directory_iterator - Iterates through the entries in path. There is no
+/// operator++ because we need an error_code. If it's really needed we can make
+/// it call report_fatal_error on error.
+class directory_iterator {
+ intptr_t IterationHandle;
+ directory_entry CurrentEntry;
+
+ // Platform implementations implement these functions to handle iteration.
+ friend error_code directory_iterator_construct(directory_iterator &it,
+ StringRef path);
+ friend error_code directory_iterator_increment(directory_iterator &it);
+ friend error_code directory_iterator_destruct(directory_iterator &it);
+
+public:
+ explicit directory_iterator(const Twine &path, error_code &ec)
+ : IterationHandle(0) {
+ SmallString<128> path_storage;
+ ec = directory_iterator_construct(*this, path.toStringRef(path_storage));
+ }
+
+ /// Construct end iterator.
+ directory_iterator() : IterationHandle(0) {}
+
+ ~directory_iterator() {
+ directory_iterator_destruct(*this);
+ }
+
+ // No operator++ because we need error_code.
+ directory_iterator &increment(error_code &ec) {
+ ec = directory_iterator_increment(*this);
+ return *this;
+ }
+
+ const directory_entry &operator*() const { return CurrentEntry; }
+ const directory_entry *operator->() const { return &CurrentEntry; }
+
+ bool operator!=(const directory_iterator &RHS) const {
+ return CurrentEntry != RHS.CurrentEntry;
+ }
+ // Other members as required by
+ // C++ Std, 24.1.1 Input iterators [input.iterators]
+};
+
+/// recursive_directory_iterator - Same as directory_iterator except for it
+/// recurses down into child directories.
+class recursive_directory_iterator {
+ uint16_t Level;
+ bool HasNoPushRequest;
+ // implementation directory iterator status
+
+public:
+ explicit recursive_directory_iterator(const Twine &path, error_code &ec);
+ // No operator++ because we need error_code.
+ directory_iterator &increment(error_code &ec);
+
+ const directory_entry &operator*() const;
+ const directory_entry *operator->() const;
+
+ // observers
+ /// Gets the current level. path is at level 0.
+ int level() const;
+ /// Returns true if no_push has been called for this directory_entry.
+ bool no_push_request() const;
+
+ // modifiers
+ /// Goes up one level if Level > 0.
+ void pop();
+ /// Does not go down into the current directory_entry.
+ void no_push();
+
+ // Other members as required by
+ // C++ Std, 24.1.1 Input iterators [input.iterators]
+};
+
+/// @}
+
+} // end namespace fs
+} // end namespace sys
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
index d0dd4a7598..748ce7cea7 100644
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -15,7 +15,7 @@
#ifndef LLVM_SUPPORT_FILEUTILITIES_H
#define LLVM_SUPPORT_FILEUTILITIES_H
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
namespace llvm {
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index 2d29e525fb..a5165f44d5 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -26,7 +26,7 @@
#include "llvm/Support/DOTGraphTraits.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <vector>
#include <cassert>
@@ -70,7 +70,7 @@ class GraphWriter {
for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
std::string label = DTraits.getEdgeSourceLabel(Node, EI);
- if (label == "")
+ if (label.empty())
continue;
hasEdgeSourceLabels = true;
@@ -78,7 +78,7 @@ class GraphWriter {
if (i)
O << "|";
- O << "<s" << i << ">" << DTraits.getEdgeSourceLabel(Node, EI);
+ O << "<s" << i << ">" << DOT::EscapeString(label);
}
if (EI != EE && hasEdgeSourceLabels)
@@ -235,12 +235,12 @@ public:
DestPort = static_cast<int>(Offset);
}
- if (DTraits.getEdgeSourceLabel(Node, EI) == "")
+ if (DTraits.getEdgeSourceLabel(Node, EI).empty())
edgeidx = -1;
emitEdge(static_cast<const void*>(Node), edgeidx,
static_cast<const void*>(TargetNode), DestPort,
- DTraits.getEdgeAttributes(Node, EI));
+ DTraits.getEdgeAttributes(Node, EI, G));
}
}
diff --git a/include/llvm/System/Host.h b/include/llvm/Support/Host.h
index 4fbf5c177c..f77d4c1182 100644
--- a/include/llvm/System/Host.h
+++ b/include/llvm/Support/Host.h
@@ -1,4 +1,4 @@
-//===- llvm/System/Host.h - Host machine characteristics --------*- C++ -*-===//
+//===- llvm/Support/Host.h - Host machine characteristics --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
index b3934224f5..2394a59c09 100644
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -74,6 +74,13 @@ public:
}
/// SetInsertPoint - This specifies that created instructions should be
+ /// inserted before the specified instruction.
+ void SetInsertPoint(Instruction *I) {
+ BB = I->getParent();
+ InsertPt = I;
+ }
+
+ /// SetInsertPoint - This specifies that created instructions should be
/// inserted at the specified point.
void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
BB = TheBB;
@@ -228,13 +235,48 @@ public:
return Type::getVoidTy(Context);
}
- const PointerType *getInt8PtrTy() {
- return Type::getInt8PtrTy(Context);
+ const PointerType *getInt8PtrTy(unsigned AddrSpace = 0) {
+ return Type::getInt8PtrTy(Context, AddrSpace);
}
/// getCurrentFunctionReturnType - Get the return type of the current function
/// that we're emitting into.
const Type *getCurrentFunctionReturnType() const;
+
+ /// CreateMemSet - Create and insert a memset to the specified pointer and the
+ /// specified value. If the pointer isn't an i8*, it will be converted. If a
+ /// TBAA tag is specified, it will be added to the instruction.
+ CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0) {
+ return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
+ }
+
+ CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0);
+
+ /// CreateMemCpy - Create and insert a memcpy between the specified pointers.
+ /// If the pointers aren't i8*, they will be converted. If a TBAA tag is
+ /// specified, it will be added to the instruction.
+ CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0) {
+ return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
+ }
+
+ CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0);
+
+ /// CreateMemMove - Create and insert a memmove between the specified
+ /// pointers. If the pointers aren't i8*, they will be converted. If a TBAA
+ /// tag is specified, it will be added to the instruction.
+ CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0) {
+ return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
+ }
+
+ CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0);
+private:
+ Value *getCastedInt8PtrValue(Value *Ptr);
};
/// IRBuilder - This provides a uniform API for creating instructions and
@@ -272,6 +314,11 @@ public:
SetInsertPoint(TheBB);
}
+ explicit IRBuilder(Instruction *IP)
+ : IRBuilderBase(IP->getContext()), Folder(Context) {
+ SetInsertPoint(IP);
+ }
+
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F)
: IRBuilderBase(TheBB->getContext()), Folder(F) {
SetInsertPoint(TheBB, IP);
@@ -298,6 +345,11 @@ public:
return I;
}
+ /// Insert - No-op overload to handle constants.
+ Constant *Insert(Constant *C, const Twine& = "") const {
+ return C;
+ }
+
//===--------------------------------------------------------------------===//
// Instruction creation methods: Terminators
//===--------------------------------------------------------------------===//
@@ -396,177 +448,179 @@ public:
//===--------------------------------------------------------------------===//
// Instruction creation methods: Binary Operators
//===--------------------------------------------------------------------===//
-
- Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
+private:
+ BinaryOperator *CreateInsertNUWNSWBinOp(BinaryOperator::BinaryOps Opc,
+ Value *LHS, Value *RHS,
+ const Twine &Name,
+ bool HasNUW, bool HasNSW) {
+ BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+public:
+ Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateAdd(LC, RC);
- return Insert(BinaryOperator::CreateAdd(LHS, RHS), Name);
+ return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name);
+ return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name,
+ HasNUW, HasNSW);
}
Value *CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateNSWAdd(LC, RC);
- return Insert(BinaryOperator::CreateNSWAdd(LHS, RHS), Name);
+ return CreateAdd(LHS, RHS, Name, false, true);
}
Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateNUWAdd(LC, RC);
- return Insert(BinaryOperator::CreateNUWAdd(LHS, RHS), Name);
+ return CreateAdd(LHS, RHS, Name, true, false);
}
Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateFAdd(LC, RC);
+ return Insert(Folder.CreateFAdd(LC, RC), Name);
return Insert(BinaryOperator::CreateFAdd(LHS, RHS), Name);
}
- Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateSub(LC, RC);
- return Insert(BinaryOperator::CreateSub(LHS, RHS), Name);
+ return Insert(Folder.CreateSub(LC, RC), Name);
+ return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name,
+ HasNUW, HasNSW);
}
Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateNSWSub(LC, RC);
- return Insert(BinaryOperator::CreateNSWSub(LHS, RHS), Name);
+ return CreateSub(LHS, RHS, Name, false, true);
}
Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateNUWSub(LC, RC);
- return Insert(BinaryOperator::CreateNUWSub(LHS, RHS), Name);
+ return CreateSub(LHS, RHS, Name, true, false);
}
Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateFSub(LC, RC);
+ return Insert(Folder.CreateFSub(LC, RC), Name);
return Insert(BinaryOperator::CreateFSub(LHS, RHS), Name);
}
- Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateMul(LC, RC);
- return Insert(BinaryOperator::CreateMul(LHS, RHS), Name);
+ return Insert(Folder.CreateMul(LC, RC), Name);
+ return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name,
+ HasNUW, HasNSW);
}
Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateNSWMul(LC, RC);
- return Insert(BinaryOperator::CreateNSWMul(LHS, RHS), Name);
+ return CreateMul(LHS, RHS, Name, false, true);
}
Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateNUWMul(LC, RC);
- return Insert(BinaryOperator::CreateNUWMul(LHS, RHS), Name);
+ return CreateMul(LHS, RHS, Name, true, false);
}
Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateFMul(LC, RC);
+ return Insert(Folder.CreateFMul(LC, RC), Name);
return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name);
}
- Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateUDiv(LC, RC);
- return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
+ return Insert(Folder.CreateUDiv(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name);
}
- Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateSDiv(LC, RC);
- return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
+ Value *CreateExactUDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateUDiv(LHS, RHS, Name, true);
}
- Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateExactSDiv(LC, RC);
+ return Insert(Folder.CreateSDiv(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name);
}
+ Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateSDiv(LHS, RHS, Name, true);
+ }
Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateFDiv(LC, RC);
+ return Insert(Folder.CreateFDiv(LC, RC), Name);
return Insert(BinaryOperator::CreateFDiv(LHS, RHS), Name);
}
Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateURem(LC, RC);
+ return Insert(Folder.CreateURem(LC, RC), Name);
return Insert(BinaryOperator::CreateURem(LHS, RHS), Name);
}
Value *CreateSRem(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateSRem(LC, RC);
+ return Insert(Folder.CreateSRem(LC, RC), Name);
return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name);
}
Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateFRem(LC, RC);
+ return Insert(Folder.CreateFRem(LC, RC), Name);
return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name);
}
- Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateShl(LC, RC);
- return Insert(BinaryOperator::CreateShl(LHS, RHS), Name);
+ return Insert(Folder.CreateShl(LC, RC, HasNUW, HasNSW), Name);
+ return CreateInsertNUWNSWBinOp(Instruction::Shl, LHS, RHS, Name,
+ HasNUW, HasNSW);
}
- Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateShl(LC, RHSC);
- return Insert(BinaryOperator::CreateShl(LHS, RHSC), Name);
+ Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
+ return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name,
+ HasNUW, HasNSW);
}
- Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateShl(LC, RHSC);
- return Insert(BinaryOperator::CreateShl(LHS, RHSC), Name);
+ Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
+ return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name,
+ HasNUW, HasNSW);
}
- Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateLShr(LC, RC);
- return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
+ return Insert(Folder.CreateLShr(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactLShr(LHS, RHS), Name);
}
- Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateLShr(LC, RHSC);
- return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name);
+ Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
}
- Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateLShr(LC, RHSC);
- return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name);
+ Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
}
- Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateAShr(LC, RC);
- return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
+ return Insert(Folder.CreateAShr(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactAShr(LHS, RHS), Name);
}
- Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateAShr(LC, RHSC);
- return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name);
+ Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
}
- Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateAShr(LC, RHSC);
- return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name);
+ Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
}
Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
@@ -574,21 +628,15 @@ public:
if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isAllOnesValue())
return LHS; // LHS & -1 -> LHS
if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateAnd(LC, RC);
+ return Insert(Folder.CreateAnd(LC, RC), Name);
}
return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
}
Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateAnd(LC, RHSC);
- return Insert(BinaryOperator::CreateAnd(LHS, RHSC), Name);
+ return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateAnd(LC, RHSC);
- return Insert(BinaryOperator::CreateAnd(LHS, RHSC), Name);
+ return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
@@ -596,73 +644,61 @@ public:
if (RC->isNullValue())
return LHS; // LHS | 0 -> LHS
if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateOr(LC, RC);
+ return Insert(Folder.CreateOr(LC, RC), Name);
}
return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
}
Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateOr(LC, RHSC);
- return Insert(BinaryOperator::CreateOr(LHS, RHSC), Name);
+ return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateOr(LC, RHSC);
- return Insert(BinaryOperator::CreateOr(LHS, RHSC), Name);
+ return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateXor(LC, RC);
+ return Insert(Folder.CreateXor(LC, RC), Name);
return Insert(BinaryOperator::CreateXor(LHS, RHS), Name);
}
Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateXor(LC, RHSC);
- return Insert(BinaryOperator::CreateXor(LHS, RHSC), Name);
+ return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Folder.CreateXor(LC, RHSC);
- return Insert(BinaryOperator::CreateXor(LHS, RHSC), Name);
+ return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
}
Value *CreateBinOp(Instruction::BinaryOps Opc,
Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateBinOp(Opc, LC, RC);
+ return Insert(Folder.CreateBinOp(Opc, LC, RC), Name);
return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
}
- Value *CreateNeg(Value *V, const Twine &Name = "") {
+ Value *CreateNeg(Value *V, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateNeg(VC);
- return Insert(BinaryOperator::CreateNeg(V), Name);
+ return Insert(Folder.CreateNeg(VC, HasNUW, HasNSW), Name);
+ BinaryOperator *BO = Insert(BinaryOperator::CreateNeg(V), Name);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
}
Value *CreateNSWNeg(Value *V, const Twine &Name = "") {
- if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateNSWNeg(VC);
- return Insert(BinaryOperator::CreateNSWNeg(V), Name);
+ return CreateNeg(V, Name, false, true);
}
Value *CreateNUWNeg(Value *V, const Twine &Name = "") {
- if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateNUWNeg(VC);
- return Insert(BinaryOperator::CreateNUWNeg(V), Name);
+ return CreateNeg(V, Name, true, false);
}
Value *CreateFNeg(Value *V, const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateFNeg(VC);
+ return Insert(Folder.CreateFNeg(VC), Name);
return Insert(BinaryOperator::CreateFNeg(V), Name);
}
Value *CreateNot(Value *V, const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateNot(VC);
+ return Insert(Folder.CreateNot(VC), Name);
return Insert(BinaryOperator::CreateNot(V), Name);
}
@@ -700,7 +736,9 @@ public:
if (!isa<Constant>(*i))
break;
if (i == IdxEnd)
- return Folder.CreateGetElementPtr(PC, &IdxBegin[0], IdxEnd - IdxBegin);
+ return Insert(Folder.CreateGetElementPtr(PC, &IdxBegin[0],
+ IdxEnd - IdxBegin),
+ Name);
}
return Insert(GetElementPtrInst::Create(Ptr, IdxBegin, IdxEnd), Name);
}
@@ -715,9 +753,10 @@ public:
if (!isa<Constant>(*i))
break;
if (i == IdxEnd)
- return Folder.CreateInBoundsGetElementPtr(PC,
- &IdxBegin[0],
- IdxEnd - IdxBegin);
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC,
+ &IdxBegin[0],
+ IdxEnd - IdxBegin),
+ Name);
}
return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxBegin, IdxEnd),
Name);
@@ -725,20 +764,20 @@ public:
Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr))
if (Constant *IC = dyn_cast<Constant>(Idx))
- return Folder.CreateGetElementPtr(PC, &IC, 1);
+ return Insert(Folder.CreateGetElementPtr(PC, &IC, 1), Name);
return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
}
Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr))
if (Constant *IC = dyn_cast<Constant>(Idx))
- return Folder.CreateInBoundsGetElementPtr(PC, &IC, 1);
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, &IC, 1), Name);
return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
}
Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Folder.CreateGetElementPtr(PC, &Idx, 1);
+ return Insert(Folder.CreateGetElementPtr(PC, &Idx, 1), Name);
return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name);
}
@@ -747,7 +786,7 @@ public:
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1);
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1), Name);
return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name);
}
@@ -759,7 +798,7 @@ public:
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Folder.CreateGetElementPtr(PC, Idxs, 2);
+ return Insert(Folder.CreateGetElementPtr(PC, Idxs, 2), Name);
return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);
}
@@ -771,7 +810,7 @@ public:
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2);
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2), Name);
return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name);
}
@@ -779,7 +818,7 @@ public:
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Folder.CreateGetElementPtr(PC, &Idx, 1);
+ return Insert(Folder.CreateGetElementPtr(PC, &Idx, 1), Name);
return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name);
}
@@ -788,7 +827,7 @@ public:
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1);
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1), Name);
return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name);
}
@@ -800,7 +839,7 @@ public:
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Folder.CreateGetElementPtr(PC, Idxs, 2);
+ return Insert(Folder.CreateGetElementPtr(PC, Idxs, 2), Name);
return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);
}
@@ -812,7 +851,7 @@ public:
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2);
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2), Name);
return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name);
}
@@ -878,7 +917,7 @@ public:
if (V->getType() == DestTy)
return V;
if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateZExtOrBitCast(VC, DestTy);
+ return Insert(Folder.CreateZExtOrBitCast(VC, DestTy), Name);
return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name);
}
Value *CreateSExtOrBitCast(Value *V, const Type *DestTy,
@@ -886,7 +925,7 @@ public:
if (V->getType() == DestTy)
return V;
if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateSExtOrBitCast(VC, DestTy);
+ return Insert(Folder.CreateSExtOrBitCast(VC, DestTy), Name);
return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name);
}
Value *CreateTruncOrBitCast(Value *V, const Type *DestTy,
@@ -894,7 +933,7 @@ public:
if (V->getType() == DestTy)
return V;
if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateTruncOrBitCast(VC, DestTy);
+ return Insert(Folder.CreateTruncOrBitCast(VC, DestTy), Name);
return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name);
}
Value *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy,
@@ -902,7 +941,7 @@ public:
if (V->getType() == DestTy)
return V;
if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateCast(Op, VC, DestTy);
+ return Insert(Folder.CreateCast(Op, VC, DestTy), Name);
return Insert(CastInst::Create(Op, V, DestTy), Name);
}
Value *CreatePointerCast(Value *V, const Type *DestTy,
@@ -910,7 +949,7 @@ public:
if (V->getType() == DestTy)
return V;
if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreatePointerCast(VC, DestTy);
+ return Insert(Folder.CreatePointerCast(VC, DestTy), Name);
return Insert(CastInst::CreatePointerCast(V, DestTy), Name);
}
Value *CreateIntCast(Value *V, const Type *DestTy, bool isSigned,
@@ -918,7 +957,7 @@ public:
if (V->getType() == DestTy)
return V;
if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateIntCast(VC, DestTy, isSigned);
+ return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name);
return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
}
private:
@@ -930,7 +969,7 @@ public:
if (V->getType() == DestTy)
return V;
if (Constant *VC = dyn_cast<Constant>(V))
- return Folder.CreateFPCast(VC, DestTy);
+ return Insert(Folder.CreateFPCast(VC, DestTy), Name);
return Insert(CastInst::CreateFPCast(V, DestTy), Name);
}
@@ -1016,14 +1055,14 @@ public:
const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateICmp(P, LC, RC);
+ return Insert(Folder.CreateICmp(P, LC, RC), Name);
return Insert(new ICmpInst(P, LHS, RHS), Name);
}
Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateFCmp(P, LC, RC);
+ return Insert(Folder.CreateFCmp(P, LC, RC), Name);
return Insert(new FCmpInst(P, LHS, RHS), Name);
}
@@ -1073,7 +1112,7 @@ public:
if (Constant *CC = dyn_cast<Constant>(C))
if (Constant *TC = dyn_cast<Constant>(True))
if (Constant *FC = dyn_cast<Constant>(False))
- return Folder.CreateSelect(CC, TC, FC);
+ return Insert(Folder.CreateSelect(CC, TC, FC), Name);
return Insert(SelectInst::Create(C, True, False), Name);
}
@@ -1085,7 +1124,7 @@ public:
const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(Vec))
if (Constant *IC = dyn_cast<Constant>(Idx))
- return Folder.CreateExtractElement(VC, IC);
+ return Insert(Folder.CreateExtractElement(VC, IC), Name);
return Insert(ExtractElementInst::Create(Vec, Idx), Name);
}
@@ -1094,7 +1133,7 @@ public:
if (Constant *VC = dyn_cast<Constant>(Vec))
if (Constant *NC = dyn_cast<Constant>(NewElt))
if (Constant *IC = dyn_cast<Constant>(Idx))
- return Folder.CreateInsertElement(VC, NC, IC);
+ return Insert(Folder.CreateInsertElement(VC, NC, IC), Name);
return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name);
}
@@ -1103,14 +1142,14 @@ public:
if (Constant *V1C = dyn_cast<Constant>(V1))
if (Constant *V2C = dyn_cast<Constant>(V2))
if (Constant *MC = dyn_cast<Constant>(Mask))
- return Folder.CreateShuffleVector(V1C, V2C, MC);
+ return Insert(Folder.CreateShuffleVector(V1C, V2C, MC), Name);
return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
}
Value *CreateExtractValue(Value *Agg, unsigned Idx,
const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg))
- return Folder.CreateExtractValue(AggC, &Idx, 1);
+ return Insert(Folder.CreateExtractValue(AggC, &Idx, 1), Name);
return Insert(ExtractValueInst::Create(Agg, Idx), Name);
}
@@ -1120,7 +1159,8 @@ public:
RandomAccessIterator IdxEnd,
const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg))
- return Folder.CreateExtractValue(AggC, IdxBegin, IdxEnd - IdxBegin);
+ return Insert(Folder.CreateExtractValue(AggC, IdxBegin, IdxEnd-IdxBegin),
+ Name);
return Insert(ExtractValueInst::Create(Agg, IdxBegin, IdxEnd), Name);
}
@@ -1128,7 +1168,7 @@ public:
const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg))
if (Constant *ValC = dyn_cast<Constant>(Val))
- return Folder.CreateInsertValue(AggC, ValC, &Idx, 1);
+ return Insert(Folder.CreateInsertValue(AggC, ValC, &Idx, 1), Name);
return Insert(InsertValueInst::Create(Agg, Val, Idx), Name);
}
@@ -1139,7 +1179,9 @@ public:
const Twine &Name = "") {
if (Constant *AggC = dyn_cast<Constant>(Agg))
if (Constant *ValC = dyn_cast<Constant>(Val))
- return Folder.CreateInsertValue(AggC, ValC, IdxBegin, IdxEnd-IdxBegin);
+ return Insert(Folder.CreateInsertValue(AggC, ValC, IdxBegin,
+ IdxEnd - IdxBegin),
+ Name);
return Insert(InsertValueInst::Create(Agg, Val, IdxBegin, IdxEnd), Name);
}
diff --git a/include/llvm/Support/IRReader.h b/include/llvm/Support/IRReader.h
index a44da528ac..292c001e09 100644
--- a/include/llvm/Support/IRReader.h
+++ b/include/llvm/Support/IRReader.h
@@ -19,10 +19,12 @@
#ifndef LLVM_SUPPORT_IRREADER_H
#define LLVM_SUPPORT_IRREADER_H
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/system_error.h"
namespace llvm {
@@ -56,15 +58,14 @@ namespace llvm {
inline Module *getLazyIRFileModule(const std::string &Filename,
SMDiagnostic &Err,
LLVMContext &Context) {
- std::string ErrMsg;
- MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg);
- if (F == 0) {
- Err = SMDiagnostic(Filename,
- "Could not open input file: " + ErrMsg);
+ OwningPtr<MemoryBuffer> File;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
+ Err = SMDiagnostic(Filename,
+ "Could not open input file: " + ec.message());
return 0;
}
- return getLazyIRModule(F, Err, Context);
+ return getLazyIRModule(File.take(), Err, Context);
}
/// If the given MemoryBuffer holds a bitcode image, return a Module
@@ -94,15 +95,14 @@ namespace llvm {
inline Module *ParseIRFile(const std::string &Filename,
SMDiagnostic &Err,
LLVMContext &Context) {
- std::string ErrMsg;
- MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg);
- if (F == 0) {
- Err = SMDiagnostic(Filename,
- "Could not open input file: " + ErrMsg);
+ OwningPtr<MemoryBuffer> File;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
+ Err = SMDiagnostic(Filename,
+ "Could not open input file: " + ec.message());
return 0;
}
- return ParseIR(F, Err, Context);
+ return ParseIR(File.take(), Err, Context);
}
}
diff --git a/include/llvm/System/IncludeFile.h b/include/llvm/Support/IncludeFile.h
index 3268ea225f..a9319725d4 100644
--- a/include/llvm/System/IncludeFile.h
+++ b/include/llvm/Support/IncludeFile.h
@@ -1,4 +1,4 @@
-//===- llvm/System/IncludeFile.h - Ensure Linking Of Library ---*- C++ -*-===//
+//===- llvm/Support/IncludeFile.h - Ensure Linking Of Library ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,14 +16,14 @@
#define LLVM_SYSTEM_INCLUDEFILE_H
/// This macro is the public interface that IncludeFile.h exports. This gives
-/// us the option to implement the "link the definition" capability in any
+/// us the option to implement the "link the definition" capability in any
/// manner that we choose. All header files that depend on a specific .cpp
/// file being linked at run time should use this macro instead of the
-/// IncludeFile class directly.
-///
+/// IncludeFile class directly.
+///
/// For example, foo.h would use:<br/>
/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/>
-///
+///
/// And, foo.cp would use:<br/>
/// <tt>DEFINING_FILE_FOR(foo)</tt><br/>
#ifdef __GNUC__
@@ -34,14 +34,14 @@
extern const char name ## LinkVar; \
__attribute__((used)) static const char *const name ## LinkObj = \
&name ## LinkVar; \
- }
+ }
#else
// Otherwise use a constructor call.
#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
namespace llvm { \
extern const char name ## LinkVar; \
static const IncludeFile name ## LinkObj ( &name ## LinkVar ); \
- }
+ }
#endif
/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should
@@ -53,9 +53,9 @@
namespace llvm {
/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED
-/// macro to make sure that the implementation of a header file is included
-/// into a tool that uses the header. This is solely
-/// to overcome problems linking .a files and not getting the implementation
+/// macro to make sure that the implementation of a header file is included
+/// into a tool that uses the header. This is solely
+/// to overcome problems linking .a files and not getting the implementation
/// of compilation units we need. This is commonly an issue with the various
/// Passes but also occurs elsewhere in LLVM. We like to use .a files because
/// they link faster and provide the smallest executables. However, sometimes
diff --git a/include/llvm/System/LICENSE.TXT b/include/llvm/Support/LICENSE.TXT
index f569da2052..3479b3fd74 100644
--- a/include/llvm/System/LICENSE.TXT
+++ b/include/llvm/Support/LICENSE.TXT
@@ -1,6 +1,6 @@
LLVM System Interface Library
-------------------------------------------------------------------------------
-The LLVM System Interface Library is licensed under the Illinois Open Source
+The LLVM System Interface Library is licensed under the Illinois Open Source
License and has the following additional copyright:
Copyright (C) 2004 eXtensible Systems, Inc.
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 964ac6a845..6841a0f1fc 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -14,7 +14,7 @@
#ifndef LLVM_SUPPORT_MACHO_H
#define LLVM_SUPPORT_MACHO_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
// NOTE: The enums in this file are intentially named to be different than those
// in the headers in /usr/include/mach (on darwin systems) to avoid conflicts
@@ -23,7 +23,7 @@ namespace llvm {
namespace MachO {
// Enums from <mach-o/loader.h>
enum {
- // Constants for the "magic" field in llvm::MachO::mach_header and
+ // Constants for the "magic" field in llvm::MachO::mach_header and
// llvm::MachO::mach_header_64
HeaderMagic32 = 0xFEEDFACEu, // MH_MAGIC
HeaderMagic32Swapped = 0xCEFAEDFEu, // MH_CIGAM
@@ -71,7 +71,7 @@ namespace llvm {
HeaderFlagBitNoReexportedDylibs = 0x00100000u, // MH_NO_REEXPORTED_DYLIBS
HeaderFlagBitPIE = 0x00200000u, // MH_PIE
HeaderFlagBitDeadStrippableDylib = 0x00400000u, // MH_DEAD_STRIPPABLE_DYLIB
-
+
// Constants for the "cmd" field in llvm::MachO::load_command
LoadCommandDynamicLinkerRequired = 0x80000000u, // LC_REQ_DYLD
LoadCommandSegment32 = 0x00000001u, // LC_SEGMENT
@@ -110,7 +110,7 @@ namespace llvm {
LoadCommandDynamicLinkerInfo = 0x00000022u, // LC_DYLD_INFO
LoadCommandDynamicLinkerInfoOnly = 0x80000022u, // LC_DYLD_INFO_ONLY
LoadCommandDylibLoadUpward = 0x80000023u, // LC_LOAD_UPWARD_DYLIB
-
+
// Constant bits for the "flags" field in llvm::MachO::segment_command
SegmentCommandFlagBitHighVM = 0x1u, // SG_HIGHVM
SegmentCommandFlagBitFixedVMLibrary = 0x2u, // SG_FVMLIB
@@ -243,20 +243,20 @@ namespace llvm {
StabFunction = 0x24u, // N_FUN
StabStaticSymbol = 0x26u, // N_STSYM
StabLocalCommon = 0x28u, // N_LCSYM
- StabBeginSymbol = 0x2Eu, // N_BNSYM
+ StabBeginSymbol = 0x2Eu, // N_BNSYM
StabSourceFileOptions = 0x3Cu, // N_OPT
StabRegisterSymbol = 0x40u, // N_RSYM
StabSourceLine = 0x44u, // N_SLINE
- StabEndSymbol = 0x4Eu, // N_ENSYM
+ StabEndSymbol = 0x4Eu, // N_ENSYM
StabStructureType = 0x60u, // N_SSYM
StabSourceFileName = 0x64u, // N_SO
StabObjectFileName = 0x66u, // N_OSO
StabLocalSymbol = 0x80u, // N_LSYM
StabBeginIncludeFileName = 0x82u, // N_BINCL
StabIncludeFileName = 0x84u, // N_SOL
- StabCompilerParameters = 0x86u, // N_PARAMS
- StabCompilerVersion = 0x88u, // N_VERSION
- StabCompilerOptLevel = 0x8Au, // N_OLEVEL
+ StabCompilerParameters = 0x86u, // N_PARAMS
+ StabCompilerVersion = 0x88u, // N_VERSION
+ StabCompilerOptLevel = 0x8Au, // N_OLEVEL
StabParameter = 0xA0u, // N_PSYM
StabEndIncludeFile = 0xA2u, // N_EINCL
StabAlternateEntry = 0xA4u, // N_ENTRY
@@ -269,9 +269,9 @@ namespace llvm {
StabLength = 0xFEu // N_LENG
};
-
+
// Structs from <mach-o/loader.h>
-
+
struct mach_header {
uint32_t magic;
uint32_t cputype;
@@ -636,12 +636,12 @@ namespace llvm {
};
// Get/Set functions from <mach-o/nlist.h>
-
+
static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
{
return (((n_desc) >> 8u) & 0xffu);
}
-
+
static inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal)
{
n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
@@ -651,7 +651,7 @@ namespace llvm {
{
return (n_desc >> 8u) & 0x0fu;
}
-
+
static inline void SET_COMM_ALIGN (uint16_t &n_desc, uint8_t align)
{
n_desc = ((n_desc & 0xf0ffu) | ((align & 0x0fu) << 8u));
@@ -662,7 +662,7 @@ namespace llvm {
// Capability bits used in the definition of cpu_type.
CPUArchMask = 0xff000000, // Mask for architecture bits
CPUArchABI64 = 0x01000000, // 64 bit ABI
-
+
// Constants for the cputype field.
CPUTypeI386 = 7,
CPUTypeX86_64 = CPUTypeI386 | CPUArchABI64,
@@ -673,11 +673,11 @@ namespace llvm {
// Constants for the cpusubtype field.
-
+
// X86
CPUSubType_I386_ALL = 3,
CPUSubType_X86_64_ALL = 3,
-
+
// ARM
CPUSubType_ARM_ALL = 0,
CPUSubType_ARM_V4T = 5,
@@ -687,7 +687,7 @@ namespace llvm {
// PowerPC
CPUSubType_POWERPC_ALL = 0,
-
+
CPUSubType_SPARC_ALL = 0
};
} // end namespace MachO
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index a6b3341c16..53e73ad35f 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -14,8 +14,8 @@
#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
#define LLVM_SUPPORT_MANAGED_STATIC_H
-#include "llvm/System/Atomic.h"
-#include "llvm/System/Threading.h"
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Threading.h"
namespace llvm {
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index dafb479a99..4627557f7f 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -14,8 +14,7 @@
#ifndef LLVM_SUPPORT_MATHEXTRAS_H
#define LLVM_SUPPORT_MATHEXTRAS_H
-#include "llvm/System/DataTypes.h"
-#include "llvm/System/SwapByteOrder.h"
+#include "llvm/Support/SwapByteOrder.h"
namespace llvm {
@@ -77,6 +76,12 @@ inline bool isUIntN(unsigned N, uint64_t x) {
return x == (x & (~0ULL >> (64 - N)));
}
+/// isIntN - Checks if an signed integer fits into the given (dynamic)
+/// bit width.
+inline bool isIntN(unsigned N, int64_t x) {
+ return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
+}
+
/// isMask_32 - This function returns true if the argument is a sequence of ones
/// starting at the least significant bit with the remainder zero (32 bit
/// version). Ex. isMask_32(0x0000FFFFU) == true.
@@ -119,19 +124,19 @@ inline bool isPowerOf2_64(uint64_t Value) {
/// ByteSwap_16 - This function returns a byte-swapped representation of the
/// 16-bit argument, Value.
inline uint16_t ByteSwap_16(uint16_t Value) {
- return sys::SwapByteOrder(Value);
+ return sys::SwapByteOrder_16(Value);
}
/// ByteSwap_32 - This function returns a byte-swapped representation of the
/// 32-bit argument, Value.
inline uint32_t ByteSwap_32(uint32_t Value) {
- return sys::SwapByteOrder(Value);
+ return sys::SwapByteOrder_32(Value);
}
/// ByteSwap_64 - This function returns a byte-swapped representation of the
/// 64-bit argument, Value.
inline uint64_t ByteSwap_64(uint64_t Value) {
- return sys::SwapByteOrder(Value);
+ return sys::SwapByteOrder_64(Value);
}
/// CountLeadingZeros_32 - this function performs the platform optimal form of
diff --git a/include/llvm/System/Memory.h b/include/llvm/Support/Memory.h
index 2dd36e8ab1..9c3f85b958 100644
--- a/include/llvm/System/Memory.h
+++ b/include/llvm/Support/Memory.h
@@ -1,4 +1,4 @@
-//===- llvm/System/Memory.h - Memory Support --------------------*- C++ -*-===//
+//===- llvm/Support/Memory.h - Memory Support --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,7 +14,7 @@
#ifndef LLVM_SYSTEM_MEMORY_H
#define LLVM_SYSTEM_MEMORY_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
@@ -51,7 +51,7 @@ namespace sys {
///
/// On success, this returns a non-null memory block, otherwise it returns
/// a null memory block and fills in *ErrMsg.
- ///
+ ///
/// @brief Allocate Read/Write/Execute memory.
static MemoryBlock AllocateRWX(size_t NumBytes,
const MemoryBlock *NearBlock,
@@ -65,8 +65,8 @@ namespace sys {
/// in *ErrMsg.
/// @brief Release Read/Write/Execute memory.
static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
-
-
+
+
/// InvalidateInstructionCache - Before the JIT can run a block of code
/// that has been emitted it must invalidate the instruction cache on some
/// platforms.
@@ -82,11 +82,11 @@ namespace sys {
/// boundaries, and the JIT internal allocations are not page aligned.
static bool setWritable (MemoryBlock &M, std::string *ErrMsg = 0);
- /// setRangeExecutable - Mark the page containing a range of addresses
+ /// setRangeExecutable - Mark the page containing a range of addresses
/// as executable.
static bool setRangeExecutable(const void *Addr, size_t Size);
- /// setRangeWritable - Mark the page containing a range of addresses
+ /// setRangeWritable - Mark the page containing a range of addresses
/// as writable.
static bool setRangeWritable(const void *Addr, size_t Size);
};
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index eb3e25d3db..b6243b7b10 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -15,12 +15,13 @@
#define LLVM_SUPPORT_MEMORYBUFFER_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
-#include <string>
-#include <sys/stat.h>
+#include "llvm/Support/DataTypes.h"
namespace llvm {
+class error_code;
+template<class T> class OwningPtr;
+
/// MemoryBuffer - This interface provides simple read-only access to a block
/// of memory, and provides simple methods for reading files and standard input
/// into a memory buffer. In addition to basic access to the characters in the
@@ -47,8 +48,8 @@ public:
const char *getBufferEnd() const { return BufferEnd; }
size_t getBufferSize() const { return BufferEnd-BufferStart; }
- StringRef getBuffer() const {
- return StringRef(BufferStart, getBufferSize());
+ StringRef getBuffer() const {
+ return StringRef(BufferStart, getBufferSize());
}
/// getBufferIdentifier - Return an identifier for this buffer, typically the
@@ -61,14 +62,17 @@ 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 MemoryBuffer *getFile(StringRef Filename,
- std::string *ErrStr = 0,
- int64_t FileSize = -1,
- struct stat *FileInfo = 0);
- static MemoryBuffer *getFile(const char *Filename,
- std::string *ErrStr = 0,
- int64_t FileSize = -1,
- struct stat *FileInfo = 0);
+ static error_code getFile(StringRef Filename, OwningPtr<MemoryBuffer> &result,
+ int64_t FileSize = -1);
+ static error_code getFile(const char *Filename,
+ OwningPtr<MemoryBuffer> &result,
+ int64_t FileSize = -1);
+
+ /// getOpenFile - Given an already-open file descriptor, read the file and
+ /// return a MemoryBuffer.
+ static error_code getOpenFile(int FD, const char *Filename,
+ OwningPtr<MemoryBuffer> &result,
+ int64_t FileSize = -1);
/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
/// that InputData must be null terminated.
@@ -95,21 +99,19 @@ public:
StringRef BufferName = "");
/// getSTDIN - Read all of stdin into a file buffer, and return it.
- /// If an error occurs, this returns null and fills in *ErrStr with a reason.
- static MemoryBuffer *getSTDIN(std::string *ErrStr = 0);
+ /// If an error occurs, this returns null and sets ec.
+ static error_code getSTDIN(OwningPtr<MemoryBuffer> &result);
/// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
- /// if the Filename is "-". If an error occurs, this returns null and fills
- /// in *ErrStr with a reason.
- static MemoryBuffer *getFileOrSTDIN(StringRef Filename,
- std::string *ErrStr = 0,
- int64_t FileSize = -1,
- struct stat *FileInfo = 0);
- static MemoryBuffer *getFileOrSTDIN(const char *Filename,
- std::string *ErrStr = 0,
- int64_t FileSize = -1,
- struct stat *FileInfo = 0);
+ /// if the Filename is "-". If an error occurs, this returns null and sets
+ /// ec.
+ static error_code getFileOrSTDIN(StringRef Filename,
+ OwningPtr<MemoryBuffer> &result,
+ int64_t FileSize = -1);
+ static error_code getFileOrSTDIN(const char *Filename,
+ OwningPtr<MemoryBuffer> &result,
+ int64_t FileSize = -1);
};
} // end namespace llvm
diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h
index e193ca2f2b..dec0f134b3 100644
--- a/include/llvm/Support/MemoryObject.h
+++ b/include/llvm/Support/MemoryObject.h
@@ -10,7 +10,7 @@
#ifndef MEMORYOBJECT_H
#define MEMORYOBJECT_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/include/llvm/System/Mutex.h b/include/llvm/Support/Mutex.h
index 71d10067c3..42ea63060f 100644
--- a/include/llvm/System/Mutex.h
+++ b/include/llvm/Support/Mutex.h
@@ -1,4 +1,4 @@
-//===- llvm/System/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
+//===- llvm/Support/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,7 +14,7 @@
#ifndef LLVM_SYSTEM_MUTEX_H
#define LLVM_SYSTEM_MUTEX_H
-#include "llvm/System/Threading.h"
+#include "llvm/Support/Threading.h"
#include <cassert>
namespace llvm
@@ -79,9 +79,9 @@ namespace llvm
void operator=(const MutexImpl &);
/// @}
};
-
-
- /// SmartMutex - A mutex with a compile time constant parameter that
+
+
+ /// SmartMutex - A mutex with a compile time constant parameter that
/// indicates whether this mutex should become a no-op when we're not
/// running in multithreaded mode.
template<bool mt_only>
@@ -91,7 +91,7 @@ namespace llvm
public:
explicit SmartMutex(bool rec = true) :
MutexImpl(rec), acquired(0), recursive(rec) { }
-
+
bool acquire() {
if (!mt_only || llvm_is_multithreaded()) {
return MutexImpl::acquire();
@@ -124,29 +124,29 @@ namespace llvm
return MutexImpl::tryacquire();
else return true;
}
-
+
private:
SmartMutex(const SmartMutex<mt_only> & original);
void operator=(const SmartMutex<mt_only> &);
};
-
+
/// Mutex - A standard, always enforced mutex.
typedef SmartMutex<false> Mutex;
-
+
template<bool mt_only>
class SmartScopedLock {
SmartMutex<mt_only>& mtx;
-
+
public:
SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) {
mtx.acquire();
}
-
+
~SmartScopedLock() {
mtx.release();
}
};
-
+
typedef SmartScopedLock<false> ScopedLock;
}
}
diff --git a/include/llvm/Support/MutexGuard.h b/include/llvm/Support/MutexGuard.h
index 9958b97a3e..cd13bfe6ee 100644
--- a/include/llvm/Support/MutexGuard.h
+++ b/include/llvm/Support/MutexGuard.h
@@ -15,7 +15,7 @@
#ifndef LLVM_SUPPORT_MUTEXGUARD_H
#define LLVM_SUPPORT_MUTEXGUARD_H
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
namespace llvm {
/// Instances of this class acquire a given Mutex Lock when constructed and
diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h
index 01256e18a5..92a9fd695e 100644
--- a/include/llvm/Support/NoFolder.h
+++ b/include/llvm/Support/NoFolder.h
@@ -15,8 +15,7 @@
// llvm/Analysis/ConstantFolding.h.
//
// Note: since it is not actually possible to create unfolded constants, this
-// class returns values rather than constants. The values do not have names,
-// even if names were provided to IRBuilder, which may be confusing.
+// class returns instructions rather than constants.
//
//===----------------------------------------------------------------------===//
@@ -30,7 +29,7 @@ namespace llvm {
class LLVMContext;
-/// NoFolder - Create "constants" (actually, values) with no folding.
+/// NoFolder - Create "constants" (actually, instructions) with no folding.
class NoFolder {
public:
explicit NoFolder(LLVMContext &) {}
@@ -39,84 +38,115 @@ public:
// Binary Operators
//===--------------------------------------------------------------------===//
- Value *CreateAdd(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateAdd(LHS, RHS);
- }
- Value *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateAdd(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+ Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateNSWAdd(LHS, RHS);
}
- Value *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateNUWAdd(LHS, RHS);
}
- Value *CreateFAdd(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFAdd(LHS, RHS);
}
- Value *CreateSub(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateSub(LHS, RHS);
+ Instruction *CreateSub(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
}
- Value *CreateNSWSub(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateNSWSub(LHS, RHS);
}
- Value *CreateNUWSub(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateNUWSub(LHS, RHS);
}
- Value *CreateFSub(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFSub(LHS, RHS);
}
- Value *CreateMul(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateMul(LHS, RHS);
+ Instruction *CreateMul(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
}
- Value *CreateNSWMul(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateNSWMul(LHS, RHS);
}
- Value *CreateNUWMul(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateNUWMul(LHS, RHS);
}
- Value *CreateFMul(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFMul(LHS, RHS);
}
- Value *CreateUDiv(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateUDiv(LHS, RHS);
+ Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ if (!isExact)
+ return BinaryOperator::CreateUDiv(LHS, RHS);
+ return BinaryOperator::CreateExactUDiv(LHS, RHS);
+ }
+ Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateExactUDiv(LHS, RHS);
}
- Value *CreateSDiv(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateSDiv(LHS, RHS);
+ Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ if (!isExact)
+ return BinaryOperator::CreateSDiv(LHS, RHS);
+ return BinaryOperator::CreateExactSDiv(LHS, RHS);
}
- Value *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateExactSDiv(LHS, RHS);
}
- Value *CreateFDiv(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFDiv(LHS, RHS);
}
- Value *CreateURem(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateURem(LHS, RHS);
}
- Value *CreateSRem(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateSRem(LHS, RHS);
}
- Value *CreateFRem(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFRem(LHS, RHS);
}
- Value *CreateShl(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateShl(LHS, RHS);
- }
- Value *CreateLShr(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateLShr(LHS, RHS);
- }
- Value *CreateAShr(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateAShr(LHS, RHS);
- }
- Value *CreateAnd(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
+ bool HasNSW = false) const {
+ BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+ Instruction *CreateLShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ if (!isExact)
+ return BinaryOperator::CreateLShr(LHS, RHS);
+ return BinaryOperator::CreateExactLShr(LHS, RHS);
+ }
+ Instruction *CreateAShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ if (!isExact)
+ return BinaryOperator::CreateAShr(LHS, RHS);
+ return BinaryOperator::CreateExactAShr(LHS, RHS);
+ }
+ Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateAnd(LHS, RHS);
}
- Value *CreateOr(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateOr(LHS, RHS);
}
- Value *CreateXor(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateXor(LHS, RHS);
}
- Value *CreateBinOp(Instruction::BinaryOps Opc,
- Constant *LHS, Constant *RHS) const {
+ Instruction *CreateBinOp(Instruction::BinaryOps Opc,
+ Constant *LHS, Constant *RHS) const {
return BinaryOperator::Create(Opc, LHS, RHS);
}
@@ -124,16 +154,23 @@ public:
// Unary Operators
//===--------------------------------------------------------------------===//
- Value *CreateNeg(Constant *C) const {
- return BinaryOperator::CreateNeg(C);
- }
- Value *CreateNSWNeg(Constant *C) const {
+ Instruction *CreateNeg(Constant *C,
+ bool HasNUW = false, bool HasNSW = false) const {
+ BinaryOperator *BO = BinaryOperator::CreateNeg(C);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+ Instruction *CreateNSWNeg(Constant *C) const {
return BinaryOperator::CreateNSWNeg(C);
}
- Value *CreateNUWNeg(Constant *C) const {
+ Instruction *CreateNUWNeg(Constant *C) const {
return BinaryOperator::CreateNUWNeg(C);
}
- Value *CreateNot(Constant *C) const {
+ Instruction *CreateFNeg(Constant *C) const {
+ return BinaryOperator::CreateFNeg(C);
+ }
+ Instruction *CreateNot(Constant *C) const {
return BinaryOperator::CreateNot(C);
}
@@ -145,8 +182,8 @@ public:
unsigned NumIdx) const {
return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx);
}
- Value *CreateGetElementPtr(Constant *C, Value* const *IdxList,
- unsigned NumIdx) const {
+ Instruction *CreateGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
return GetElementPtrInst::Create(C, IdxList, IdxList+NumIdx);
}
@@ -154,8 +191,8 @@ public:
unsigned NumIdx) const {
return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx);
}
- Value *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
- unsigned NumIdx) const {
+ Instruction *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
return GetElementPtrInst::CreateInBounds(C, IdxList, IdxList+NumIdx);
}
@@ -163,23 +200,51 @@ public:
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
- Value *CreateCast(Instruction::CastOps Op, Constant *C,
+ Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
const Type *DestTy) const {
return CastInst::Create(Op, C, DestTy);
}
- Value *CreateIntCast(Constant *C, const Type *DestTy,
+ Instruction *CreatePointerCast(Constant *C, const Type *DestTy) const {
+ return CastInst::CreatePointerCast(C, DestTy);
+ }
+ Instruction *CreateIntCast(Constant *C, const Type *DestTy,
bool isSigned) const {
return CastInst::CreateIntegerCast(C, DestTy, isSigned);
}
+ Instruction *CreateFPCast(Constant *C, const Type *DestTy) const {
+ return CastInst::CreateFPCast(C, DestTy);
+ }
+
+ Instruction *CreateBitCast(Constant *C, const Type *DestTy) const {
+ return CreateCast(Instruction::BitCast, C, DestTy);
+ }
+ Instruction *CreateIntToPtr(Constant *C, const Type *DestTy) const {
+ return CreateCast(Instruction::IntToPtr, C, DestTy);
+ }
+ Instruction *CreatePtrToInt(Constant *C, const Type *DestTy) const {
+ return CreateCast(Instruction::PtrToInt, C, DestTy);
+ }
+ Instruction *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const {
+ return CastInst::CreateZExtOrBitCast(C, DestTy);
+ }
+ Instruction *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const {
+ return CastInst::CreateSExtOrBitCast(C, DestTy);
+ }
+
+ Instruction *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const {
+ return CastInst::CreateTruncOrBitCast(C, DestTy);
+ }
//===--------------------------------------------------------------------===//
// Compare Instructions
//===--------------------------------------------------------------------===//
- Value *CreateICmp(CmpInst::Predicate P, Constant *LHS, Constant *RHS) const {
+ Instruction *CreateICmp(CmpInst::Predicate P,
+ Constant *LHS, Constant *RHS) const {
return new ICmpInst(P, LHS, RHS);
}
- Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFCmp(CmpInst::Predicate P,
+ Constant *LHS, Constant *RHS) const {
return new FCmpInst(P, LHS, RHS);
}
@@ -187,30 +252,33 @@ public:
// Other Instructions
//===--------------------------------------------------------------------===//
- Value *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+ Instruction *CreateSelect(Constant *C,
+ Constant *True, Constant *False) const {
return SelectInst::Create(C, True, False);
}
- Value *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+ Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
return ExtractElementInst::Create(Vec, Idx);
}
- Value *CreateInsertElement(Constant *Vec, Constant *NewElt,
- Constant *Idx) const {
+ Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
+ Constant *Idx) const {
return InsertElementInst::Create(Vec, NewElt, Idx);
}
- Value *CreateShuffleVector(Constant *V1, Constant *V2, Constant *Mask) const {
+ Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
+ Constant *Mask) const {
return new ShuffleVectorInst(V1, V2, Mask);
}
- Value *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
- unsigned NumIdx) const {
+ Instruction *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
+ unsigned NumIdx) const {
return ExtractValueInst::Create(Agg, IdxList, IdxList+NumIdx);
}
- Value *CreateInsertValue(Constant *Agg, Constant *Val,
- const unsigned *IdxList, unsigned NumIdx) const {
+ Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
+ const unsigned *IdxList,
+ unsigned NumIdx) const {
return InsertValueInst::Create(Agg, Val, IdxList, IdxList+NumIdx);
}
};
diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h
new file mode 100644
index 0000000000..196eecce81
--- /dev/null
+++ b/include/llvm/Support/Path.h
@@ -0,0 +1,16 @@
+//===- llvm/Support/Path.h - Path Operating System Concept ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file currently includes both PathV1 and PathV2 to facilitate moving
+// clients over to the new interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/PathV1.h"
+#include "llvm/Support/PathV2.h"
diff --git a/include/llvm/System/Path.h b/include/llvm/Support/PathV1.h
index eca9dd9f87..d7753a3e71 100644
--- a/include/llvm/System/Path.h
+++ b/include/llvm/Support/PathV1.h
@@ -1,4 +1,4 @@
-//===- llvm/System/Path.h - Path Operating System Concept -------*- C++ -*-===//
+//===- llvm/Support/PathV1.h - Path Operating System Concept ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,11 +15,17 @@
#define LLVM_SYSTEM_PATH_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/TimeValue.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TimeValue.h"
#include <set>
#include <string>
#include <vector>
+#define LLVM_PATH_DEPRECATED_MSG(replacement) \
+ "PathV1 has been deprecated and will be removed as soon as all LLVM and" \
+ " Clang clients have been moved over to PathV2. Please use `" #replacement \
+ "` from PathV2 instead."
+
namespace llvm {
namespace sys {
@@ -92,7 +98,8 @@ namespace sys {
/// it is file:///. Other operating systems may have different notions of
/// what the root directory is or none at all. In that case, a consistent
/// default root directory will be used.
- static Path GetRootDirectory();
+ LLVM_ATTRIBUTE_DEPRECATED(static Path GetRootDirectory(),
+ LLVM_PATH_DEPRECATED_MSG(NOTHING));
/// Construct a path to a unique temporary directory that is created in
/// a "standard" place for the operating system. The directory is
@@ -100,7 +107,7 @@ namespace sys {
/// cannot be created, the function will throw an exception.
/// @returns an invalid path (empty) on error
/// @param ErrMsg Optional place for an error message if an error occurs
- /// @brief Constrct a path to an new, unique, existing temporary
+ /// @brief Construct a path to an new, unique, existing temporary
/// directory.
static Path GetTemporaryDirectory(std::string* ErrMsg = 0);
@@ -254,23 +261,27 @@ namespace sys {
bool isEmpty() const { return path.empty(); }
/// This function returns the last component of the path name. The last
- /// component is the file or directory name occuring after the last
+ /// component is the file or directory name occurring after the last
/// directory separator. If no directory separator is present, the entire
/// path name is returned (i.e. same as toString).
/// @returns StringRef containing the last component of the path name.
/// @brief Returns the last component of the path name.
- StringRef getLast() const;
+ LLVM_ATTRIBUTE_DEPRECATED(
+ StringRef getLast() const,
+ LLVM_PATH_DEPRECATED_MSG(path::filename));
/// This function strips off the path and suffix of the file or directory
/// name and returns just the basename. For example /a/foo.bar would cause
/// this function to return "foo".
/// @returns StringRef containing the basename of the path
/// @brief Get the base name of the path
- StringRef getBasename() const;
+ LLVM_ATTRIBUTE_DEPRECATED(StringRef getBasename() const,
+ LLVM_PATH_DEPRECATED_MSG(path::stem));
/// This function strips off the suffix of the path beginning with the
/// path separator ('/' on Unix, '\' on Windows) and returns the result.
- StringRef getDirname() const;
+ LLVM_ATTRIBUTE_DEPRECATED(StringRef getDirname() const,
+ LLVM_PATH_DEPRECATED_MSG(path::parent_path));
/// This function strips off the path and basename(up to and
/// including the last dot) of the file or directory name and
@@ -278,7 +289,8 @@ namespace sys {
/// this function to return "bar".
/// @returns StringRef containing the suffix of the path
/// @brief Get the suffix of the path
- StringRef getSuffix() const;
+ LLVM_ATTRIBUTE_DEPRECATED(StringRef getSuffix() const,
+ LLVM_PATH_DEPRECATED_MSG(path::extension));
/// Obtain a 'C' string for the path name.
/// @returns a 'C' string containing the path name.
@@ -300,12 +312,16 @@ namespace sys {
/// This function determines if the path name is absolute, as opposed to
/// relative.
/// @brief Determine if the path is absolute.
- bool isAbsolute() const;
+ LLVM_ATTRIBUTE_DEPRECATED(
+ bool isAbsolute() const,
+ LLVM_PATH_DEPRECATED_MSG(path::is_absolute));
/// This function determines if the path name is absolute, as opposed to
/// relative.
/// @brief Determine if the path is absolute.
- static bool isAbsolute(const char *NameStart, unsigned NameLen);
+ LLVM_ATTRIBUTE_DEPRECATED(
+ static bool isAbsolute(const char *NameStart, unsigned NameLen),
+ LLVM_PATH_DEPRECATED_MSG(path::is_absolute));
/// This function opens the file associated with the path name provided by
/// the Path object and reads its magic number. If the magic number at the
@@ -313,7 +329,8 @@ namespace sys {
/// cases (file not found, file not accessible, etc.) it returns false.
/// @returns true if the magic number of the file matches \p magic.
/// @brief Determine if file has a specific magic number
- bool hasMagicNumber(StringRef magic) const;
+ LLVM_ATTRIBUTE_DEPRECATED(bool hasMagicNumber(StringRef magic) const,
+ LLVM_PATH_DEPRECATED_MSG(fs::has_magic));
/// This function retrieves the first \p len bytes of the file associated
/// with \p this. These bytes are returned as the "magic number" in the
@@ -363,19 +380,22 @@ namespace sys {
/// directory.
/// @brief Determines if the path is a file or directory in
/// the file system.
- bool exists() const;
+ LLVM_ATTRIBUTE_DEPRECATED(bool exists() const,
+ LLVM_PATH_DEPRECATED_MSG(fs::exists));
/// This function determines if the path name references an
/// existing directory.
/// @returns true if the pathname references an existing directory.
/// @brief Determines if the path is a directory in the file system.
- bool isDirectory() const;
+ LLVM_ATTRIBUTE_DEPRECATED(bool isDirectory() const,
+ LLVM_PATH_DEPRECATED_MSG(fs::is_directory));
/// This function determines if the path name references an
/// existing symbolic link.
/// @returns true if the pathname references an existing symlink.
/// @brief Determines if the path is a symlink in the file system.
- bool isSymLink() const;
+ LLVM_ATTRIBUTE_DEPRECATED(bool isSymLink() const,
+ LLVM_PATH_DEPRECATED_MSG(fs::is_symlink));
/// This function determines if the path name references a readable file
/// or directory in the file system. This function checks for
@@ -455,14 +475,9 @@ namespace sys {
bool appendComponent(StringRef component);
/// A period and the \p suffix are appended to the end of the pathname.
- /// The precondition for this function is that the Path reference a file
- /// name (i.e. isFile() returns true). If the Path is not a file, no
- /// action is taken and the function returns false. If the path would
- /// become invalid for the host operating system, false is returned. When
- /// the \p suffix is empty, no action is performed.
- /// @returns false if the suffix could not be added, true if it was.
+ /// When the \p suffix is empty, no action is performed.
/// @brief Adds a period and the \p suffix to the end of the pathname.
- bool appendSuffix(StringRef suffix);
+ void appendSuffix(StringRef suffix);
/// The suffix of the filename is erased. The suffix begins with and
/// includes the last . character in the filename after the last directory
@@ -484,7 +499,9 @@ namespace sys {
/// The current Path name is made absolute by prepending the
/// current working directory if necessary.
- void makeAbsolute();
+ LLVM_ATTRIBUTE_DEPRECATED(
+ void makeAbsolute(),
+ LLVM_PATH_DEPRECATED_MSG(fs::make_absolute));
/// @}
/// @name Disk Mutators
@@ -616,7 +633,7 @@ namespace sys {
/// efficiency. First, the file status requires additional space and the space
/// is incorporated directly into PathWithStatus without an additional malloc.
/// Second, obtaining status information is an expensive operation on most
- /// operating systems so we want to be careful and explicity about where we
+ /// operating systems so we want to be careful and explicit about where we
/// allow this operation in LLVM.
/// @brief Path with file status class.
class PathWithStatus : public Path {
@@ -710,7 +727,7 @@ namespace sys {
Mach_O_Executable_FileType, ///< Mach-O Executable
Mach_O_FixedVirtualMemorySharedLib_FileType, ///< Mach-O Shared Lib, FVM
Mach_O_Core_FileType, ///< Mach-O Core File
- Mach_O_PreloadExectuable_FileType, ///< Mach-O Preloaded Executable
+ Mach_O_PreloadExecutable_FileType, ///< Mach-O Preloaded Executable
Mach_O_DynamicallyLinkedSharedLib_FileType, ///< Mach-O dynlinked shared lib
Mach_O_DynamicLinker_FileType, ///< The Mach-O dynamic linker
Mach_O_Bundle_FileType, ///< Mach-O Bundle file
diff --git a/include/llvm/Support/PathV2.h b/include/llvm/Support/PathV2.h
new file mode 100644
index 0000000000..251563398f
--- /dev/null
+++ b/include/llvm/Support/PathV2.h
@@ -0,0 +1,347 @@
+//===- llvm/Support/PathV2.h - Path Operating System Concept ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::path namespace. It is designed after
+// TR2/boost filesystem (v3), but modified to remove exception handling and the
+// path class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PATHV2_H
+#define LLVM_SUPPORT_PATHV2_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/DataTypes.h"
+#include <iterator>
+
+namespace llvm {
+namespace sys {
+namespace path {
+
+/// @name Lexical Component Iterator
+/// @{
+
+/// @brief Path iterator.
+///
+/// This is a bidirectional iterator that iterates over the individual
+/// components in \a path. The forward traversal order is as follows:
+/// * The root-name element, if present.
+/// * The root-directory element, if present.
+/// * Each successive filename element, if present.
+/// * Dot, if one or more trailing non-root slash characters are present.
+/// The backwards traversal order is the reverse of forward traversal.
+///
+/// Iteration examples. Each component is separated by ',':
+/// / => /
+/// /foo => /,foo
+/// foo/ => foo,.
+/// /foo/bar => /,foo,bar
+/// ../ => ..,.
+/// C:\foo\bar => C:,/,foo,bar
+///
+class const_iterator {
+ StringRef Path; //< The entire path.
+ StringRef Component; //< The current component. Not necessarily in Path.
+ size_t Position; //< The iterators current position within Path.
+
+ // An end iterator has Position = Path.size() + 1.
+ friend const_iterator begin(StringRef path);
+ friend const_iterator end(StringRef path);
+
+public:
+ typedef const StringRef value_type;
+ typedef ptrdiff_t difference_type;
+ typedef value_type &reference;
+ typedef value_type *pointer;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ reference operator*() const { return Component; }
+ pointer operator->() const { return &Component; }
+ const_iterator &operator++(); // preincrement
+ const_iterator &operator++(int); // postincrement
+ const_iterator &operator--(); // predecrement
+ const_iterator &operator--(int); // postdecrement
+ bool operator==(const const_iterator &RHS) const;
+ bool operator!=(const const_iterator &RHS) const;
+
+ /// @brief Difference in bytes between this and RHS.
+ ptrdiff_t operator-(const const_iterator &RHS) const;
+};
+
+typedef std::reverse_iterator<const_iterator> reverse_iterator;
+
+/// @brief Get begin iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized with the first component of \a path.
+const_iterator begin(StringRef path);
+
+/// @brief Get end iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized to the end of \a path.
+const_iterator end(StringRef path);
+
+/// @brief Get reverse begin iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized with the first reverse component of \a path.
+inline reverse_iterator rbegin(StringRef path) {
+ return reverse_iterator(end(path));
+}
+
+/// @brief Get reverse end iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized to the reverse end of \a path.
+inline reverse_iterator rend(StringRef path) {
+ return reverse_iterator(begin(path));
+}
+
+/// @}
+/// @name Lexical Modifiers
+/// @{
+
+/// @brief Remove the last component from \a path unless it is the root dir.
+///
+/// directory/filename.cpp => directory/
+/// directory/ => directory
+/// / => /
+///
+/// @param path A path that is modified to not have a file component.
+void remove_filename(SmallVectorImpl<char> &path);
+
+/// @brief Replace the file extension of \a path with \a extension.
+///
+/// ./filename.cpp => ./filename.extension
+/// ./filename => ./filename.extension
+/// ./ => ./.extension
+///
+/// @param path A path that has its extension replaced with \a extension.
+/// @param extension The extension to be added. It may be empty. It may also
+/// optionally start with a '.', if it does not, one will be
+/// prepended.
+void replace_extension(SmallVectorImpl<char> &path, const Twine &extension);
+
+/// @brief Append to path.
+///
+/// /foo + bar/f => /foo/bar/f
+/// /foo/ + bar/f => /foo/bar/f
+/// foo + bar/f => foo/bar/f
+///
+/// @param path Set to \a path + \a component.
+/// @param component The component to be appended to \a path.
+void append(SmallVectorImpl<char> &path, const Twine &a,
+ const Twine &b = "",
+ const Twine &c = "",
+ const Twine &d = "");
+
+/// @brief Append to path.
+///
+/// /foo + [bar,f] => /foo/bar/f
+/// /foo/ + [bar,f] => /foo/bar/f
+/// foo + [bar,f] => foo/bar/f
+///
+/// @param path Set to \a path + [\a begin, \a end).
+/// @param begin Start of components to append.
+/// @param end One past the end of components to append.
+void append(SmallVectorImpl<char> &path,
+ const_iterator begin, const_iterator end);
+
+/// @}
+/// @name Transforms (or some other better name)
+/// @{
+
+/// Convert path to the native form. This is used to give paths to users and
+/// operating system calls in the platform's normal way. For example, on Windows
+/// all '/' are converted to '\'.
+///
+/// @param path A path that is transformed to native format.
+/// @param result Holds the result of the transformation.
+void native(const Twine &path, SmallVectorImpl<char> &result);
+
+/// @}
+/// @name Lexical Observers
+/// @{
+
+/// @brief Get root name.
+///
+/// //net/hello => //net
+/// c:/hello => c: (on Windows, on other platforms nothing)
+/// /hello => <empty>
+///
+/// @param path Input path.
+/// @result The root name of \a path if it has one, otherwise "".
+const StringRef root_name(StringRef path);
+
+/// @brief Get root directory.
+///
+/// /goo/hello => /
+/// c:/hello => /
+/// d/file.txt => <empty>
+///
+/// @param path Input path.
+/// @result The root directory of \a path if it has one, otherwise
+/// "".
+const StringRef root_directory(StringRef path);
+
+/// @brief Get root path.
+///
+/// Equivalent to root_name + root_directory.
+///
+/// @param path Input path.
+/// @result The root path of \a path if it has one, otherwise "".
+const StringRef root_path(StringRef path);
+
+/// @brief Get relative path.
+///
+/// C:\hello\world => hello\world
+/// foo/bar => foo/bar
+/// /foo/bar => foo/bar
+///
+/// @param path Input path.
+/// @result The path starting after root_path if one exists, otherwise "".
+const StringRef relative_path(StringRef path);
+
+/// @brief Get parent path.
+///
+/// / => <empty>
+/// /foo => /
+/// foo/../bar => foo/..
+///
+/// @param path Input path.
+/// @result The parent path of \a path if one exists, otherwise "".
+const StringRef parent_path(StringRef path);
+
+/// @brief Get filename.
+///
+/// /foo.txt => foo.txt
+/// . => .
+/// .. => ..
+/// / => /
+///
+/// @param path Input path.
+/// @result The filename part of \a path. This is defined as the last component
+/// of \a path.
+const StringRef filename(StringRef path);
+
+/// @brief Get stem.
+///
+/// If filename contains a dot but not solely one or two dots, result is the
+/// substring of filename ending at (but not including) the last dot. Otherwise
+/// it is filename.
+///
+/// /foo/bar.txt => bar
+/// /foo/bar => bar
+/// /foo/.txt => <empty>
+/// /foo/. => .
+/// /foo/.. => ..
+///
+/// @param path Input path.
+/// @result The stem of \a path.
+const StringRef stem(StringRef path);
+
+/// @brief Get extension.
+///
+/// If filename contains a dot but not solely one or two dots, result is the
+/// substring of filename starting at (and including) the last dot, and ending
+/// at the end of \a path. Otherwise "".
+///
+/// /foo/bar.txt => .txt
+/// /foo/bar => <empty>
+/// /foo/.txt => .txt
+///
+/// @param path Input path.
+/// @result The extension of \a path.
+const StringRef extension(StringRef path);
+
+/// @brief Check whether the given char is a path separator on the host OS.
+///
+/// @param value a character
+/// @result true if \a value is a path separator character on the host OS
+bool is_separator(char value);
+
+/// @brief Has root name?
+///
+/// root_name != ""
+///
+/// @param path Input path.
+/// @result True if the path has a root name, false otherwise.
+bool has_root_name(const Twine &path);
+
+/// @brief Has root directory?
+///
+/// root_directory != ""
+///
+/// @param path Input path.
+/// @result True if the path has a root directory, false otherwise.
+bool has_root_directory(const Twine &path);
+
+/// @brief Has root path?
+///
+/// root_path != ""
+///
+/// @param path Input path.
+/// @result True if the path has a root path, false otherwise.
+bool has_root_path(const Twine &path);
+
+/// @brief Has relative path?
+///
+/// relative_path != ""
+///
+/// @param path Input path.
+/// @result True if the path has a relative path, false otherwise.
+bool has_relative_path(const Twine &path);
+
+/// @brief Has parent path?
+///
+/// parent_path != ""
+///
+/// @param path Input path.
+/// @result True if the path has a parent path, false otherwise.
+bool has_parent_path(const Twine &path);
+
+/// @brief Has filename?
+///
+/// filename != ""
+///
+/// @param path Input path.
+/// @result True if the path has a filename, false otherwise.
+bool has_filename(const Twine &path);
+
+/// @brief Has stem?
+///
+/// stem != ""
+///
+/// @param path Input path.
+/// @result True if the path has a stem, false otherwise.
+bool has_stem(const Twine &path);
+
+/// @brief Has extension?
+///
+/// extension != ""
+///
+/// @param path Input path.
+/// @result True if the path has a extension, false otherwise.
+bool has_extension(const Twine &path);
+
+/// @brief Is path absolute?
+///
+/// @param path Input path.
+/// @result True if the path is absolute, false if it is not.
+bool is_absolute(const Twine &path);
+
+/// @brief Is path relative?
+///
+/// @param path Input path.
+/// @result True if the path is relative, false if it is not.
+bool is_relative(const Twine &path);
+
+} // end namespace path
+} // end namespace sys
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index bee6768637..948ae5176e 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/Support/PatternMatch.h
@@ -41,18 +41,62 @@ bool match(Val *V, const Pattern &P) {
}
template<typename Class>
-struct leaf_ty {
+struct class_match {
template<typename ITy>
bool match(ITy *V) { return isa<Class>(V); }
};
/// m_Value() - Match an arbitrary value and ignore it.
-inline leaf_ty<Value> m_Value() { return leaf_ty<Value>(); }
+inline class_match<Value> m_Value() { return class_match<Value>(); }
/// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it.
-inline leaf_ty<ConstantInt> m_ConstantInt() { return leaf_ty<ConstantInt>(); }
+inline class_match<ConstantInt> m_ConstantInt() {
+ return class_match<ConstantInt>();
+}
+/// m_Undef() - Match an arbitrary undef constant.
+inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); }
+inline class_match<Constant> m_Constant() { return class_match<Constant>(); }
+
+struct match_zero {
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const Constant *C = dyn_cast<Constant>(V))
+ return C->isNullValue();
+ return false;
+ }
+};
+
+/// m_Zero() - Match an arbitrary zero/null constant. This includes
+/// zero_initializer for vectors and ConstantPointerNull for pointers.
+inline match_zero m_Zero() { return match_zero(); }
+
+
+struct apint_match {
+ const APInt *&Res;
+ apint_match(const APInt *&R) : Res(R) {}
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ Res = &CI->getValue();
+ return true;
+ }
+ if (ConstantVector *CV = dyn_cast<ConstantVector>(V))
+ if (ConstantInt *CI =
+ dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
+ return false;
+ }
+};
+
+/// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the
+/// specified pointer to the contained APInt.
+inline apint_match m_APInt(const APInt *&Res) { return Res; }
+
+
template<int64_t Val>
-struct constantint_ty {
+struct constantint_match {
template<typename ITy>
bool match(ITy *V) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
@@ -68,37 +112,82 @@ struct constantint_ty {
}
};
-/// m_ConstantInt(int64_t) - Match a ConstantInt with a specific value
-/// and ignore it.
+/// m_ConstantInt<int64_t> - Match a ConstantInt with a specific value.
template<int64_t Val>
-inline constantint_ty<Val> m_ConstantInt() {
- return constantint_ty<Val>();
+inline constantint_match<Val> m_ConstantInt() {
+ return constantint_match<Val>();
}
-struct zero_ty {
+/// cst_pred_ty - This helper class is used to match scalar and vector constants
+/// that satisfy a specified predicate.
+template<typename Predicate>
+struct cst_pred_ty : public Predicate {
template<typename ITy>
bool match(ITy *V) {
- if (const Constant *C = dyn_cast<Constant>(V))
- return C->isNullValue();
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ return this->isValue(CI->getValue());
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
+ if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
+ return this->isValue(CI->getValue());
return false;
}
};
-
-/// m_Zero() - Match an arbitrary zero/null constant.
-inline zero_ty m_Zero() { return zero_ty(); }
-
-struct one_ty {
+
+/// api_pred_ty - This helper class is used to match scalar and vector constants
+/// that satisfy a specified predicate, and bind them to an APInt.
+template<typename Predicate>
+struct api_pred_ty : public Predicate {
+ const APInt *&Res;
+ api_pred_ty(const APInt *&R) : Res(R) {}
template<typename ITy>
bool match(ITy *V) {
- if (const ConstantInt *C = dyn_cast<ConstantInt>(V))
- return C->isOne();
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ if (this->isValue(CI->getValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
+ if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
+ if (this->isValue(CI->getValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
return false;
}
};
+
+
+struct is_one {
+ bool isValue(const APInt &C) { return C == 1; }
+};
-/// m_One() - Match a an integer 1.
-inline one_ty m_One() { return one_ty(); }
+/// m_One() - Match an integer 1 or a vector with all elements equal to 1.
+inline cst_pred_ty<is_one> m_One() { return cst_pred_ty<is_one>(); }
+inline api_pred_ty<is_one> m_One(const APInt *&V) { return V; }
+
+struct is_all_ones {
+ bool isValue(const APInt &C) { return C.isAllOnesValue(); }
+};
+/// m_AllOnes() - Match an integer or vector with all bits set to true.
+inline cst_pred_ty<is_all_ones> m_AllOnes() {return cst_pred_ty<is_all_ones>();}
+inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; }
+
+struct is_sign_bit {
+ bool isValue(const APInt &C) { return C.isSignBit(); }
+};
+
+/// m_SignBit() - Match an integer or vector with only the sign bit(s) set.
+inline cst_pred_ty<is_sign_bit> m_SignBit() {return cst_pred_ty<is_sign_bit>();}
+inline api_pred_ty<is_sign_bit> m_SignBit(const APInt *&V) { return V; }
+
+struct is_power2 {
+ bool isValue(const APInt &C) { return C.isPowerOf2(); }
+};
+
+/// m_Power2() - Match an integer or vector power of 2.
+inline cst_pred_ty<is_power2> m_Power2() { return cst_pred_ty<is_power2>(); }
+inline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; }
template<typename Class>
struct bind_ty {
@@ -121,6 +210,9 @@ inline bind_ty<Value> m_Value(Value *&V) { return V; }
/// m_ConstantInt - Match a ConstantInt, capturing the value if we match.
inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
+/// m_Constant - Match a Constant, capturing the value if we match.
+inline bind_ty<Constant> m_Constant(Constant *&C) { return C; }
+
/// specificval_ty - Match a specified Value*.
struct specificval_ty {
const Value *Val;
@@ -140,8 +232,7 @@ inline specificval_ty m_Specific(const Value *V) { return V; }
// Matchers for specific binary operators.
//
-template<typename LHS_t, typename RHS_t,
- unsigned Opcode, typename ConcreteTy = BinaryOperator>
+template<typename LHS_t, typename RHS_t, unsigned Opcode>
struct BinaryOp_match {
LHS_t L;
RHS_t R;
@@ -151,9 +242,8 @@ struct BinaryOp_match {
template<typename OpTy>
bool match(OpTy *V) {
if (V->getValueID() == Value::InstructionVal + Opcode) {
- ConcreteTy *I = cast<ConcreteTy>(V);
- return I->getOpcode() == Opcode && L.match(I->getOperand(0)) &&
- R.match(I->getOperand(1));
+ BinaryOperator *I = cast<BinaryOperator>(V);
+ return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
}
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
@@ -163,193 +253,156 @@ struct BinaryOp_match {
};
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Add> m_Add(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Add>
+m_Add(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FAdd> m_FAdd(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::FAdd>
+m_FAdd(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FAdd>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Sub> m_Sub(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Sub>
+m_Sub(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FSub> m_FSub(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::FSub>
+m_FSub(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Mul>
+m_Mul(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FMul> m_FMul(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::FMul>
+m_FMul(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FMul>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::UDiv>
+m_UDiv(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::SDiv> m_SDiv(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::SDiv>
+m_SDiv(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FDiv> m_FDiv(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::FDiv>
+m_FDiv(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::URem> m_URem(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::URem>
+m_URem(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::SRem> m_SRem(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::SRem>
+m_SRem(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FRem> m_FRem(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::FRem>
+m_FRem(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::And> m_And(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::And>
+m_And(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Or> m_Or(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Or>
+m_Or(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Xor> m_Xor(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Xor>
+m_Xor(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Shl> m_Shl(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::Shl>
+m_Shl(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::LShr> m_LShr(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::LShr>
+m_LShr(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
}
template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::AShr> m_AShr(const LHS &L,
- const RHS &R) {
+inline BinaryOp_match<LHS, RHS, Instruction::AShr>
+m_AShr(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
}
//===----------------------------------------------------------------------===//
-// Matchers for either AShr or LShr .. for convenience
+// Class that matches two different binary ops.
//
-template<typename LHS_t, typename RHS_t, typename ConcreteTy = BinaryOperator>
-struct Shr_match {
+template<typename LHS_t, typename RHS_t, unsigned Opc1, unsigned Opc2>
+struct BinOp2_match {
LHS_t L;
RHS_t R;
- Shr_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+ BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
template<typename OpTy>
bool match(OpTy *V) {
- if (V->getValueID() == Value::InstructionVal + Instruction::LShr ||
- V->getValueID() == Value::InstructionVal + Instruction::AShr) {
- ConcreteTy *I = cast<ConcreteTy>(V);
- return (I->getOpcode() == Instruction::AShr ||
- I->getOpcode() == Instruction::LShr) &&
- L.match(I->getOperand(0)) &&
- R.match(I->getOperand(1));
+ if (V->getValueID() == Value::InstructionVal + Opc1 ||
+ V->getValueID() == Value::InstructionVal + Opc2) {
+ BinaryOperator *I = cast<BinaryOperator>(V);
+ return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
}
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- return (CE->getOpcode() == Instruction::LShr ||
- CE->getOpcode() == Instruction::AShr) &&
- L.match(CE->getOperand(0)) &&
- R.match(CE->getOperand(1));
+ return (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) &&
+ L.match(CE->getOperand(0)) && R.match(CE->getOperand(1));
return false;
}
};
+/// m_Shr - Matches LShr or AShr.
template<typename LHS, typename RHS>
-inline Shr_match<LHS, RHS> m_Shr(const LHS &L, const RHS &R) {
- return Shr_match<LHS, RHS>(L, R);
+inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>
+m_Shr(const LHS &L, const RHS &R) {
+ return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>(L, R);
}
-//===----------------------------------------------------------------------===//
-// Matchers for binary classes
-//
-
-template<typename LHS_t, typename RHS_t, typename Class, typename OpcType>
-struct BinaryOpClass_match {
- OpcType *Opcode;
- LHS_t L;
- RHS_t R;
-
- BinaryOpClass_match(OpcType &Op, const LHS_t &LHS,
- const RHS_t &RHS)
- : Opcode(&Op), L(LHS), R(RHS) {}
- BinaryOpClass_match(const LHS_t &LHS, const RHS_t &RHS)
- : Opcode(0), L(LHS), R(RHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (Class *I = dyn_cast<Class>(V))
- if (L.match(I->getOperand(0)) &&
- R.match(I->getOperand(1))) {
- if (Opcode)
- *Opcode = I->getOpcode();
- return true;
- }
-#if 0 // Doesn't handle constantexprs yet!
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
- R.match(CE->getOperand(1));
-#endif
- return false;
- }
-};
-
+/// m_LogicalShift - Matches LShr or Shl.
template<typename LHS, typename RHS>
-inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
-m_Shift(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) {
- return BinaryOpClass_match<LHS, RHS,
- BinaryOperator, Instruction::BinaryOps>(Op, L, R);
+inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>
+m_LogicalShift(const LHS &L, const RHS &R) {
+ return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>(L, R);
}
+/// m_IDiv - Matches UDiv and SDiv.
template<typename LHS, typename RHS>
-inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
-m_Shift(const LHS &L, const RHS &R) {
- return BinaryOpClass_match<LHS, RHS,
- BinaryOperator, Instruction::BinaryOps>(L, R);
+inline BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>
+m_IDiv(const LHS &L, const RHS &R) {
+ return BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>(L, R);
}
//===----------------------------------------------------------------------===//
@@ -362,15 +415,13 @@ struct CmpClass_match {
LHS_t L;
RHS_t R;
- CmpClass_match(PredicateTy &Pred, const LHS_t &LHS,
- const RHS_t &RHS)
+ CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, const RHS_t &RHS)
: Predicate(Pred), L(LHS), R(RHS) {}
template<typename OpTy>
bool match(OpTy *V) {
if (Class *I = dyn_cast<Class>(V))
- if (L.match(I->getOperand(0)) &&
- R.match(I->getOperand(1))) {
+ if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
Predicate = I->getPredicate();
return true;
}
@@ -425,11 +476,9 @@ m_Select(const Cond &C, const LHS &L, const RHS &R) {
/// m_SelectCst - This matches a select of two constants, e.g.:
/// m_SelectCst<-1, 0>(m_Value(V))
template<int64_t L, int64_t R, typename Cond>
-inline SelectClass_match<Cond, constantint_ty<L>, constantint_ty<R> >
+inline SelectClass_match<Cond, constantint_match<L>, constantint_match<R> >
m_SelectCst(const Cond &C) {
- return SelectClass_match<Cond, constantint_ty<L>,
- constantint_ty<R> >(C, m_ConstantInt<L>(),
- m_ConstantInt<R>());
+ return m_Select(C, m_ConstantInt<L>(), m_ConstantInt<R>());
}
@@ -507,20 +556,14 @@ struct not_match {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
if (CE->getOpcode() == Instruction::Xor)
return matchIfNot(CE->getOperand(0), CE->getOperand(1));
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
- return L.match(ConstantExpr::getNot(CI));
return false;
}
private:
bool matchIfNot(Value *LHS, Value *RHS) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
return CI->isAllOnesValue() && L.match(LHS);
- if (ConstantInt *CI = dyn_cast<ConstantInt>(LHS))
- return CI->isAllOnesValue() && L.match(RHS);
if (ConstantVector *CV = dyn_cast<ConstantVector>(RHS))
return CV->isAllOnesValue() && L.match(LHS);
- if (ConstantVector *CV = dyn_cast<ConstantVector>(LHS))
- return CV->isAllOnesValue() && L.match(RHS);
return false;
}
};
@@ -543,17 +586,17 @@ struct neg_match {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
if (CE->getOpcode() == Instruction::Sub)
return matchIfNeg(CE->getOperand(0), CE->getOperand(1));
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
- return L.match(ConstantExpr::getNeg(CI));
return false;
}
private:
bool matchIfNeg(Value *LHS, Value *RHS) {
- return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) &&
- L.match(RHS);
+ if (ConstantInt *C = dyn_cast<ConstantInt>(LHS))
+ return C->isZero() && L.match(RHS);
+ return false;
}
};
+/// m_Neg - Match an integer negate.
template<typename LHS>
inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
@@ -572,23 +615,23 @@ struct fneg_match {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
if (CE->getOpcode() == Instruction::FSub)
return matchIfFNeg(CE->getOperand(0), CE->getOperand(1));
- if (ConstantFP *CF = dyn_cast<ConstantFP>(V))
- return L.match(ConstantExpr::getFNeg(CF));
return false;
}
private:
bool matchIfFNeg(Value *LHS, Value *RHS) {
- return LHS == ConstantFP::getZeroValueForNegation(LHS->getType()) &&
- L.match(RHS);
+ if (ConstantFP *C = dyn_cast<ConstantFP>(LHS))
+ return C->isNegativeZeroValue() && L.match(RHS);
+ return false;
}
};
+/// m_FNeg - Match a floating point negate.
template<typename LHS>
inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; }
//===----------------------------------------------------------------------===//
-// Matchers for control flow
+// Matchers for control flow.
//
template<typename Cond_t>
@@ -602,12 +645,10 @@ struct brc_match {
template<typename OpTy>
bool match(OpTy *V) {
if (BranchInst *BI = dyn_cast<BranchInst>(V))
- if (BI->isConditional()) {
- if (Cond.match(BI->getCondition())) {
- T = BI->getSuccessor(0);
- F = BI->getSuccessor(1);
- return true;
- }
+ if (BI->isConditional() && Cond.match(BI->getCondition())) {
+ T = BI->getSuccessor(0);
+ F = BI->getSuccessor(1);
+ return true;
}
return false;
}
diff --git a/include/llvm/Support/PointerLikeTypeTraits.h b/include/llvm/Support/PointerLikeTypeTraits.h
index b851404800..8370821392 100644
--- a/include/llvm/Support/PointerLikeTypeTraits.h
+++ b/include/llvm/Support/PointerLikeTypeTraits.h
@@ -15,7 +15,7 @@
#ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
#define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/include/llvm/System/Process.h b/include/llvm/Support/Process.h
index 41bcd69b6a..33799229ff 100644
--- a/include/llvm/System/Process.h
+++ b/include/llvm/Support/Process.h
@@ -1,4 +1,4 @@
-//===- llvm/System/Process.h ------------------------------------*- C++ -*-===//
+//===- llvm/Support/Process.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,7 +14,7 @@
#ifndef LLVM_SYSTEM_PROCESS_H
#define LLVM_SYSTEM_PROCESS_H
-#include "llvm/System/TimeValue.h"
+#include "llvm/Support/TimeValue.h"
namespace llvm {
namespace sys {
diff --git a/include/llvm/System/Program.h b/include/llvm/Support/Program.h
index c595082e8b..78a495ef21 100644
--- a/include/llvm/System/Program.h
+++ b/include/llvm/Support/Program.h
@@ -1,4 +1,4 @@
-//===- llvm/System/Program.h ------------------------------------*- C++ -*-===//
+//===- llvm/Support/Program.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,7 +14,7 @@
#ifndef LLVM_SYSTEM_PROGRAM_H
#define LLVM_SYSTEM_PROGRAM_H
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
namespace llvm {
namespace sys {
diff --git a/include/llvm/System/RWMutex.h b/include/llvm/Support/RWMutex.h
index 3a288180bf..0d4cb81de3 100644
--- a/include/llvm/System/RWMutex.h
+++ b/include/llvm/Support/RWMutex.h
@@ -14,7 +14,7 @@
#ifndef LLVM_SYSTEM_RWMUTEX_H
#define LLVM_SYSTEM_RWMUTEX_H
-#include "llvm/System/Threading.h"
+#include "llvm/Support/Threading.h"
#include <cassert>
namespace llvm
@@ -43,7 +43,7 @@ namespace llvm
/// Attempts to unconditionally acquire the lock in reader mode. If the
/// lock is held by a writer, this method will wait until it can acquire
- /// the lock.
+ /// the lock.
/// @returns false if any kind of error occurs, true otherwise.
/// @brief Unconditionally acquire the lock in reader mode.
bool reader_acquire();
@@ -55,7 +55,7 @@ namespace llvm
/// Attempts to unconditionally acquire the lock in reader mode. If the
/// lock is held by any readers, this method will wait until it can
- /// acquire the lock.
+ /// acquire the lock.
/// @returns false if any kind of error occurs, true otherwise.
/// @brief Unconditionally acquire the lock in writer mode.
bool writer_acquire();
@@ -79,8 +79,8 @@ namespace llvm
void operator=(const RWMutexImpl &);
/// @}
};
-
- /// SmartMutex - An R/W mutex with a compile time constant parameter that
+
+ /// SmartMutex - An R/W mutex with a compile time constant parameter that
/// indicates whether this mutex should become a no-op when we're not
/// running in multithreaded mode.
template<bool mt_only>
@@ -88,80 +88,80 @@ namespace llvm
unsigned readers, writers;
public:
explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
-
+
bool reader_acquire() {
if (!mt_only || llvm_is_multithreaded())
return RWMutexImpl::reader_acquire();
-
+
// Single-threaded debugging code. This would be racy in multithreaded
// mode, but provides not sanity checks in single threaded mode.
++readers;
return true;
}
-
+
bool reader_release() {
if (!mt_only || llvm_is_multithreaded())
return RWMutexImpl::reader_release();
-
+
// Single-threaded debugging code. This would be racy in multithreaded
// mode, but provides not sanity checks in single threaded mode.
assert(readers > 0 && "Reader lock not acquired before release!");
--readers;
return true;
}
-
+
bool writer_acquire() {
if (!mt_only || llvm_is_multithreaded())
return RWMutexImpl::writer_acquire();
-
+
// Single-threaded debugging code. This would be racy in multithreaded
// mode, but provides not sanity checks in single threaded mode.
assert(writers == 0 && "Writer lock already acquired!");
++writers;
return true;
}
-
+
bool writer_release() {
if (!mt_only || llvm_is_multithreaded())
return RWMutexImpl::writer_release();
-
+
// Single-threaded debugging code. This would be racy in multithreaded
// mode, but provides not sanity checks in single threaded mode.
assert(writers == 1 && "Writer lock not acquired before release!");
--writers;
return true;
}
-
+
private:
SmartRWMutex(const SmartRWMutex<mt_only> & original);
void operator=(const SmartRWMutex<mt_only> &);
};
typedef SmartRWMutex<false> RWMutex;
-
+
/// ScopedReader - RAII acquisition of a reader lock
template<bool mt_only>
struct SmartScopedReader {
SmartRWMutex<mt_only>& mutex;
-
+
explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
mutex.reader_acquire();
}
-
+
~SmartScopedReader() {
mutex.reader_release();
}
};
typedef SmartScopedReader<false> ScopedReader;
-
+
/// ScopedWriter - RAII acquisition of a writer lock
template<bool mt_only>
struct SmartScopedWriter {
SmartRWMutex<mt_only>& mutex;
-
+
explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
mutex.writer_acquire();
}
-
+
~SmartScopedWriter() {
mutex.writer_release();
}
diff --git a/include/llvm/System/Signals.h b/include/llvm/Support/Signals.h
index 7f1c87c3d5..9a84df68dd 100644
--- a/include/llvm/System/Signals.h
+++ b/include/llvm/Support/Signals.h
@@ -1,4 +1,4 @@
-//===- llvm/System/Signals.h - Signal Handling support ----------*- C++ -*-===//
+//===- llvm/Support/Signals.h - Signal Handling support ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,7 +15,7 @@
#ifndef LLVM_SYSTEM_SIGNALS_H
#define LLVM_SYSTEM_SIGNALS_H
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
namespace llvm {
namespace sys {
diff --git a/include/llvm/System/Solaris.h b/include/llvm/Support/Solaris.h
index 15adb7472c..57eee2cb49 100644
--- a/include/llvm/System/Solaris.h
+++ b/include/llvm/Support/Solaris.h
@@ -1,4 +1,4 @@
-/*===- llvm/System/Solaris.h ------------------------------------*- C++ -*-===*
+/*===- llvm/Support/Solaris.h ------------------------------------*- C++ -*-===*
*
* The LLVM Compiler Infrastructure
*
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index 816f894372..2a712e44bd 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -36,8 +36,7 @@ public:
/// DiagHandlerTy - Clients that want to handle their own diagnostics in a
/// custom way can register a function pointer+context as a diagnostic
/// handler. It gets called each time PrintMessage is invoked.
- typedef void (*DiagHandlerTy)(const SMDiagnostic&, void *Context,
- unsigned LocCookie);
+ typedef void (*DiagHandlerTy)(const SMDiagnostic&, void *Context);
private:
struct SrcBuffer {
/// Buffer - The memory buffer for the file.
@@ -61,7 +60,6 @@ private:
DiagHandlerTy DiagHandler;
void *DiagContext;
- unsigned DiagLocCookie;
SourceMgr(const SourceMgr&); // DO NOT IMPLEMENT
void operator=(const SourceMgr&); // DO NOT IMPLEMENT
@@ -74,12 +72,10 @@ public:
}
/// setDiagHandler - Specify a diagnostic handler to be invoked every time
- /// PrintMessage is called. Ctx and Cookie are passed into the handler when
- /// it is invoked.
- void setDiagHandler(DiagHandlerTy DH, void *Ctx = 0, unsigned Cookie = 0) {
+ /// PrintMessage is called. Ctx is passed into the handler when it is invoked.
+ void setDiagHandler(DiagHandlerTy DH, void *Ctx = 0) {
DiagHandler = DH;
DiagContext = Ctx;
- DiagLocCookie = Cookie;
}
const SrcBuffer &getBufferInfo(unsigned i) const {
@@ -160,10 +156,9 @@ public:
// Null diagnostic.
SMDiagnostic() : SM(0), LineNo(0), ColumnNo(0), ShowLine(0) {}
// Diagnostic with no location (e.g. file not found, command line arg error).
- SMDiagnostic(const std::string &filename, const std::string &Msg,
- bool showline = true)
+ SMDiagnostic(const std::string &filename, const std::string &Msg)
: SM(0), Filename(filename), LineNo(-1), ColumnNo(-1),
- Message(Msg), ShowLine(showline) {}
+ Message(Msg), ShowLine(false) {}
// Diagnostic with a location.
SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN,
@@ -175,7 +170,7 @@ public:
const SourceMgr *getSourceMgr() const { return SM; }
SMLoc getLoc() const { return Loc; }
- const std::string &getFilename() { return Filename; }
+ const std::string &getFilename() const { return Filename; }
int getLineNo() const { return LineNo; }
int getColumnNo() const { return ColumnNo; }
const std::string &getMessage() const { return Message; }
diff --git a/include/llvm/Support/StableBasicBlockNumbering.h b/include/llvm/Support/StableBasicBlockNumbering.h
deleted file mode 100644
index 5e0f87e489..0000000000
--- a/include/llvm/Support/StableBasicBlockNumbering.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===- StableBasicBlockNumbering.h - Provide BB identifiers -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class provides a *stable* numbering of basic blocks that does not depend
-// on their address in memory (which is nondeterministic). When requested, this
-// class simply provides a unique ID for each basic block in the function
-// specified and the inverse mapping.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_STABLEBASICBLOCKNUMBERING_H
-#define LLVM_SUPPORT_STABLEBASICBLOCKNUMBERING_H
-
-#include "llvm/Function.h"
-#include "llvm/ADT/UniqueVector.h"
-
-namespace llvm {
- class StableBasicBlockNumbering {
- // BBNumbering - Holds the numbering.
- UniqueVector<BasicBlock*> BBNumbering;
- public:
- StableBasicBlockNumbering(Function *F = 0) {
- if (F) compute(*F);
- }
-
- /// compute - If we have not computed a numbering for the function yet, do
- /// so.
- void compute(Function &F) {
- if (BBNumbering.empty()) {
- for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
- BBNumbering.insert(I);
- }
- }
-
- /// getNumber - Return the ID number for the specified BasicBlock.
- ///
- unsigned getNumber(BasicBlock *BB) const {
- unsigned Idx = BBNumbering.idFor(BB);
- assert(Idx && "Invalid basic block or numbering not computed!");
- return Idx-1;
- }
-
- /// getBlock - Return the BasicBlock corresponding to a particular ID.
- ///
- BasicBlock *getBlock(unsigned N) const {
- assert(N < BBNumbering.size() &&
- "Block ID out of range or numbering not computed!");
- return BBNumbering[N+1];
- }
- };
-}
-
-#endif
diff --git a/include/llvm/Support/StandardPasses.h b/include/llvm/Support/StandardPasses.h
index a608f2ceab..d774faf386 100644
--- a/include/llvm/Support/StandardPasses.h
+++ b/include/llvm/Support/StandardPasses.h
@@ -20,20 +20,35 @@
#define LLVM_SUPPORT_STANDARDPASSES_H
#include "llvm/PassManager.h"
-#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/IPO.h"
namespace llvm {
+
+ static inline void createStandardAliasAnalysisPasses(PassManagerBase *PM) {
+ // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
+ // BasicAliasAnalysis wins if they disagree. This is intended to help
+ // support "obvious" type-punning idioms.
+ PM->add(createTypeBasedAliasAnalysisPass());
+ PM->add(createBasicAliasAnalysisPass());
+ }
+
/// createStandardFunctionPasses - Add the standard list of function passes to
/// the provided pass manager.
///
/// \arg OptimizationLevel - The optimization level, corresponding to -O0,
/// -O1, etc.
static inline void createStandardFunctionPasses(PassManagerBase *PM,
- unsigned OptimizationLevel);
+ unsigned OptimizationLevel) {
+ if (OptimizationLevel > 0) {
+ createStandardAliasAnalysisPasses(PM);
+ PM->add(createCFGSimplificationPass());
+ PM->add(createScalarReplAggregatesPass());
+ PM->add(createEarlyCSEPass());
+ }
+ }
/// createStandardModulePasses - Add the standard list of module passes to the
/// provided pass manager.
@@ -54,51 +69,6 @@ namespace llvm {
bool UnrollLoops,
bool SimplifyLibCalls,
bool HaveExceptions,
- Pass *InliningPass);
-
- /// createStandardLTOPasses - Add the standard list of module passes suitable
- /// for link time optimization.
- ///
- /// Internalize - Run the internalize pass.
- /// RunInliner - Use a function inlining pass.
- /// VerifyEach - Run the verifier after each pass.
- static inline void createStandardLTOPasses(PassManagerBase *PM,
- bool Internalize,
- bool RunInliner,
- bool VerifyEach);
-
- // Implementations
-
- static inline void createStandardAliasAnalysisPasses(PassManagerBase *PM) {
- // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
- // BasicAliasAnalysis wins if they disagree. This is intended to help
- // support "obvious" type-punning idioms.
- PM->add(createTypeBasedAliasAnalysisPass());
- PM->add(createBasicAliasAnalysisPass());
- }
-
- static inline void createStandardFunctionPasses(PassManagerBase *PM,
- unsigned OptimizationLevel) {
- if (OptimizationLevel > 0) {
- createStandardAliasAnalysisPasses(PM);
- PM->add(createCFGSimplificationPass());
- if (OptimizationLevel == 1)
- PM->add(createPromoteMemoryToRegisterPass());
- else
- PM->add(createScalarReplAggregatesPass());
- PM->add(createInstructionCombiningPass());
- }
- }
-
- /// createStandardModulePasses - Add the standard module passes. This is
- /// expected to be run after the standard function passes.
- static inline void createStandardModulePasses(PassManagerBase *PM,
- unsigned OptimizationLevel,
- bool OptimizeSize,
- bool UnitAtATime,
- bool UnrollLoops,
- bool SimplifyLibCalls,
- bool HaveExceptions,
Pass *InliningPass) {
createStandardAliasAnalysisPasses(PM);
@@ -119,7 +89,7 @@ namespace llvm {
// Start of CallGraph SCC passes.
if (UnitAtATime && HaveExceptions)
- PM->add(createPruneEHPass()); // Remove dead EH info
+ PM->add(createPruneEHPass()); // Remove dead EH info
if (InliningPass)
PM->add(InliningPass);
if (UnitAtATime)
@@ -128,10 +98,11 @@ namespace llvm {
PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args
// Start of function pass.
- PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas
+ // Break up aggregate allocas, using SSAUpdater.
+ PM->add(createScalarReplAggregatesPass(-1, false));
+ PM->add(createEarlyCSEPass()); // Catch trivial redundancies
if (SimplifyLibCalls)
PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations
- PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
PM->add(createJumpThreadingPass()); // Thread jumps.
PM->add(createCorrelatedValuePropagationPass()); // Propagate conditionals
PM->add(createCFGSimplificationPass()); // Merge & remove BBs
@@ -145,6 +116,7 @@ namespace llvm {
PM->add(createLoopUnswitchPass(OptimizeSize || OptimizationLevel < 3));
PM->add(createInstructionCombiningPass());
PM->add(createIndVarSimplifyPass()); // Canonicalize indvars
+ PM->add(createLoopIdiomPass()); // Recognize idioms like memset.
PM->add(createLoopDeletionPass()); // Delete dead loops
if (UnrollLoops)
PM->add(createLoopUnrollPass()); // Unroll small loops
@@ -184,6 +156,12 @@ namespace llvm {
PM->add(createVerifierPass());
}
+ /// createStandardLTOPasses - Add the standard list of module passes suitable
+ /// for link time optimization.
+ ///
+ /// Internalize - Run the internalize pass.
+ /// RunInliner - Use a function inlining pass.
+ /// VerifyEach - Run the verifier after each pass.
static inline void createStandardLTOPasses(PassManagerBase *PM,
bool Internalize,
bool RunInliner,
diff --git a/include/llvm/Support/SwapByteOrder.h b/include/llvm/Support/SwapByteOrder.h
new file mode 100644
index 0000000000..6c0592c05a
--- /dev/null
+++ b/include/llvm/Support/SwapByteOrder.h
@@ -0,0 +1,101 @@
+//===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares generic and optimized functions to swap the byte order of
+// an integral type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_SWAP_BYTE_ORDER_H
+#define LLVM_SYSTEM_SWAP_BYTE_ORDER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cstddef>
+#include <limits>
+
+namespace llvm {
+namespace sys {
+
+/// SwapByteOrder_16 - This function returns a byte-swapped representation of
+/// the 16-bit argument.
+inline uint16_t SwapByteOrder_16(uint16_t value) {
+#if defined(_MSC_VER) && !defined(_DEBUG)
+ // The DLL version of the runtime lacks these functions (bug!?), but in a
+ // release build they're replaced with BSWAP instructions anyway.
+ return _byteswap_ushort(value);
+#else
+ uint16_t Hi = value << 8;
+ uint16_t Lo = value >> 8;
+ return Hi | Lo;
+#endif
+}
+
+/// SwapByteOrder_32 - This function returns a byte-swapped representation of
+/// the 32-bit argument.
+inline uint32_t SwapByteOrder_32(uint32_t value) {
+#if defined(__llvm__) || \
+(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
+ return __builtin_bswap32(value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_ulong(value);
+#else
+ uint32_t Byte0 = value & 0x000000FF;
+ uint32_t Byte1 = value & 0x0000FF00;
+ uint32_t Byte2 = value & 0x00FF0000;
+ uint32_t Byte3 = value & 0xFF000000;
+ return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
+#endif
+}
+
+/// SwapByteOrder_64 - This function returns a byte-swapped representation of
+/// the 64-bit argument.
+inline uint64_t SwapByteOrder_64(uint64_t value) {
+#if defined(__llvm__) || \
+(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
+ return __builtin_bswap64(value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_uint64(value);
+#else
+ uint64_t Hi = SwapByteOrder_32(uint32_t(value));
+ uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
+ return (Hi << 32) | Lo;
+#endif
+}
+
+inline unsigned char SwapByteOrder(unsigned char C) { return C; }
+inline signed char SwapByteOrder(signed char C) { return C; }
+inline char SwapByteOrder(char C) { return C; }
+
+inline unsigned short SwapByteOrder(unsigned short C) { return SwapByteOrder_16(C); }
+inline signed short SwapByteOrder( signed short C) { return SwapByteOrder_16(C); }
+
+inline unsigned int SwapByteOrder(unsigned int C) { return SwapByteOrder_32(C); }
+inline signed int SwapByteOrder( signed int C) { return SwapByteOrder_32(C); }
+
+#if __LONG_MAX__ == __INT_MAX__
+inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_32(C); }
+inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_32(C); }
+#elif __LONG_MAX__ == __LONG_LONG_MAX__
+inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_64(C); }
+inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_64(C); }
+#else
+#error "Unknown long size!"
+#endif
+
+inline unsigned long long SwapByteOrder(unsigned long long C) {
+ return SwapByteOrder_64(C);
+}
+inline signed long long SwapByteOrder(signed long long C) {
+ return SwapByteOrder_64(C);
+}
+
+} // end namespace sys
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
index d34f35fe0d..20ca5571ff 100644
--- a/include/llvm/Support/TargetFolder.h
+++ b/include/llvm/Support/TargetFolder.h
@@ -46,50 +46,32 @@ public:
// Binary Operators
//===--------------------------------------------------------------------===//
- Constant *CreateAdd(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getAdd(LHS, RHS));
- }
- Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getNSWAdd(LHS, RHS));
- }
- Constant *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getNUWAdd(LHS, RHS));
+ Constant *CreateAdd(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
}
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFAdd(LHS, RHS));
}
- Constant *CreateSub(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getSub(LHS, RHS));
- }
- Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getNSWSub(LHS, RHS));
- }
- Constant *CreateNUWSub(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getNUWSub(LHS, RHS));
+ Constant *CreateSub(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
}
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFSub(LHS, RHS));
}
- Constant *CreateMul(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getMul(LHS, RHS));
- }
- Constant *CreateNSWMul(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getNSWMul(LHS, RHS));
- }
- Constant *CreateNUWMul(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getNUWMul(LHS, RHS));
+ Constant *CreateMul(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
}
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFMul(LHS, RHS));
}
- Constant *CreateUDiv(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getUDiv(LHS, RHS));
- }
- Constant *CreateSDiv(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getSDiv(LHS, RHS));
+ Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
}
- Constant *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getExactSDiv(LHS, RHS));
+ Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
}
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFDiv(LHS, RHS));
@@ -103,14 +85,15 @@ public:
Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFRem(LHS, RHS));
}
- Constant *CreateShl(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getShl(LHS, RHS));
+ Constant *CreateShl(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
}
- Constant *CreateLShr(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getLShr(LHS, RHS));
+ Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
}
- Constant *CreateAShr(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getAShr(LHS, RHS));
+ Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
}
Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getAnd(LHS, RHS));
@@ -131,14 +114,9 @@ public:
// Unary Operators
//===--------------------------------------------------------------------===//
- Constant *CreateNeg(Constant *C) const {
- return Fold(ConstantExpr::getNeg(C));
- }
- Constant *CreateNSWNeg(Constant *C) const {
- return Fold(ConstantExpr::getNSWNeg(C));
- }
- Constant *CreateNUWNeg(Constant *C) const {
- return Fold(ConstantExpr::getNUWNeg(C));
+ Constant *CreateNeg(Constant *C,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
}
Constant *CreateFNeg(Constant *C) const {
return Fold(ConstantExpr::getFNeg(C));
diff --git a/include/llvm/System/ThreadLocal.h b/include/llvm/Support/ThreadLocal.h
index e6edd79d6f..15350a7aff 100644
--- a/include/llvm/System/ThreadLocal.h
+++ b/include/llvm/Support/ThreadLocal.h
@@ -1,4 +1,4 @@
-//===- llvm/System/ThreadLocal.h - Thread Local Data ------------*- C++ -*-===//
+//===- llvm/Support/ThreadLocal.h - Thread Local Data ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,7 +14,7 @@
#ifndef LLVM_SYSTEM_THREAD_LOCAL_H
#define LLVM_SYSTEM_THREAD_LOCAL_H
-#include "llvm/System/Threading.h"
+#include "llvm/Support/Threading.h"
#include <cassert>
namespace llvm {
@@ -30,21 +30,21 @@ namespace llvm {
const void* getInstance();
void removeInstance();
};
-
+
/// ThreadLocal - A class used to abstract thread-local storage. It holds,
/// for each thread, a pointer a single object of type T.
template<class T>
class ThreadLocal : public ThreadLocalImpl {
public:
ThreadLocal() : ThreadLocalImpl() { }
-
+
/// get - Fetches a pointer to the object associated with the current
/// thread. If no object has yet been associated, it returns NULL;
T* get() { return static_cast<T*>(getInstance()); }
-
+
// set - Associates a pointer to an object with the current thread.
void set(T* d) { setInstance(d); }
-
+
// erase - Removes the pointer associated with the current thread.
void erase() { removeInstance(); }
};
diff --git a/include/llvm/System/Threading.h b/include/llvm/Support/Threading.h
index 1d0ed1e492..c0e842c2fe 100644
--- a/include/llvm/System/Threading.h
+++ b/include/llvm/Support/Threading.h
@@ -1,4 +1,4 @@
-//===-- llvm/System/Threading.h - Control multithreading mode --*- C++ -*-===//
+//===-- llvm/Support/Threading.h - Control multithreading mode --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,25 +18,25 @@ namespace llvm {
/// llvm_start_multithreaded - Allocate and initialize structures needed to
/// make LLVM safe for multithreading. The return value indicates whether
/// multithreaded initialization succeeded. LLVM will still be operational
- /// on "failed" return, and will still be safe for hosting threading
+ /// on "failed" return, and will still be safe for hosting threading
/// applications in the JIT, but will not be safe for concurrent calls to the
/// LLVM APIs.
/// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
bool llvm_start_multithreaded();
-
+
/// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM
/// safe for multithreading.
/// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
void llvm_stop_multithreaded();
-
+
/// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe
/// mode or not.
bool llvm_is_multithreaded();
-
+
/// acquire_global_lock - Acquire the global lock. This is a no-op if called
/// before llvm_start_multithreaded().
void llvm_acquire_global_lock();
-
+
/// release_global_lock - Release the global lock. This is a no-op if called
/// before llvm_start_multithreaded().
void llvm_release_global_lock();
diff --git a/include/llvm/System/TimeValue.h b/include/llvm/Support/TimeValue.h
index b82647f74e..e1227118c2 100644
--- a/include/llvm/System/TimeValue.h
+++ b/include/llvm/Support/TimeValue.h
@@ -11,7 +11,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
#ifndef LLVM_SYSTEM_TIMEVALUE_H
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
index b1792b1671..faba94edf2 100644
--- a/include/llvm/Support/Timer.h
+++ b/include/llvm/Support/Timer.h
@@ -15,7 +15,7 @@
#ifndef LLVM_SUPPORT_TIMER_H
#define LLVM_SUPPORT_TIMER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <string>
diff --git a/include/llvm/System/Valgrind.h b/include/llvm/Support/Valgrind.h
index 5ec79c3c55..7662eaaff5 100644
--- a/include/llvm/System/Valgrind.h
+++ b/include/llvm/Support/Valgrind.h
@@ -1,4 +1,4 @@
-//===- llvm/System/Valgrind.h - Communication with Valgrind -----*- C++ -*-===//
+//===- llvm/Support/Valgrind.h - Communication with Valgrind -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 6bc8935b14..6bfae5e298 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -15,7 +15,7 @@
#define LLVM_SUPPORT_RAW_OSTREAM_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class format_object_base;
@@ -165,7 +165,7 @@ public:
}
raw_ostream &operator<<(const char *Str) {
- // Inline fast path, particulary for constant strings where a sufficiently
+ // Inline fast path, particularly for constant strings where a sufficiently
// smart compiler will simplify strlen.
return this->operator<<(StringRef(Str));
@@ -196,7 +196,7 @@ public:
/// write_escaped - Output \arg Str, turning '\\', '\t', '\n', '"', and
/// anything that doesn't satisfy std::isprint into an escape sequence.
- raw_ostream &write_escaped(StringRef Str);
+ raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
raw_ostream &write(unsigned char C);
raw_ostream &write(const char *Ptr, size_t Size);
@@ -301,6 +301,10 @@ class raw_fd_ostream : public raw_ostream {
///
bool Error;
+ /// Controls whether the stream should attempt to use atomic writes, when
+ /// possible.
+ bool UseAtomicWrites;
+
uint64_t pos;
/// write_impl - See raw_ostream::write_impl.
@@ -358,9 +362,19 @@ public:
void close();
/// seek - Flushes the stream and repositions the underlying file descriptor
- /// positition to the offset specified from the beginning of the file.
+ /// position to the offset specified from the beginning of the file.
uint64_t seek(uint64_t off);
+ /// SetUseAtomicWrite - Set the stream to attempt to use atomic writes for
+ /// individual output routines where possible.
+ ///
+ /// Note that because raw_ostream's are typically buffered, this flag is only
+ /// sensible when used on unbuffered streams which will flush their output
+ /// immediately.
+ void SetUseAtomicWrites(bool Value) {
+ UseAtomicWrites = Value;
+ }
+
virtual raw_ostream &changeColor(enum Colors colors, bool bold=false,
bool bg=false);
virtual raw_ostream &resetColor();
diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h
new file mode 100644
index 0000000000..e5306ecfb3
--- /dev/null
+++ b/include/llvm/Support/system_error.h
@@ -0,0 +1,910 @@
+//===---------------------------- system_error ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This was lifted from libc++ and modified for C++03. This is called
+// system_error even though it does not define that class because that's what
+// it's called in C++0x. We don't define system_error because it is only used
+// for exception handling, which we don't use in LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_SYSTEM_ERROR_H
+#define LLVM_SYSTEM_SYSTEM_ERROR_H
+
+/*
+ system_error synopsis
+
+namespace std
+{
+
+class error_category
+{
+public:
+ virtual ~error_category();
+
+ error_category(const error_category&) = delete;
+ error_category& operator=(const error_category&) = delete;
+
+ virtual const char* name() const = 0;
+ virtual error_condition default_error_condition(int ev) const;
+ virtual bool equivalent(int code, const error_condition& condition) const;
+ virtual bool equivalent(const error_code& code, int condition) const;
+ virtual std::string message(int ev) const = 0;
+
+ bool operator==(const error_category& rhs) const;
+ bool operator!=(const error_category& rhs) const;
+ bool operator<(const error_category& rhs) const;
+};
+
+const error_category& generic_category();
+const error_category& system_category();
+
+template <class T> struct is_error_code_enum
+ : public false_type {};
+
+template <class T> struct is_error_condition_enum
+ : public false_type {};
+
+class error_code
+{
+public:
+ // constructors:
+ error_code();
+ error_code(int val, const error_category& cat);
+ template <class ErrorCodeEnum>
+ error_code(ErrorCodeEnum e);
+
+ // modifiers:
+ void assign(int val, const error_category& cat);
+ template <class ErrorCodeEnum>
+ error_code& operator=(ErrorCodeEnum e);
+ void clear();
+
+ // observers:
+ int value() const;
+ const error_category& category() const;
+ error_condition default_error_condition() const;
+ std::string message() const;
+ explicit operator bool() const;
+};
+
+// non-member functions:
+bool operator<(const error_code& lhs, const error_code& rhs);
+template <class charT, class traits>
+ basic_ostream<charT,traits>&
+ operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
+
+class error_condition
+{
+public:
+ // constructors:
+ error_condition();
+ error_condition(int val, const error_category& cat);
+ template <class ErrorConditionEnum>
+ error_condition(ErrorConditionEnum e);
+
+ // modifiers:
+ void assign(int val, const error_category& cat);
+ template <class ErrorConditionEnum>
+ error_condition& operator=(ErrorConditionEnum e);
+ void clear();
+
+ // observers:
+ int value() const;
+ const error_category& category() const;
+ std::string message() const;
+ explicit operator bool() const;
+};
+
+bool operator<(const error_condition& lhs, const error_condition& rhs);
+
+class system_error
+ : public runtime_error
+{
+public:
+ system_error(error_code ec, const std::string& what_arg);
+ system_error(error_code ec, const char* what_arg);
+ system_error(error_code ec);
+ system_error(int ev, const error_category& ecat, const std::string& what_arg);
+ system_error(int ev, const error_category& ecat, const char* what_arg);
+ system_error(int ev, const error_category& ecat);
+
+ const error_code& code() const throw();
+ const char* what() const throw();
+};
+
+enum class errc
+{
+ address_family_not_supported, // EAFNOSUPPORT
+ address_in_use, // EADDRINUSE
+ address_not_available, // EADDRNOTAVAIL
+ already_connected, // EISCONN
+ argument_list_too_long, // E2BIG
+ argument_out_of_domain, // EDOM
+ bad_address, // EFAULT
+ bad_file_descriptor, // EBADF
+ bad_message, // EBADMSG
+ broken_pipe, // EPIPE
+ connection_aborted, // ECONNABORTED
+ connection_already_in_progress, // EALREADY
+ connection_refused, // ECONNREFUSED
+ connection_reset, // ECONNRESET
+ cross_device_link, // EXDEV
+ destination_address_required, // EDESTADDRREQ
+ device_or_resource_busy, // EBUSY
+ directory_not_empty, // ENOTEMPTY
+ executable_format_error, // ENOEXEC
+ file_exists, // EEXIST
+ file_too_large, // EFBIG
+ filename_too_long, // ENAMETOOLONG
+ function_not_supported, // ENOSYS
+ host_unreachable, // EHOSTUNREACH
+ identifier_removed, // EIDRM
+ illegal_byte_sequence, // EILSEQ
+ inappropriate_io_control_operation, // ENOTTY
+ interrupted, // EINTR
+ invalid_argument, // EINVAL
+ invalid_seek, // ESPIPE
+ io_error, // EIO
+ is_a_directory, // EISDIR
+ message_size, // EMSGSIZE
+ network_down, // ENETDOWN
+ network_reset, // ENETRESET
+ network_unreachable, // ENETUNREACH
+ no_buffer_space, // ENOBUFS
+ no_child_process, // ECHILD
+ no_link, // ENOLINK
+ no_lock_available, // ENOLCK
+ no_message_available, // ENODATA
+ no_message, // ENOMSG
+ no_protocol_option, // ENOPROTOOPT
+ no_space_on_device, // ENOSPC
+ no_stream_resources, // ENOSR
+ no_such_device_or_address, // ENXIO
+ no_such_device, // ENODEV
+ no_such_file_or_directory, // ENOENT
+ no_such_process, // ESRCH
+ not_a_directory, // ENOTDIR
+ not_a_socket, // ENOTSOCK
+ not_a_stream, // ENOSTR
+ not_connected, // ENOTCONN
+ not_enough_memory, // ENOMEM
+ not_supported, // ENOTSUP
+ operation_canceled, // ECANCELED
+ operation_in_progress, // EINPROGRESS
+ operation_not_permitted, // EPERM
+ operation_not_supported, // EOPNOTSUPP
+ operation_would_block, // EWOULDBLOCK
+ owner_dead, // EOWNERDEAD
+ permission_denied, // EACCES
+ protocol_error, // EPROTO
+ protocol_not_supported, // EPROTONOSUPPORT
+ read_only_file_system, // EROFS
+ resource_deadlock_would_occur, // EDEADLK
+ resource_unavailable_try_again, // EAGAIN
+ result_out_of_range, // ERANGE
+ state_not_recoverable, // ENOTRECOVERABLE
+ stream_timeout, // ETIME
+ text_file_busy, // ETXTBSY
+ timed_out, // ETIMEDOUT
+ too_many_files_open_in_system, // ENFILE
+ too_many_files_open, // EMFILE
+ too_many_links, // EMLINK
+ too_many_symbolic_link_levels, // ELOOP
+ value_too_large, // EOVERFLOW
+ wrong_protocol_type // EPROTOTYPE
+};
+
+template <> struct is_error_condition_enum<errc> : true_type { }
+
+error_code make_error_code(errc e);
+error_condition make_error_condition(errc e);
+
+// Comparison operators:
+bool operator==(const error_code& lhs, const error_code& rhs);
+bool operator==(const error_code& lhs, const error_condition& rhs);
+bool operator==(const error_condition& lhs, const error_code& rhs);
+bool operator==(const error_condition& lhs, const error_condition& rhs);
+bool operator!=(const error_code& lhs, const error_code& rhs);
+bool operator!=(const error_code& lhs, const error_condition& rhs);
+bool operator!=(const error_condition& lhs, const error_code& rhs);
+bool operator!=(const error_condition& lhs, const error_condition& rhs);
+
+template <> struct hash<std::error_code>;
+
+} // std
+
+*/
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/type_traits.h"
+#include <cerrno>
+#include <string>
+
+// This must be here instead of a .inc file because it is used in the definition
+// of the enum values below.
+#ifdef LLVM_ON_WIN32
+
+ // The following numbers were taken from VS2010.
+# ifndef EAFNOSUPPORT
+# define EAFNOSUPPORT 102
+# endif
+# ifndef EADDRINUSE
+# define EADDRINUSE 100
+# endif
+# ifndef EADDRNOTAVAIL
+# define EADDRNOTAVAIL 101
+# endif
+# ifndef EISCONN
+# define EISCONN 113
+# endif
+# ifndef E2BIG
+# define E2BIG 7
+# endif
+# ifndef EDOM
+# define EDOM 33
+# endif
+# ifndef EFAULT
+# define EFAULT 14
+# endif
+# ifndef EBADF
+# define EBADF 9
+# endif
+# ifndef EBADMSG
+# define EBADMSG 104
+# endif
+# ifndef EPIPE
+# define EPIPE 32
+# endif
+# ifndef ECONNABORTED
+# define ECONNABORTED 106
+# endif
+# ifndef EALREADY
+# define EALREADY 103
+# endif
+# ifndef ECONNREFUSED
+# define ECONNREFUSED 107
+# endif
+# ifndef ECONNRESET
+# define ECONNRESET 108
+# endif
+# ifndef EXDEV
+# define EXDEV 18
+# endif
+# ifndef EDESTADDRREQ
+# define EDESTADDRREQ 109
+# endif
+# ifndef EBUSY
+# define EBUSY 16
+# endif
+# ifndef ENOTEMPTY
+# define ENOTEMPTY 41
+# endif
+# ifndef ENOEXEC
+# define ENOEXEC 8
+# endif
+# ifndef EEXIST
+# define EEXIST 17
+# endif
+# ifndef EFBIG
+# define EFBIG 27
+# endif
+# ifndef ENAMETOOLONG
+# define ENAMETOOLONG 38
+# endif
+# ifndef ENOSYS
+# define ENOSYS 40
+# endif
+# ifndef EHOSTUNREACH
+# define EHOSTUNREACH 110
+# endif
+# ifndef EIDRM
+# define EIDRM 111
+# endif
+# ifndef EILSEQ
+# define EILSEQ 42
+# endif
+# ifndef ENOTTY
+# define ENOTTY 25
+# endif
+# ifndef EINTR
+# define EINTR 4
+# endif
+# ifndef EINVAL
+# define EINVAL 22
+# endif
+# ifndef ESPIPE
+# define ESPIPE 29
+# endif
+# ifndef EIO
+# define EIO 5
+# endif
+# ifndef EISDIR
+# define EISDIR 21
+# endif
+# ifndef EMSGSIZE
+# define EMSGSIZE 115
+# endif
+# ifndef ENETDOWN
+# define ENETDOWN 116
+# endif
+# ifndef ENETRESET
+# define ENETRESET 117
+# endif
+# ifndef ENETUNREACH
+# define ENETUNREACH 118
+# endif
+# ifndef ENOBUFS
+# define ENOBUFS 119
+# endif
+# ifndef ECHILD
+# define ECHILD 10
+# endif
+# ifndef ENOLINK
+# define ENOLINK 121
+# endif
+# ifndef ENOLCK
+# define ENOLCK 39
+# endif
+# ifndef ENODATA
+# define ENODATA 120
+# endif
+# ifndef ENOMSG
+# define ENOMSG 122
+# endif
+# ifndef ENOPROTOOPT
+# define ENOPROTOOPT 123
+# endif
+# ifndef ENOSPC
+# define ENOSPC 28
+# endif
+# ifndef ENOSR
+# define ENOSR 124
+# endif
+# ifndef ENXIO
+# define ENXIO 6
+# endif
+# ifndef ENODEV
+# define ENODEV 19
+# endif
+# ifndef ENOENT
+# define ENOENT 2
+# endif
+# ifndef ESRCH
+# define ESRCH 3
+# endif
+# ifndef ENOTDIR
+# define ENOTDIR 20
+# endif
+# ifndef ENOTSOCK
+# define ENOTSOCK 128
+# endif
+# ifndef ENOSTR
+# define ENOSTR 125
+# endif
+# ifndef ENOTCONN
+# define ENOTCONN 126
+# endif
+# ifndef ENOMEM
+# define ENOMEM 12
+# endif
+# ifndef ENOTSUP
+# define ENOTSUP 129
+# endif
+# ifndef ECANCELED
+# define ECANCELED 105
+# endif
+# ifndef EINPROGRESS
+# define EINPROGRESS 112
+# endif
+# ifndef EPERM
+# define EPERM 1
+# endif
+# ifndef EOPNOTSUPP
+# define EOPNOTSUPP 130
+# endif
+# ifndef EWOULDBLOCK
+# define EWOULDBLOCK 140
+# endif
+# ifndef EOWNERDEAD
+# define EOWNERDEAD 133
+# endif
+# ifndef EACCES
+# define EACCES 13
+# endif
+# ifndef EPROTO
+# define EPROTO 134
+# endif
+# ifndef EPROTONOSUPPORT
+# define EPROTONOSUPPORT 135
+# endif
+# ifndef EROFS
+# define EROFS 30
+# endif
+# ifndef EDEADLK
+# define EDEADLK 36
+# endif
+# ifndef EAGAIN
+# define EAGAIN 11
+# endif
+# ifndef ERANGE
+# define ERANGE 34
+# endif
+# ifndef ENOTRECOVERABLE
+# define ENOTRECOVERABLE 127
+# endif
+# ifndef ETIME
+# define ETIME 137
+# endif
+# ifndef ETXTBSY
+# define ETXTBSY 139
+# endif
+# ifndef ETIMEDOUT
+# define ETIMEDOUT 138
+# endif
+# ifndef ENFILE
+# define ENFILE 23
+# endif
+# ifndef EMFILE
+# define EMFILE 24
+# endif
+# ifndef EMLINK
+# define EMLINK 31
+# endif
+# ifndef ELOOP
+# define ELOOP 114
+# endif
+# ifndef EOVERFLOW
+# define EOVERFLOW 132
+# endif
+# ifndef EPROTOTYPE
+# define EPROTOTYPE 136
+# endif
+#endif
+
+namespace llvm {
+
+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;
+
+// is_error_code_enum
+
+template <class Tp> struct is_error_code_enum : public false_type {};
+
+// is_error_condition_enum
+
+template <class Tp> struct is_error_condition_enum : public false_type {};
+
+// Some error codes are not present on all platforms, so we provide equivalents
+// for them:
+
+//enum class errc
+struct errc {
+enum _ {
+ success = 0,
+ address_family_not_supported = EAFNOSUPPORT,
+ address_in_use = EADDRINUSE,
+ address_not_available = EADDRNOTAVAIL,
+ already_connected = EISCONN,
+ argument_list_too_long = E2BIG,
+ argument_out_of_domain = EDOM,
+ bad_address = EFAULT,
+ bad_file_descriptor = EBADF,
+#ifdef EBADMSG
+ bad_message = EBADMSG,
+#else
+ bad_message = EINVAL,
+#endif
+ broken_pipe = EPIPE,
+ connection_aborted = ECONNABORTED,
+ connection_already_in_progress = EALREADY,
+ connection_refused = ECONNREFUSED,
+ connection_reset = ECONNRESET,
+ cross_device_link = EXDEV,
+ destination_address_required = EDESTADDRREQ,
+ device_or_resource_busy = EBUSY,
+ directory_not_empty = ENOTEMPTY,
+ executable_format_error = ENOEXEC,
+ file_exists = EEXIST,
+ file_too_large = EFBIG,
+ filename_too_long = ENAMETOOLONG,
+ function_not_supported = ENOSYS,
+ host_unreachable = EHOSTUNREACH,
+ identifier_removed = EIDRM,
+ illegal_byte_sequence = EILSEQ,
+ inappropriate_io_control_operation = ENOTTY,
+ interrupted = EINTR,
+ invalid_argument = EINVAL,
+ invalid_seek = ESPIPE,
+ io_error = EIO,
+ is_a_directory = EISDIR,
+ message_size = EMSGSIZE,
+ network_down = ENETDOWN,
+ network_reset = ENETRESET,
+ network_unreachable = ENETUNREACH,
+ no_buffer_space = ENOBUFS,
+ no_child_process = ECHILD,
+#ifdef ENOLINK
+ no_link = ENOLINK,
+#else
+ no_link = EINVAL,
+#endif
+ no_lock_available = ENOLCK,
+#ifdef ENODATA
+ no_message_available = ENODATA,
+#else
+ no_message_available = ENOMSG,
+#endif
+ no_message = ENOMSG,
+ no_protocol_option = ENOPROTOOPT,
+ no_space_on_device = ENOSPC,
+#ifdef ENOSR
+ no_stream_resources = ENOSR,
+#else
+ no_stream_resources = ENOMEM,
+#endif
+ no_such_device_or_address = ENXIO,
+ no_such_device = ENODEV,
+ no_such_file_or_directory = ENOENT,
+ no_such_process = ESRCH,
+ not_a_directory = ENOTDIR,
+ not_a_socket = ENOTSOCK,
+#ifdef ENOSTR
+ not_a_stream = ENOSTR,
+#else
+ not_a_stream = EINVAL,
+#endif
+ not_connected = ENOTCONN,
+ not_enough_memory = ENOMEM,
+ not_supported = ENOTSUP,
+#ifdef ECANCELED
+ operation_canceled = ECANCELED,
+#else
+ operation_canceled = EINVAL,
+#endif
+ operation_in_progress = EINPROGRESS,
+ operation_not_permitted = EPERM,
+ operation_not_supported = EOPNOTSUPP,
+ operation_would_block = EWOULDBLOCK,
+#ifdef EOWNERDEAD
+ owner_dead = EOWNERDEAD,
+#else
+ owner_dead = EINVAL,
+#endif
+ permission_denied = EACCES,
+#ifdef EPROTO
+ protocol_error = EPROTO,
+#else
+ protocol_error = EINVAL,
+#endif
+ protocol_not_supported = EPROTONOSUPPORT,
+ read_only_file_system = EROFS,
+ resource_deadlock_would_occur = EDEADLK,
+ resource_unavailable_try_again = EAGAIN,
+ result_out_of_range = ERANGE,
+#ifdef ENOTRECOVERABLE
+ state_not_recoverable = ENOTRECOVERABLE,
+#else
+ state_not_recoverable = EINVAL,
+#endif
+#ifdef ETIME
+ stream_timeout = ETIME,
+#else
+ stream_timeout = ETIMEDOUT,
+#endif
+ text_file_busy = ETXTBSY,
+ timed_out = ETIMEDOUT,
+ too_many_files_open_in_system = ENFILE,
+ too_many_files_open = EMFILE,
+ too_many_links = EMLINK,
+ too_many_symbolic_link_levels = ELOOP,
+ value_too_large = EOVERFLOW,
+ wrong_protocol_type = EPROTOTYPE
+};
+
+ _ v_;
+
+ errc(_ v) : v_(v) {}
+ operator int() const {return v_;}
+};
+
+template <> struct is_error_condition_enum<errc> : true_type { };
+
+template <> struct is_error_condition_enum<errc::_> : true_type { };
+
+class error_condition;
+class error_code;
+
+// class error_category
+
+class _do_message;
+
+class error_category
+{
+public:
+ virtual ~error_category();
+
+private:
+ error_category();
+ error_category(const error_category&);// = delete;
+ error_category& operator=(const error_category&);// = delete;
+
+public:
+ virtual const char* name() const = 0;
+ virtual error_condition default_error_condition(int _ev) const;
+ virtual bool equivalent(int _code, const error_condition& _condition) const;
+ virtual bool equivalent(const error_code& _code, int _condition) const;
+ virtual std::string message(int _ev) const = 0;
+
+ bool operator==(const error_category& _rhs) const {return this == &_rhs;}
+
+ bool operator!=(const error_category& _rhs) const {return !(*this == _rhs);}
+
+ bool operator< (const error_category& _rhs) const {return this < &_rhs;}
+
+ friend class _do_message;
+};
+
+class _do_message : public error_category
+{
+public:
+ virtual std::string message(int ev) const;
+};
+
+const error_category& generic_category();
+const error_category& system_category();
+
+/// Get the error_category used for errno values from POSIX functions. This is
+/// the same as the system_category on POISIX systems, but is the same as the
+/// generic_category on Windows.
+const error_category& posix_category();
+
+class error_condition
+{
+ int _val_;
+ const error_category* _cat_;
+public:
+ error_condition() : _val_(0), _cat_(&generic_category()) {}
+
+ error_condition(int _val, const error_category& _cat)
+ : _val_(_val), _cat_(&_cat) {}
+
+ template <class E>
+ error_condition(E _e, typename enable_if_c<
+ is_error_condition_enum<E>::value
+ >::type* = 0)
+ {*this = make_error_condition(_e);}
+
+ void assign(int _val, const error_category& _cat) {
+ _val_ = _val;
+ _cat_ = &_cat;
+ }
+
+ template <class E>
+ typename enable_if_c
+ <
+ is_error_condition_enum<E>::value,
+ error_condition&
+ >::type
+ operator=(E _e)
+ {*this = make_error_condition(_e); return *this;}
+
+ void clear() {
+ _val_ = 0;
+ _cat_ = &generic_category();
+ }
+
+ int value() const {return _val_;}
+
+ const error_category& category() const {return *_cat_;}
+ std::string message() const;
+
+ typedef void (*unspecified_bool_type)();
+ static void unspecified_bool_true() {}
+
+ operator unspecified_bool_type() const { // true if error
+ return _val_ == 0 ? 0 : unspecified_bool_true;
+ }
+};
+
+inline error_condition make_error_condition(errc _e) {
+ return error_condition(static_cast<int>(_e), generic_category());
+}
+
+inline bool operator<(const error_condition& _x, const error_condition& _y) {
+ return _x.category() < _y.category()
+ || (_x.category() == _y.category() && _x.value() < _y.value());
+}
+
+// error_code
+
+class error_code {
+ int _val_;
+ const error_category* _cat_;
+public:
+ error_code() : _val_(0), _cat_(&system_category()) {}
+
+ error_code(int _val, const error_category& _cat)
+ : _val_(_val), _cat_(&_cat) {}
+
+ template <class E>
+ error_code(E _e, typename enable_if_c<
+ is_error_code_enum<E>::value
+ >::type* = 0) {
+ *this = make_error_code(_e);
+ }
+
+ void assign(int _val, const error_category& _cat) {
+ _val_ = _val;
+ _cat_ = &_cat;
+ }
+
+ template <class E>
+ typename enable_if_c
+ <
+ is_error_code_enum<E>::value,
+ error_code&
+ >::type
+ operator=(E _e)
+ {*this = make_error_code(_e); return *this;}
+
+ void clear() {
+ _val_ = 0;
+ _cat_ = &system_category();
+ }
+
+ int value() const {return _val_;}
+
+ const error_category& category() const {return *_cat_;}
+
+ error_condition default_error_condition() const
+ {return _cat_->default_error_condition(_val_);}
+
+ std::string message() const;
+
+ typedef void (*unspecified_bool_type)();
+ static void unspecified_bool_true() {}
+
+ operator unspecified_bool_type() const { // true if error
+ return _val_ == 0 ? 0 : unspecified_bool_true;
+ }
+};
+
+inline error_code make_error_code(errc _e) {
+ return error_code(static_cast<int>(_e), generic_category());
+}
+
+inline bool operator<(const error_code& _x, const error_code& _y) {
+ return _x.category() < _y.category()
+ || (_x.category() == _y.category() && _x.value() < _y.value());
+}
+
+inline bool operator==(const error_code& _x, const error_code& _y) {
+ return _x.category() == _y.category() && _x.value() == _y.value();
+}
+
+inline bool operator==(const error_code& _x, const error_condition& _y) {
+ return _x.category().equivalent(_x.value(), _y)
+ || _y.category().equivalent(_x, _y.value());
+}
+
+inline bool operator==(const error_condition& _x, const error_code& _y) {
+ return _y == _x;
+}
+
+inline bool operator==(const error_condition& _x, const error_condition& _y) {
+ return _x.category() == _y.category() && _x.value() == _y.value();
+}
+
+inline bool operator!=(const error_code& _x, const error_code& _y) {
+ return !(_x == _y);
+}
+
+inline bool operator!=(const error_code& _x, const error_condition& _y) {
+ return !(_x == _y);
+}
+
+inline bool operator!=(const error_condition& _x, const error_code& _y) {
+ return !(_x == _y);
+}
+
+inline bool operator!=(const error_condition& _x, const error_condition& _y) {
+ return !(_x == _y);
+}
+
+// Windows errors.
+
+// To construct an error_code after an API error:
+//
+// error_code( ::GetLastError(), system_category() )
+struct windows_error {
+enum _ {
+ success = 0,
+ // These names and values are based on Windows WinError.h
+ // This is not a complete list. Add to this list if you need to explicitly
+ // check for it.
+ invalid_function = 1, // ERROR_INVALID_FUNCTION,
+ file_not_found = 2, // ERROR_FILE_NOT_FOUND,
+ path_not_found = 3, // ERROR_PATH_NOT_FOUND,
+ too_many_open_files = 4, // ERROR_TOO_MANY_OPEN_FILES,
+ access_denied = 5, // ERROR_ACCESS_DENIED,
+ invalid_handle = 6, // ERROR_INVALID_HANDLE,
+ arena_trashed = 7, // ERROR_ARENA_TRASHED,
+ not_enough_memory = 8, // ERROR_NOT_ENOUGH_MEMORY,
+ invalid_block = 9, // ERROR_INVALID_BLOCK,
+ bad_environment = 10, // ERROR_BAD_ENVIRONMENT,
+ bad_format = 11, // ERROR_BAD_FORMAT,
+ invalid_access = 12, // ERROR_INVALID_ACCESS,
+ outofmemory = 14, // ERROR_OUTOFMEMORY,
+ invalid_drive = 15, // ERROR_INVALID_DRIVE,
+ current_directory = 16, // ERROR_CURRENT_DIRECTORY,
+ not_same_device = 17, // ERROR_NOT_SAME_DEVICE,
+ no_more_files = 18, // ERROR_NO_MORE_FILES,
+ write_protect = 19, // ERROR_WRITE_PROTECT,
+ bad_unit = 20, // ERROR_BAD_UNIT,
+ not_ready = 21, // ERROR_NOT_READY,
+ bad_command = 22, // ERROR_BAD_COMMAND,
+ crc = 23, // ERROR_CRC,
+ bad_length = 24, // ERROR_BAD_LENGTH,
+ seek = 25, // ERROR_SEEK,
+ not_dos_disk = 26, // ERROR_NOT_DOS_DISK,
+ sector_not_found = 27, // ERROR_SECTOR_NOT_FOUND,
+ out_of_paper = 28, // ERROR_OUT_OF_PAPER,
+ write_fault = 29, // ERROR_WRITE_FAULT,
+ read_fault = 30, // ERROR_READ_FAULT,
+ gen_failure = 31, // ERROR_GEN_FAILURE,
+ sharing_violation = 32, // ERROR_SHARING_VIOLATION,
+ lock_violation = 33, // ERROR_LOCK_VIOLATION,
+ wrong_disk = 34, // ERROR_WRONG_DISK,
+ sharing_buffer_exceeded = 36, // ERROR_SHARING_BUFFER_EXCEEDED,
+ handle_eof = 38, // ERROR_HANDLE_EOF,
+ handle_disk_full = 39, // ERROR_HANDLE_DISK_FULL,
+ rem_not_list = 51, // ERROR_REM_NOT_LIST,
+ dup_name = 52, // ERROR_DUP_NAME,
+ bad_net_path = 53, // ERROR_BAD_NETPATH,
+ network_busy = 54, // ERROR_NETWORK_BUSY,
+ file_exists = 80, // ERROR_FILE_EXISTS,
+ cannot_make = 82, // ERROR_CANNOT_MAKE,
+ broken_pipe = 109, // ERROR_BROKEN_PIPE,
+ open_failed = 110, // ERROR_OPEN_FAILED,
+ buffer_overflow = 111, // ERROR_BUFFER_OVERFLOW,
+ disk_full = 112, // ERROR_DISK_FULL,
+ insufficient_buffer = 122, // ERROR_INSUFFICIENT_BUFFER,
+ lock_failed = 167, // ERROR_LOCK_FAILED,
+ busy = 170, // ERROR_BUSY,
+ cancel_violation = 173, // ERROR_CANCEL_VIOLATION,
+ already_exists = 183 // ERROR_ALREADY_EXISTS
+};
+ _ v_;
+
+ windows_error(_ v) : v_(v) {}
+ explicit windows_error(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+};
+
+
+template <> struct is_error_code_enum<windows_error> : true_type { };
+
+template <> struct is_error_code_enum<windows_error::_> : true_type { };
+
+inline error_code make_error_code(windows_error e) {
+ return error_code(static_cast<int>(e), system_category());
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/System/Alarm.h b/include/llvm/System/Alarm.h
deleted file mode 100644
index 7c284167c2..0000000000
--- a/include/llvm/System/Alarm.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===- llvm/System/Alarm.h - Alarm Generation support ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides an operating system independent interface to alarm(2)
-// type functionality. The Alarm class allows a one-shot alarm to be set up
-// at some number of seconds in the future. When the alarm triggers, a method
-// is called to process the event
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_ALARM_H
-#define LLVM_SYSTEM_ALARM_H
-
-namespace llvm {
-namespace sys {
-
- /// This function registers an alarm to trigger some number of \p seconds in
- /// the future. When that time arrives, the AlarmStatus function will begin
- /// to return 1 instead of 0. The user must poll the status of the alarm by
- /// making occasional calls to AlarmStatus. If the user sends an interrupt
- /// signal, AlarmStatus will begin returning -1, even if the alarm event
- /// occurred.
- /// @returns nothing
- void SetupAlarm(
- unsigned seconds ///< Number of seconds in future when alarm arrives
- );
-
- /// This function terminates the alarm previously set up
- /// @returns nothing
- void TerminateAlarm();
-
- /// This function acquires the status of the alarm.
- /// @returns -1=cancelled, 0=untriggered, 1=triggered
- int AlarmStatus();
-
- /// Sleep for n seconds. Warning: mixing calls to Sleep() and other *Alarm
- /// calls may be a bad idea on some platforms (source: Linux man page).
- /// @returns nothing.
- void Sleep(unsigned n);
-
-
-} // End sys namespace
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/System/SwapByteOrder.h b/include/llvm/System/SwapByteOrder.h
deleted file mode 100644
index 64a8acb019..0000000000
--- a/include/llvm/System/SwapByteOrder.h
+++ /dev/null
@@ -1,101 +0,0 @@
-//===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares generic and optimized functions to swap the byte order of
-// an integral type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_SWAP_BYTE_ORDER_H
-#define LLVM_SYSTEM_SWAP_BYTE_ORDER_H
-
-#include "llvm/Support/type_traits.h"
-#include "llvm/System/DataTypes.h"
-#include <cstddef>
-#include <limits>
-
-namespace llvm {
-namespace sys {
-
-template<typename value_type>
-inline
-typename enable_if_c<sizeof(value_type) == 1
- && std::numeric_limits<value_type>::is_integer,
- value_type>::type
-SwapByteOrder(value_type Value) {
- // No swapping needed.
- return Value;
-}
-
-template<typename value_type>
-inline
-typename enable_if_c<sizeof(value_type) == 2
- && std::numeric_limits<value_type>::is_integer,
- value_type>::type
-SwapByteOrder(value_type Value) {
- // Cast signed types to unsigned before swapping.
- uint16_t value = static_cast<uint16_t>(Value);
-#if defined(_MSC_VER) && !defined(_DEBUG)
- // The DLL version of the runtime lacks these functions (bug!?), but in a
- // release build they're replaced with BSWAP instructions anyway.
- return _byteswap_ushort(value);
-#else
- uint16_t Hi = value << 8;
- uint16_t Lo = value >> 8;
- return value_type(Hi | Lo);
-#endif
-}
-
-template<typename value_type>
-inline
-typename enable_if_c<sizeof(value_type) == 4
- && std::numeric_limits<value_type>::is_integer,
- value_type>::type
-SwapByteOrder(value_type Value) {
- // Cast signed types to unsigned before swapping.
- uint32_t value = static_cast<uint32_t>(Value);
-#if defined(__llvm__) || \
- (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
- return __builtin_bswap32(value);
-#elif defined(_MSC_VER) && !defined(_DEBUG)
- return _byteswap_ulong(value);
-#else
- uint32_t Byte0 = value & 0x000000FF;
- uint32_t Byte1 = value & 0x0000FF00;
- uint32_t Byte2 = value & 0x00FF0000;
- uint32_t Byte3 = value & 0xFF000000;
- return value_type(
- (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24));
-#endif
-}
-
-template<typename value_type>
-inline
-typename enable_if_c<sizeof(value_type) == 8
- && std::numeric_limits<value_type>::is_integer,
- value_type>::type
-SwapByteOrder(value_type Value) {
- // Cast signed types to unsigned before swapping.
- uint64_t value = static_cast<uint64_t>(Value);
-#if defined(__llvm__) || \
- (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
- return __builtin_bswap64(value);
-#elif defined(_MSC_VER) && !defined(_DEBUG)
- return _byteswap_uint64(value);
-#else
- uint64_t Hi = SwapByteOrder<uint32_t>(uint32_t(value));
- uint32_t Lo = SwapByteOrder<uint32_t>(uint32_t(value >> 32));
- return value_type((Hi << 32) | Lo);
-#endif
-}
-
-} // end namespace sys
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index a9f3576559..c1c118b08c 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -15,7 +15,6 @@
#define LLVM_SUPPORT_MANGLER_H
#include "llvm/ADT/DenseMap.h"
-#include <string>
namespace llvm {
class StringRef;
@@ -69,12 +68,6 @@ public:
/// empty.
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName,
ManglerPrefixTy PrefixTy = Mangler::Default);
-
- /// getNameWithPrefix - Return 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.
- std::string getNameWithPrefix(const GlobalValue *GV,
- bool isImplicitlyPrivate = false);
};
} // End llvm namespace
diff --git a/include/llvm/Target/SubtargetFeature.h b/include/llvm/Target/SubtargetFeature.h
index 45468714a3..6c21ae9583 100644
--- a/include/llvm/Target/SubtargetFeature.h
+++ b/include/llvm/Target/SubtargetFeature.h
@@ -22,7 +22,7 @@
#include <vector>
#include <cstring>
#include "llvm/ADT/Triple.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class raw_ostream;
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index bd629f16e2..0f7e6aaaf2 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -1,10 +1,10 @@
//===- Target.td - Target Independent TableGen interface ---*- tablegen -*-===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file defines the target-independent interfaces which should be
@@ -47,7 +47,7 @@ class Register<string n> {
// modification of this register can potentially read or modify the aliased
// registers.
list<Register> Aliases = [];
-
+
// SubRegs - A list of registers that are parts of this register. Note these
// are "immediate" sub-registers and the registers within the list do not
// themselves overlap. e.g. For X86, EAX's SubRegs list contains only [AX],
@@ -84,7 +84,7 @@ class Register<string n> {
// need to specify sub-registers.
// List "subregs" specifies which registers are sub-registers to this one. This
// is used to populate the SubRegs and AliasSet fields of TargetRegisterDesc.
-// This allows the code generator to be careful not to put two values with
+// This allows the code generator to be careful not to put two values with
// overlapping live ranges into registers which alias.
class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
let SubRegs = subregs;
@@ -101,7 +101,7 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// RegType - Specify the list ValueType of the registers in this register
// class. Note that all registers in a register class must have the same
- // ValueTypes. This is a list because some targets permit storing different
+ // ValueTypes. This is a list because some targets permit storing different
// types in same register, for example vector values with 128-bit total size,
// but different count/size of items, like SSE on x86.
//
@@ -127,13 +127,13 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// allocation used by the register allocator.
//
list<Register> MemberList = regList;
-
+
// SubRegClasses - Specify the register class of subregisters as a list of
// dags: (RegClass SubRegIndex, SubRegindex, ...)
list<dag> SubRegClasses = [];
// MethodProtos/MethodBodies - These members can be used to insert arbitrary
- // code into a generated register class. The normal usage of this is to
+ // code into a generated register class. The normal usage of this is to
// overload virtual methods.
code MethodProtos = [{}];
code MethodBodies = [{}];
@@ -199,6 +199,7 @@ class Instruction {
bit isBranch = 0; // Is this instruction a branch instruction?
bit isIndirectBranch = 0; // Is this instruction an indirect branch?
bit isCompare = 0; // Is this instruction a comparison instruction?
+ bit isMoveImm = 0; // Is this instruction a move immediate instruction?
bit isBarrier = 0; // Can control flow fall through this instruction?
bit isCall = 0; // Is this instruction a call instruction?
bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand?
@@ -244,16 +245,24 @@ class Instruction {
string DisableEncoding = "";
string PostEncoderMethod = "";
+ string DecoderMethod = "";
/// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc.
bits<64> TSFlags = 0;
+
+ ///@name Assembler Parser Support
+ ///@{
+
+ string AsmMatchConverter = "";
+
+ ///@}
}
/// Predicates - These are extra conditionals which are turned into instruction
/// selector matching code. Currently each predicate is just a string.
class Predicate<string cond> {
string CondString = cond;
-
+
/// AssemblerMatcherPredicate - If this feature can be used by the assembler
/// matcher, this is true. Targets should set this by inheriting their
/// feature from the AssemblerPredicate class in addition to Predicate.
@@ -333,12 +342,18 @@ class AsmOperandClass {
/// signature should be:
/// void addFooOperands(MCInst &Inst, unsigned N) const;
string RenderMethod = ?;
+
+ /// The name of the method on the target specific operand to call to custom
+ /// handle the operand parsing. This is useful when the operands do not relate
+ /// to immediates or registers and are very instruction specific (as flags to
+ /// set in a processor register, coprocessor number, ...).
+ string ParserMethod = ?;
}
def ImmAsmOperand : AsmOperandClass {
let Name = "Imm";
}
-
+
/// Operand Types - These provide the built-in operand types that may be used
/// by a target. Targets can optionally provide their own operand types as
/// needed, though this should not be needed for RISC targets.
@@ -346,6 +361,7 @@ class Operand<ValueType ty> {
ValueType Type = ty;
string PrintMethod = "printOperand";
string EncoderMethod = "";
+ string DecoderMethod = "";
string AsmOperandLowerMethod = ?;
dag MIOperandInfo = (ops);
@@ -417,6 +433,7 @@ def INLINEASM : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
+ let neverHasSideEffects = 1; // Note side effect is encoded in an operand.
}
def PROLOG_LABEL : Instruction {
let OutOperandList = (outs);
@@ -483,7 +500,7 @@ def DBG_VALUE : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "DBG_VALUE";
- let isAsCheapAsAMove = 1;
+ let neverHasSideEffects = 1;
}
def REG_SEQUENCE : Instruction {
let OutOperandList = (outs unknown:$dst);
@@ -565,7 +582,7 @@ class AssemblerPredicate {
class MnemonicAlias<string From, string To> {
string FromMnemonic = From;
string ToMnemonic = To;
-
+
// Predicates - Predicates that must be true for this remapping to happen.
list<Predicate> Predicates = [];
}
@@ -576,7 +593,7 @@ class MnemonicAlias<string From, string To> {
class InstAlias<string Asm, dag Result> {
string AsmString = Asm; // The .s format to match the instruction with.
dag ResultInst = Result; // The MCInst to generate.
-
+
// Predicates - Predicates that must be true for this to match.
list<Predicate> Predicates = [];
}
@@ -601,15 +618,15 @@ class AsmWriter {
// will specify which alternative to use. For example "{x|y|z}" with Variant
// == 1, will expand to "y".
int Variant = 0;
-
-
+
+
// FirstOperandColumn/OperandSpacing - If the assembler syntax uses a columnar
// layout, the asmwriter can actually generate output in this columns (in
// verbose-asm mode). These two values indicate the width of the first column
// (the "opcode" area) and the width to reserve for subsequent operands. When
// verbose asm mode is enabled, operands will be indented to respect this.
int FirstOperandColumn = -1;
-
+
// OperandSpacing - Space between operand columns.
int OperandSpacing = -1;
@@ -644,15 +661,15 @@ class SubtargetFeature<string n, string a, string v, string d,
// appropriate target chip.
//
string Name = n;
-
+
// Attribute - Attribute to be set by feature.
//
string Attribute = a;
-
+
// Value - Value the attribute to be set to by feature.
//
string Value = v;
-
+
// Desc - Feature description. Used by command line (-mattr=) to display help
// information.
//
@@ -674,12 +691,12 @@ class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f> {
// appropriate target chip.
//
string Name = n;
-
+
// ProcItin - The scheduling information for the target processor.
//
ProcessorItineraries ProcItin = pi;
-
- // Features - list of
+
+ // Features - list of
list<SubtargetFeature> Features = f;
}
diff --git a/include/llvm/Target/TargetAsmBackend.h b/include/llvm/Target/TargetAsmBackend.h
index b424dea4a5..7527298efa 100644
--- a/include/llvm/Target/TargetAsmBackend.h
+++ b/include/llvm/Target/TargetAsmBackend.h
@@ -10,18 +10,18 @@
#ifndef LLVM_TARGET_TARGETASMBACKEND_H
#define LLVM_TARGET_TARGETASMBACKEND_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
-class MCDataFragment;
class MCFixup;
class MCInst;
-class MCObjectFormat;
class MCObjectWriter;
class MCSection;
template<typename T>
class SmallVectorImpl;
-class Target;
class raw_ostream;
/// TargetAsmBackend - Generic interface to target specific assembler backends.
@@ -29,21 +29,13 @@ class TargetAsmBackend {
TargetAsmBackend(const TargetAsmBackend &); // DO NOT IMPLEMENT
void operator=(const TargetAsmBackend &); // DO NOT IMPLEMENT
protected: // Can only create subclasses.
- TargetAsmBackend(const Target &);
-
- /// TheTarget - The Target that this machine was created for.
- const Target &TheTarget;
+ TargetAsmBackend();
unsigned HasReliableSymbolDifference : 1;
- unsigned HasScatteredSymbols : 1;
public:
virtual ~TargetAsmBackend();
- const Target &getTarget() const { return TheTarget; }
-
- virtual const MCObjectFormat &getObjectFormat() const = 0;
-
/// createObjectWriter - Create a new MCObjectWriter instance for use by the
/// assembler backend to emit the final object file.
virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;
@@ -62,16 +54,6 @@ public:
return HasReliableSymbolDifference;
}
- /// hasScatteredSymbols - Check whether this target supports scattered
- /// symbols. If so, the assembler should assume that atoms can be scattered by
- /// the linker. In particular, this means that the offsets between symbols
- /// which are in distinct atoms is not known at link time, and the assembler
- /// must generate fixups and relocations appropriately.
- ///
- /// Note that the assembler currently does not reason about atoms, instead it
- /// assumes all temporary symbols reside in the "current atom".
- bool hasScatteredSymbols() const { return HasScatteredSymbols; }
-
/// doesSectionRequireSymbols - Check whether the given section requires that
/// all symbols (even temporaries) have symbol table entries.
virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
@@ -86,19 +68,28 @@ public:
return true;
}
- /// isVirtualSection - Check whether the given section is "virtual", that is
- /// has no actual object file contents.
- virtual bool isVirtualSection(const MCSection &Section) const = 0;
+ /// @name Target Fixup Interfaces
+ /// @{
+
+ /// getNumFixupKinds - Get the number of target specific fixup kinds.
+ virtual unsigned getNumFixupKinds() const = 0;
- /// getPointerSize - Get the pointer size in bytes.
- virtual unsigned getPointerSize() const = 0;
+ /// getFixupKindInfo - Get information on a fixup kind.
+ virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
+
+ /// @}
/// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
/// data fragment, at the offset specified by the fixup and following the
/// fixup kind as appropriate.
- virtual void ApplyFixup(const MCFixup &Fixup, MCDataFragment &Fragment,
+ virtual void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
uint64_t Value) const = 0;
+ /// @}
+
+ /// @name Target Relaxation Interfaces
+ /// @{
+
/// MayNeedRelaxation - Check whether the given instruction may need
/// relaxation.
///
@@ -113,12 +104,18 @@ public:
/// \parm Res [output] - On return, the relaxed instruction.
virtual void RelaxInstruction(const MCInst &Inst, MCInst &Res) const = 0;
+ /// @}
+
/// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given
/// output. If the target cannot generate such a sequence, it should return an
/// error.
///
/// \return - True on success.
virtual bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const = 0;
+
+ /// HandleAssemblerFlag - Handle any target-specific assembler flags.
+ /// By default, do nothing.
+ virtual void HandleAssemblerFlag(MCAssemblerFlag Flag) {}
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
new file mode 100644
index 0000000000..98aab142b8
--- /dev/null
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -0,0 +1,75 @@
+//===-- llvm/Target/TargetAsmInfo.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface to provide the information necessary for producing assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETASMINFO_H
+#define LLVM_TARGET_TARGETASMINFO_H
+
+#include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+ class MCSection;
+ class MCContext;
+ class TargetMachine;
+ class TargetLoweringObjectFile;
+
+class TargetAsmInfo {
+ unsigned PointerSize;
+ bool IsLittleEndian;
+ TargetFrameLowering::StackDirection StackDir;
+ const TargetRegisterInfo *TRI;
+ std::vector<MachineMove> InitialFrameState;
+ const TargetLoweringObjectFile *TLOF;
+
+public:
+ explicit TargetAsmInfo(const TargetMachine &TM);
+
+ /// getPointerSize - Get the pointer size in bytes.
+ unsigned getPointerSize() const {
+ return PointerSize;
+ }
+
+ /// islittleendian - True if the target is little endian.
+ bool isLittleEndian() const {
+ return IsLittleEndian;
+ }
+
+ TargetFrameLowering::StackDirection getStackGrowthDirection() const {
+ return StackDir;
+ }
+
+ const MCSection *getDwarfLineSection() const {
+ return TLOF->getDwarfLineSection();
+ }
+
+ const MCSection *getEHFrameSection() const {
+ return TLOF->getEHFrameSection();
+ }
+
+ unsigned getDwarfRARegNum(bool isEH) const {
+ return TRI->getDwarfRegNum(TRI->getRARegister(), isEH);
+ }
+
+ const std::vector<MachineMove> &getInitialFrameState() const {
+ return InitialFrameState;
+ }
+
+ int getDwarfRegNum(unsigned RegNum, bool isEH) const {
+ return TRI->getDwarfRegNum(RegNum, isEH);
+ }
+};
+
+}
+#endif
diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h
index 6b38b8c7e1..9ff50cb275 100644
--- a/include/llvm/Target/TargetAsmParser.h
+++ b/include/llvm/Target/TargetAsmParser.h
@@ -42,6 +42,8 @@ public:
unsigned getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+ virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0;
+
/// ParseInstruction - Parse one assembly instruction.
///
/// The parser is positioned following the instruction name. The target
diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h
index 5cdd114e8b..25065d30bb 100644
--- a/include/llvm/Target/TargetData.h
+++ b/include/llvm/Target/TargetData.h
@@ -22,7 +22,7 @@
#include "llvm/Pass.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -144,7 +144,7 @@ public:
std::string getStringRepresentation() const;
/// isLegalInteger - This function returns true if the specified type is
- /// known tobe a native integer type supported by the CPU. For example,
+ /// known to be a native integer type supported by the CPU. For example,
/// i64 is not native on most 32-bit CPUs and i37 is not native on any known
/// one. This returns false if the integer width is not legal.
///
diff --git a/include/llvm/Target/TargetFrameInfo.h b/include/llvm/Target/TargetFrameInfo.h
deleted file mode 100644
index 6143f3c549..0000000000
--- a/include/llvm/Target/TargetFrameInfo.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===-- llvm/Target/TargetFrameInfo.h ---------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Interface to describe the layout of a stack frame on the target machine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_TARGETFRAMEINFO_H
-#define LLVM_TARGET_TARGETFRAMEINFO_H
-
-#include <utility>
-
-namespace llvm {
- class MachineFunction;
- class MachineBasicBlock;
-
-/// Information about stack frame layout on the target. It holds the direction
-/// of stack growth, the known stack alignment on entry to each function, and
-/// the offset to the locals area.
-///
-/// The offset to the local area is the offset from the stack pointer on
-/// function entry to the first location where function data (local variables,
-/// spill locations) can be stored.
-class TargetFrameInfo {
-public:
- enum StackDirection {
- StackGrowsUp, // Adding to the stack increases the stack address
- StackGrowsDown // Adding to the stack decreases the stack address
- };
-
- // Maps a callee saved register to a stack slot with a fixed offset.
- struct SpillSlot {
- unsigned Reg;
- int Offset; // Offset relative to stack pointer on function entry.
- };
-private:
- StackDirection StackDir;
- unsigned StackAlignment;
- unsigned TransientStackAlignment;
- int LocalAreaOffset;
-public:
- TargetFrameInfo(StackDirection D, unsigned StackAl, int LAO,
- unsigned TransAl = 1)
- : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
- LocalAreaOffset(LAO) {}
-
- virtual ~TargetFrameInfo();
-
- // These methods return information that describes the abstract stack layout
- // of the target machine.
-
- /// getStackGrowthDirection - Return the direction the stack grows
- ///
- StackDirection getStackGrowthDirection() const { return StackDir; }
-
- /// getStackAlignment - This method returns the number of bytes to which the
- /// stack pointer must be aligned on entry to a function. Typically, this
- /// is the largest alignment for any data object in the target.
- ///
- unsigned getStackAlignment() const { return StackAlignment; }
-
- /// getTransientStackAlignment - This method returns the number of bytes to
- /// which the stack pointer must be aligned at all times, even between
- /// calls.
- ///
- unsigned getTransientStackAlignment() const {
- return TransientStackAlignment;
- }
-
- /// getOffsetOfLocalArea - This method returns the offset of the local area
- /// from the stack pointer on entrance to a function.
- ///
- int getOffsetOfLocalArea() const { return LocalAreaOffset; }
-
- /// getCalleeSavedSpillSlots - This method returns a pointer to an array of
- /// pairs, that contains an entry for each callee saved register that must be
- /// spilled to a particular stack location if it is spilled.
- ///
- /// Each entry in this array contains a <register,offset> pair, indicating the
- /// fixed offset from the incoming stack pointer that each register should be
- /// spilled at. If a register is not listed here, the code generator is
- /// allowed to spill it anywhere it chooses.
- ///
- virtual const SpillSlot *
- getCalleeSavedSpillSlots(unsigned &NumEntries) const {
- NumEntries = 0;
- return 0;
- }
-
- /// targetHandlesStackFrameRounding - Returns true if the target is
- /// responsible for rounding up the stack frame (probably at emitPrologue
- /// time).
- virtual bool targetHandlesStackFrameRounding() const {
- return false;
- }
-
- /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
- /// the function.
- virtual void emitPrologue(MachineFunction &MF) const = 0;
- virtual void emitEpilogue(MachineFunction &MF,
- MachineBasicBlock &MBB) const = 0;
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
new file mode 100644
index 0000000000..e104b1663f
--- /dev/null
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -0,0 +1,196 @@
+//===-- llvm/Target/TargetFrameLowering.h ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface to describe the layout of a stack frame on the target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETFRAMELOWERING_H
+#define LLVM_TARGET_TARGETFRAMELOWERING_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+
+#include <utility>
+#include <vector>
+
+namespace llvm {
+ class CalleeSavedInfo;
+ class MachineFunction;
+ class MachineBasicBlock;
+ class MachineMove;
+ class RegScavenger;
+
+/// Information about stack frame layout on the target. It holds the direction
+/// of stack growth, the known stack alignment on entry to each function, and
+/// the offset to the locals area.
+///
+/// The offset to the local area is the offset from the stack pointer on
+/// function entry to the first location where function data (local variables,
+/// spill locations) can be stored.
+class TargetFrameLowering {
+public:
+ enum StackDirection {
+ StackGrowsUp, // Adding to the stack increases the stack address
+ StackGrowsDown // Adding to the stack decreases the stack address
+ };
+
+ // Maps a callee saved register to a stack slot with a fixed offset.
+ struct SpillSlot {
+ unsigned Reg;
+ int Offset; // Offset relative to stack pointer on function entry.
+ };
+private:
+ StackDirection StackDir;
+ unsigned StackAlignment;
+ unsigned TransientStackAlignment;
+ int LocalAreaOffset;
+public:
+ TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO,
+ unsigned TransAl = 1)
+ : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
+ LocalAreaOffset(LAO) {}
+
+ virtual ~TargetFrameLowering();
+
+ // These methods return information that describes the abstract stack layout
+ // of the target machine.
+
+ /// getStackGrowthDirection - Return the direction the stack grows
+ ///
+ StackDirection getStackGrowthDirection() const { return StackDir; }
+
+ /// getStackAlignment - This method returns the number of bytes to which the
+ /// stack pointer must be aligned on entry to a function. Typically, this
+ /// is the largest alignment for any data object in the target.
+ ///
+ unsigned getStackAlignment() const { return StackAlignment; }
+
+ /// getTransientStackAlignment - This method returns the number of bytes to
+ /// which the stack pointer must be aligned at all times, even between
+ /// calls.
+ ///
+ unsigned getTransientStackAlignment() const {
+ return TransientStackAlignment;
+ }
+
+ /// getOffsetOfLocalArea - This method returns the offset of the local area
+ /// from the stack pointer on entrance to a function.
+ ///
+ int getOffsetOfLocalArea() const { return LocalAreaOffset; }
+
+ /// getCalleeSavedSpillSlots - This method returns a pointer to an array of
+ /// pairs, that contains an entry for each callee saved register that must be
+ /// spilled to a particular stack location if it is spilled.
+ ///
+ /// Each entry in this array contains a <register,offset> pair, indicating the
+ /// fixed offset from the incoming stack pointer that each register should be
+ /// spilled at. If a register is not listed here, the code generator is
+ /// allowed to spill it anywhere it chooses.
+ ///
+ virtual const SpillSlot *
+ getCalleeSavedSpillSlots(unsigned &NumEntries) const {
+ NumEntries = 0;
+ return 0;
+ }
+
+ /// targetHandlesStackFrameRounding - Returns true if the target is
+ /// responsible for rounding up the stack frame (probably at emitPrologue
+ /// time).
+ virtual bool targetHandlesStackFrameRounding() const {
+ return false;
+ }
+
+ /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
+ /// the function.
+ virtual void emitPrologue(MachineFunction &MF) const = 0;
+ virtual void emitEpilogue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const = 0;
+
+ /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
+ /// saved registers and returns true if it isn't possible / profitable to do
+ /// so by issuing a series of store instructions via
+ /// storeRegToStackSlot(). Returns false otherwise.
+ virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const std::vector<CalleeSavedInfo> &CSI,
+ const TargetRegisterInfo *TRI) const {
+ return false;
+ }
+
+ /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee
+ /// saved registers and returns true if it isn't possible / profitable to do
+ /// so by issuing a series of load instructions via loadRegToStackSlot().
+ /// Returns false otherwise.
+ virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const std::vector<CalleeSavedInfo> &CSI,
+ const TargetRegisterInfo *TRI) const {
+ return false;
+ }
+
+ /// hasFP - Return true if the specified function should have a dedicated
+ /// frame pointer register. For most targets this is true only if the function
+ /// has variable sized allocas or if frame pointer elimination is disabled.
+ virtual bool hasFP(const MachineFunction &MF) const = 0;
+
+ /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
+ /// not required, we reserve argument space for call sites in the function
+ /// immediately on entry to the current function. This eliminates the need for
+ /// add/sub sp brackets around call sites. Returns true if the call frame is
+ /// included as part of the stack frame.
+ virtual bool hasReservedCallFrame(const MachineFunction &MF) const {
+ return !hasFP(MF);
+ }
+
+ /// canSimplifyCallFramePseudos - When possible, it's best to simplify the
+ /// call frame pseudo ops before doing frame index elimination. This is
+ /// possible only when frame index references between the pseudos won't
+ /// need adjusting for the call frame adjustments. Normally, that's true
+ /// if the function has a reserved call frame or a frame pointer. Some
+ /// targets (Thumb2, for example) may have more complicated criteria,
+ /// however, and can override this behavior.
+ virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const {
+ return hasReservedCallFrame(MF) || hasFP(MF);
+ }
+
+ /// getInitialFrameState - Returns a list of machine moves that are assumed
+ /// on entry to all functions. Note that LabelID is ignored (assumed to be
+ /// the beginning of the function.)
+ virtual void getInitialFrameState(std::vector<MachineMove> &Moves) const;
+
+ /// getFrameIndexOffset - Returns the displacement from the frame register to
+ /// the stack frame of the specified index.
+ virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
+
+ /// getFrameIndexReference - This method should return the base register
+ /// and offset used to reference a frame index location. The offset is
+ /// returned directly, and the base register is returned via FrameReg.
+ virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
+ unsigned &FrameReg) const;
+
+ /// processFunctionBeforeCalleeSavedScan - This method is called immediately
+ /// before PrologEpilogInserter scans the physical registers used to determine
+ /// what callee saved registers should be spilled. This method is optional.
+ virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ RegScavenger *RS = NULL) const {
+
+ }
+
+ /// processFunctionBeforeFrameFinalized - This method is called immediately
+ /// before the specified function's frame layout (MF.getFrameInfo()) is
+ /// finalized. Once the frame is finalized, MO_FrameIndex operands are
+ /// replaced with direct constants. This method is optional.
+ ///
+ virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetInstrDesc.h b/include/llvm/Target/TargetInstrDesc.h
index a127aed8f6..8823d5a4d1 100644
--- a/include/llvm/Target/TargetInstrDesc.h
+++ b/include/llvm/Target/TargetInstrDesc.h
@@ -15,7 +15,7 @@
#ifndef LLVM_TARGET_TARGETINSTRDESC_H
#define LLVM_TARGET_TARGETINSTRDESC_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -103,13 +103,14 @@ namespace TID {
Terminator,
Branch,
IndirectBranch,
- Predicable,
- NotDuplicable,
Compare,
+ MoveImm,
DelaySlot,
FoldableAsLoad,
MayLoad,
MayStore,
+ Predicable,
+ NotDuplicable,
UnmodeledSideEffects,
Commutable,
ConvertibleTo3Addr,
@@ -352,6 +353,12 @@ public:
return Flags & (1 << TID::Compare);
}
+ /// isMoveImmediate - Return true if this instruction is a move immediate
+ /// (including conditional moves) instruction.
+ bool isMoveImmediate() const {
+ return Flags & (1 << TID::MoveImm);
+ }
+
/// isNotDuplicable - Return true if this instruction cannot be safely
/// duplicated. For example, if the instruction has a unique labels attached
/// to it, duplicating it would cause multiple definition errors.
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 2bb01f483a..c903f3153e 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -19,7 +19,6 @@
namespace llvm {
-class CalleeSavedInfo;
class InstrItineraryData;
class LiveVariables;
class MCAsmInfo;
@@ -30,6 +29,7 @@ class MCInst;
class SDNode;
class ScheduleHazardRecognizer;
class SelectionDAG;
+class ScheduleDAG;
class TargetRegisterClass;
class TargetRegisterInfo;
@@ -135,7 +135,7 @@ public:
int &FrameIndex) const {
return 0;
}
-
+
/// isStoreToStackSlot - If the specified machine instruction is a direct
/// store to a stack slot, return the virtual or physical register number of
/// the source reg along with the FrameIndex of the loaded stack slot. If
@@ -228,9 +228,12 @@ public:
/// produceSameValue - Return true if two machine instructions would produce
/// identical values. By default, this is only true when the two instructions
- /// are deemed identical except for defs.
+ /// are deemed identical except for defs. If this function is called when the
+ /// IR is still in SSA form, the caller can pass the MachineRegisterInfo for
+ /// aggressive checks.
virtual bool produceSameValue(const MachineInstr *MI0,
- const MachineInstr *MI1) const = 0;
+ const MachineInstr *MI1,
+ const MachineRegisterInfo *MRI = 0) const = 0;
/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
@@ -268,7 +271,7 @@ public:
/// This is only invoked in cases where AnalyzeBranch returns success. It
/// returns the number of instructions that were removed.
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const {
- assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!");
+ assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!");
return 0;
}
@@ -286,7 +289,7 @@ public:
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const {
- assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
+ assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
return 0;
}
@@ -315,7 +318,7 @@ public:
float Probability, float Confidence) const {
return false;
}
-
+
/// isProfitableToIfCvt - Second variant of isProfitableToIfCvt, this one
/// checks for the case where two basic blocks from true and false path
/// of a if-then-else (diamond) are predicated on mutally exclusive
@@ -342,7 +345,7 @@ public:
float Probability, float Confidence) const {
return false;
}
-
+
/// copyPhysReg - Emit instructions to copy a pair of physical registers.
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, DebugLoc DL,
@@ -375,29 +378,7 @@ public:
const TargetRegisterInfo *TRI) const {
assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!");
}
-
- /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
- /// saved registers and returns true if it isn't possible / profitable to do
- /// so by issuing a series of store instructions via
- /// storeRegToStackSlot(). Returns false otherwise.
- virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const {
- return false;
- }
- /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee
- /// saved registers and returns true if it isn't possible / profitable to do
- /// so by issuing a series of load instructions via loadRegToStackSlot().
- /// Returns false otherwise.
- virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const {
- return false;
- }
-
/// emitFrameIndexDebugValue - Emit a target-dependent form of
/// DBG_VALUE encoding the address of a frame index. Addresses would
/// normally be lowered the same way as other addresses on the target,
@@ -508,7 +489,7 @@ public:
unsigned NumLoads) const {
return false;
}
-
+
/// ReverseBranchCondition - Reverses the branch condition of the specified
/// condition list, returning false on success and true if it cannot be
/// reversed.
@@ -516,19 +497,19 @@ public:
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
return true;
}
-
+
/// insertNoop - Insert a noop into the instruction stream at the specified
/// point.
- virtual void insertNoop(MachineBasicBlock &MBB,
+ virtual void insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
-
-
+
+
/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
virtual void getNoopForMachoTarget(MCInst &NopInst) const {
// Default to just using 'nop' string.
}
-
-
+
+
/// isPredicated - Returns true if the instruction is already predicated.
///
virtual bool isPredicated(const MachineInstr *MI) const {
@@ -586,11 +567,19 @@ public:
virtual unsigned getInlineAsmLength(const char *Str,
const MCAsmInfo &MAI) const;
- /// CreateTargetHazardRecognizer - Allocate and return a hazard recognizer
- /// to use for this target when scheduling the machine instructions after
+ /// CreateTargetHazardRecognizer - Allocate and return a hazard recognizer to
+ /// use for this target when scheduling the machine instructions before
/// register allocation.
virtual ScheduleHazardRecognizer*
- CreateTargetPostRAHazardRecognizer(const InstrItineraryData*) const = 0;
+ CreateTargetHazardRecognizer(const TargetMachine *TM,
+ const ScheduleDAG *DAG) const = 0;
+
+ /// CreateTargetPostRAHazardRecognizer - Allocate and return a hazard
+ /// recognizer to use for this target when scheduling the machine instructions
+ /// after register allocation.
+ virtual ScheduleHazardRecognizer*
+ CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
+ const ScheduleDAG *DAG) const = 0;
/// AnalyzeCompare - For a comparison instruction, return the source register
/// in SrcReg and the value it compares against in CmpValue. Return true if
@@ -609,11 +598,26 @@ public:
return false;
}
+ /// FoldImmediate - 'Reg' is known to be defined by a move immediate
+ /// instruction, try to fold the immediate into the use instruction.
+ virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
+ unsigned Reg, MachineRegisterInfo *MRI) const {
+ return false;
+ }
+
/// getNumMicroOps - Return the number of u-operations the given machine
/// instruction will be decoded to on the target cpu.
virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
const MachineInstr *MI) const;
+ /// isZeroCost - Return true for pseudo instructions that don't consume any
+ /// machine resources in their current form. These are common cases that the
+ /// scheduler should consider free, rather than conservatively handling them
+ /// as instructions with no itinerary.
+ bool isZeroCost(unsigned Opcode) const {
+ return Opcode <= TargetOpcode::COPY;
+ }
+
/// getOperandLatency - Compute and return the use operand latency of a given
/// pair of def and use.
/// In most cases, the static scheduling itinerary was enough to determine the
@@ -637,6 +641,10 @@ public:
virtual int getInstrLatency(const InstrItineraryData *ItinData,
SDNode *Node) const;
+ /// isHighLatencyDef - Return true if this opcode has high latency to its
+ /// result.
+ virtual bool isHighLatencyDef(int opc) const { return false; }
+
/// hasHighOperandLatency - Compute operand latency between a def of 'Reg'
/// and an use in the current loop, return true if the target considered
/// it 'high'. This is used by optimization passes such as machine LICM to
@@ -684,13 +692,20 @@ public:
virtual MachineInstr *duplicate(MachineInstr *Orig,
MachineFunction &MF) const;
virtual bool produceSameValue(const MachineInstr *MI0,
- const MachineInstr *MI1) const;
+ const MachineInstr *MI1,
+ const MachineRegisterInfo *MRI) const;
virtual bool isSchedulingBoundary(const MachineInstr *MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const;
+ bool usePreRAHazardRecognizer() const;
+
+ virtual ScheduleHazardRecognizer *
+ CreateTargetHazardRecognizer(const TargetMachine*, const ScheduleDAG*) const;
+
virtual ScheduleHazardRecognizer *
- CreateTargetPostRAHazardRecognizer(const InstrItineraryData*) const;
+ CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
+ const ScheduleDAG*) const;
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h
index 380147c650..a95b70f6b9 100644
--- a/include/llvm/Target/TargetInstrItineraries.h
+++ b/include/llvm/Target/TargetInstrItineraries.h
@@ -113,15 +113,17 @@ public:
const unsigned *OperandCycles; ///< Array of operand cycles selected
const unsigned *Forwardings; ///< Array of pipeline forwarding pathes
const InstrItinerary *Itineraries; ///< Array of itineraries selected
+ unsigned IssueWidth; ///< Max issue per cycle. 0=Unknown.
/// Ctors.
///
InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0),
- Itineraries(0) {}
+ Itineraries(0), IssueWidth(0) {}
+
InstrItineraryData(const InstrStage *S, const unsigned *OS,
const unsigned *F, const InstrItinerary *I)
: Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I) {}
-
+
/// isEmpty - Returns true if there are no itineraries.
///
bool isEmpty() const { return Itineraries == 0; }
@@ -135,14 +137,14 @@ public:
}
/// beginStage - Return the first stage of the itinerary.
- ///
+ ///
const InstrStage *beginStage(unsigned ItinClassIndx) const {
unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
return Stages + StageIdx;
}
/// endStage - Return the last+1 stage of the itinerary.
- ///
+ ///
const InstrStage *endStage(unsigned ItinClassIndx) const {
unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
return Stages + StageIdx;
diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h
index 7208a8dc44..b198eb62f0 100644
--- a/include/llvm/Target/TargetJITInfo.h
+++ b/include/llvm/Target/TargetJITInfo.h
@@ -19,7 +19,7 @@
#include <cassert>
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class Function;
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
new file mode 100644
index 0000000000..1847a3725e
--- /dev/null
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -0,0 +1,75 @@
+//===-- llvm/Target/TargetLibraryInfo.h - Library information ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETLIBRARYINFO_H
+#define LLVM_TARGET_TARGETLIBRARYINFO_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+ class Triple;
+
+ namespace LibFunc {
+ enum Func {
+ /// void *memset(void *b, int c, size_t len);
+ memset,
+
+ // void *memcpy(void *s1, const void *s2, size_t n);
+ memcpy,
+
+ /// void memset_pattern16(void *b, const void *pattern16, size_t len);
+ memset_pattern16,
+
+ /// int iprintf(const char *format, ...);
+ iprintf,
+
+ /// int siprintf(char *str, const char *format, ...);
+ siprintf,
+
+ /// int fiprintf(FILE *stream, const char *format, ...);
+ fiprintf,
+
+ NumLibFuncs
+ };
+ }
+
+/// TargetLibraryInfo - This immutable pass captures information about what
+/// library functions are available for the current target, and allows a
+/// frontend to disable optimizations through -fno-builtin etc.
+class TargetLibraryInfo : public ImmutablePass {
+ unsigned char AvailableArray[(LibFunc::NumLibFuncs+7)/8];
+public:
+ static char ID;
+ TargetLibraryInfo();
+ TargetLibraryInfo(const Triple &T);
+
+ /// has - This function is used by optimizations that want to match on or form
+ /// a given library function.
+ bool has(LibFunc::Func F) const {
+ return (AvailableArray[F/8] & (1 << (F&7))) != 0;
+ }
+
+ /// setUnavailable - this can be used by whatever sets up TargetLibraryInfo to
+ /// ban use of specific library functions.
+ void setUnavailable(LibFunc::Func F) {
+ AvailableArray[F/8] &= ~(1 << (F&7));
+ }
+
+ void setAvailable(LibFunc::Func F) {
+ AvailableArray[F/8] |= 1 << (F&7);
+ }
+
+ /// disableAllFunctions - This disables all builtins, which is used for
+ /// options like -fno-builtin.
+ void disableAllFunctions();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 75e5325524..42c330f4f2 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -39,6 +39,7 @@ namespace llvm {
class AllocaInst;
class APFloat;
class CallInst;
+ class CCState;
class Function;
class FastISel;
class FunctionLoweringInfo;
@@ -111,7 +112,7 @@ public:
bool isBigEndian() const { return !IsLittleEndian; }
bool isLittleEndian() const { return IsLittleEndian; }
MVT getPointerTy() const { return PointerTy; }
- MVT getShiftAmountTy() const { return ShiftAmountTy; }
+ virtual MVT getShiftAmountTy(EVT LHSTy) const;
/// isSelectExpensive - Return true if the select operation is expensive for
/// this target.
@@ -125,6 +126,10 @@ public:
/// srl/add/sra.
bool isPow2DivCheap() const { return Pow2DivIsCheap; }
+ /// isJumpExpensive() - Return true if Flow Control is an expensive operation
+ /// that should be avoided.
+ bool isJumpExpensive() const { return JumpIsExpensive; }
+
/// getSetCCResultType - Return the ValueType of the result of SETCC
/// operations. Also used to obtain the target's preferred type for
/// the condition operand of SELECT and BRCOND nodes. In the case of
@@ -206,7 +211,7 @@ public:
/// ValueTypeActions - For each value type, keep a LegalizeAction enum
/// that indicates how instruction selection should deal with the type.
uint8_t ValueTypeActions[MVT::LAST_VALUETYPE];
-
+
LegalizeAction getExtendedTypeAction(EVT VT) const {
// Handle non-vector integers.
if (!VT.isVector()) {
@@ -217,42 +222,56 @@ public:
return Promote;
return Expand;
}
-
- // If this is a type smaller than a legal vector type, promote to that
- // type, e.g. <2 x float> -> <4 x float>.
- if (VT.getVectorElementType().isSimple() &&
- VT.getVectorNumElements() != 1) {
- MVT EltType = VT.getVectorElementType().getSimpleVT();
- unsigned NumElts = VT.getVectorNumElements();
- while (1) {
- // Round up to the nearest power of 2.
- NumElts = (unsigned)NextPowerOf2(NumElts);
-
- MVT LargerVector = MVT::getVectorVT(EltType, NumElts);
- if (LargerVector == MVT()) break;
-
- // If this the larger type is legal, promote to it.
- if (getTypeAction(LargerVector) == Legal) return Promote;
- }
+
+ // Vectors with only one element are always scalarized.
+ if (VT.getVectorNumElements() == 1)
+ return Expand;
+
+ // Vectors with a number of elements that is not a power of two are always
+ // widened, for example <3 x float> -> <4 x float>.
+ if (!VT.isPow2VectorType())
+ return Promote;
+
+ // Vectors with a crazy element type are always expanded, for example
+ // <4 x i2> is expanded into two vectors of type <2 x i2>.
+ if (!VT.getVectorElementType().isSimple())
+ return Expand;
+
+ // If this type is smaller than a legal vector type then widen it,
+ // otherwise expand it. E.g. <2 x float> -> <4 x float>.
+ MVT EltType = VT.getVectorElementType().getSimpleVT();
+ unsigned NumElts = VT.getVectorNumElements();
+ while (1) {
+ // Round up to the next power of 2.
+ NumElts = (unsigned)NextPowerOf2(NumElts);
+
+ // If there is no simple vector type with this many elements then there
+ // cannot be a larger legal vector type. Note that this assumes that
+ // there are no skipped intermediate vector types in the simple types.
+ MVT LargerVector = MVT::getVectorVT(EltType, NumElts);
+ if (LargerVector == MVT())
+ return Expand;
+
+ // If this type is legal then widen the vector.
+ if (getTypeAction(LargerVector) == Legal)
+ return Promote;
}
-
- return VT.isPow2VectorType() ? Expand : Promote;
- }
+ }
public:
ValueTypeActionImpl() {
std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0);
}
-
+
LegalizeAction getTypeAction(EVT VT) const {
if (!VT.isExtended())
return getTypeAction(VT.getSimpleVT());
return getExtendedTypeAction(VT);
}
-
+
LegalizeAction getTypeAction(MVT VT) const {
return (LegalizeAction)ValueTypeActions[VT.SimpleTy];
}
-
+
void setTypeAction(EVT VT, LegalizeAction Action) {
unsigned I = VT.getSimpleVT().SimpleTy;
ValueTypeActions[I] = Action;
@@ -273,7 +292,7 @@ public:
LegalizeAction getTypeAction(MVT VT) const {
return ValueTypeActions.getTypeAction(VT);
}
-
+
/// getTypeToTransformTo - For types supported by the target, this is an
/// identity function. For types that must be promoted to larger types, this
/// returns the larger type to promote to. For integer types that are larger
@@ -306,7 +325,7 @@ public:
EVT NVT = VT.getRoundIntegerType(Context);
if (NVT == VT) // Size is a power of two - expand to half the size.
return EVT::getIntegerVT(Context, VT.getSizeInBits() / 2);
-
+
// Promote to a power of two size, avoiding multi-step promotion.
return getTypeAction(NVT) == Promote ?
getTypeToTransformTo(Context, NVT) : NVT;
@@ -638,21 +657,30 @@ public:
/// This function returns the maximum number of store operations permitted
/// to replace a call to llvm.memset. The value is set by the target at the
- /// performance threshold for such a replacement.
+ /// performance threshold for such a replacement. If OptSize is true,
+ /// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memset
- unsigned getMaxStoresPerMemset() const { return maxStoresPerMemset; }
+ unsigned getMaxStoresPerMemset(bool OptSize) const {
+ return OptSize ? maxStoresPerMemsetOptSize : maxStoresPerMemset;
+ }
/// This function returns the maximum number of store operations permitted
/// to replace a call to llvm.memcpy. The value is set by the target at the
- /// performance threshold for such a replacement.
+ /// performance threshold for such a replacement. If OptSize is true,
+ /// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memcpy
- unsigned getMaxStoresPerMemcpy() const { return maxStoresPerMemcpy; }
+ unsigned getMaxStoresPerMemcpy(bool OptSize) const {
+ return OptSize ? maxStoresPerMemcpyOptSize : maxStoresPerMemcpy;
+ }
/// This function returns the maximum number of store operations permitted
/// to replace a call to llvm.memmove. The value is set by the target at the
- /// performance threshold for such a replacement.
+ /// performance threshold for such a replacement. If OptSize is true,
+ /// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memmove
- unsigned getMaxStoresPerMemmove() const { return maxStoresPerMemmove; }
+ unsigned getMaxStoresPerMemmove(bool OptSize) const {
+ return OptSize ? maxStoresPerMemmoveOptSize : maxStoresPerMemmove;
+ }
/// This function returns true if the target allows unaligned memory accesses.
/// of the specified type. This is used, for example, in situations where an
@@ -950,6 +978,13 @@ public:
return isTypeLegal(VT);
}
+ /// isDesirableToPromoteOp - Return true if it is profitable for dag combiner
+ /// to transform a floating point op of specified opcode to a equivalent op of
+ /// an integer type. e.g. f32 load -> i32 load can be profitable on ARM.
+ virtual bool isDesirableToTransformToIntegerOp(unsigned Opc, EVT VT) const {
+ return false;
+ }
+
/// IsDesirableToPromoteOp - This method query the target whether it is
/// beneficial for dag combiner to promote the specified node. If true, it
/// should return the desired promotion type by reference.
@@ -963,10 +998,6 @@ public:
//
protected:
- /// setShiftAmountType - Describe the type that should be used for shift
- /// amounts. This type defaults to the pointer type.
- void setShiftAmountType(MVT VT) { ShiftAmountTy = VT; }
-
/// setBooleanContents - Specify how the target extends the result of a
/// boolean value from i1 to a wider type. See getBooleanContents.
void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; }
@@ -1013,7 +1044,16 @@ protected:
/// SelectIsExpensive - Tells the code generator not to expand operations
/// into sequences that use the select operations if possible.
- void setSelectIsExpensive() { SelectIsExpensive = true; }
+ void setSelectIsExpensive(bool isExpensive = true) {
+ SelectIsExpensive = isExpensive;
+ }
+
+ /// JumpIsExpensive - Tells the code generator not to expand sequence of
+ /// operations into a seperate sequences that increases the amount of
+ /// flow control.
+ void setJumpIsExpensive(bool isExpensive = true) {
+ JumpIsExpensive = isExpensive;
+ }
/// setIntDivIsCheap - Tells the code generator that integer divide is
/// expensive, and if possible, should be replaced by an alternate sequence
@@ -1219,6 +1259,9 @@ public:
return SDValue(); // this is here to silence compiler errors
}
+ /// HandleByVal - Target-specific cleanup for formal ByVal parameters.
+ virtual void HandleByVal(CCState *) const {}
+
/// CanLowerReturn - This hook should be implemented to check whether the
/// return values described by the Outs array can fit into the return
/// registers. If false is returned, an sret-demotion is performed.
@@ -1245,6 +1288,13 @@ public:
return SDValue(); // this is here to silence compiler errors
}
+ /// isUsedByReturnOnly - Return true if result of the specified node is used
+ /// by a return node only. This is used to determine whether it is possible
+ /// to codegen a libcall as tail call at legalization time.
+ virtual bool isUsedByReturnOnly(SDNode *N) const {
+ return false;
+ }
+
/// LowerOperationWrapper - This callback is invoked by the type legalizer
/// to legalize nodes with an illegal operand type but legal result types.
/// It replaces the LowerOperation callback in the type Legalizer.
@@ -1319,7 +1369,7 @@ public:
CW_Good = 1, // Good weight.
CW_Better = 2, // Better weight.
CW_Best = 3, // Best weight.
-
+
// Well-known weights.
CW_SpecificReg = CW_Okay, // Specific register operands.
CW_Register = CW_Good, // Register operands.
@@ -1372,21 +1422,21 @@ public:
CallOperandVal(0), ConstraintVT(MVT::Other) {
}
};
-
+
typedef std::vector<AsmOperandInfo> AsmOperandInfoVector;
-
+
/// ParseConstraints - Split up the constraint string from the inline
/// assembly value into the specific constraints and their prefixes,
/// and also tie in the associated operand values.
/// If this returns an empty vector, and if the constraint string itself
/// isn't empty, there was an error parsing.
virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const;
-
+
/// Examine constraint type and operand type and determine a weight value.
/// The operand object must already have been set up with the operand type.
virtual ConstraintWeight getMultipleConstraintMatchWeight(
AsmOperandInfo &info, int maIndex) const;
-
+
/// Examine constraint string and operand type and determine a weight value.
/// The operand object must already have been set up with the operand type.
virtual ConstraintWeight getSingleConstraintMatchWeight(
@@ -1396,7 +1446,7 @@ public:
/// type to use for the specific AsmOperandInfo, setting
/// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand
/// being passed in is available, it can be passed in as Op, otherwise an
- /// empty SDValue can be passed.
+ /// empty SDValue can be passed.
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
SDValue Op,
SelectionDAG *DAG = 0) const;
@@ -1597,6 +1647,11 @@ private:
/// it.
bool Pow2DivIsCheap;
+ /// JumpIsExpensive - Tells the code generator that it shouldn't generate
+ /// extra flow control instructions and should attempt to combine flow
+ /// control instructions via predication.
+ bool JumpIsExpensive;
+
/// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement
/// llvm.setjmp. Defaults to false.
bool UseUnderscoreSetJmp;
@@ -1605,10 +1660,6 @@ private:
/// llvm.longjmp. Defaults to false.
bool UseUnderscoreLongJmp;
- /// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever
- /// PointerTy is.
- MVT ShiftAmountTy;
-
/// BooleanContents - Information about the contents of the high-bits in
/// boolean values held in a type wider than i1. See getBooleanContents.
BooleanContent BooleanContents;
@@ -1751,6 +1802,10 @@ protected:
/// @brief Specify maximum number of store instructions per memset call.
unsigned maxStoresPerMemset;
+ /// Maximum number of stores operations that may be substituted for the call
+ /// to memset, used for functions with OptSize attribute.
+ unsigned maxStoresPerMemsetOptSize;
+
/// When lowering \@llvm.memcpy this field specifies the maximum number of
/// store operations that may be substituted for a call to memcpy. Targets
/// must set this value based on the cost threshold for that target. Targets
@@ -1763,6 +1818,10 @@ protected:
/// @brief Specify maximum bytes of store instructions per memcpy call.
unsigned maxStoresPerMemcpy;
+ /// Maximum number of store operations that may be substituted for a call
+ /// to memcpy, used for functions with OptSize attribute.
+ unsigned maxStoresPerMemcpyOptSize;
+
/// When lowering \@llvm.memmove this field specifies the maximum number of
/// store instructions that may be substituted for a call to memmove. Targets
/// must set this value based on the cost threshold for that target. Targets
@@ -1774,6 +1833,10 @@ protected:
/// @brief Specify maximum bytes of store instructions per memmove call.
unsigned maxStoresPerMemmove;
+ /// Maximum number of store instructions that may be substituted for a call
+ /// to memmove, used for functions with OpSize attribute.
+ unsigned maxStoresPerMemmoveOptSize;
+
/// This field specifies whether the target can benefit from code placement
/// optimization.
bool benefitFromCodePlacementOpt;
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 5456dd0700..34bf27132d 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -69,10 +69,6 @@ protected:
/// the section the Language Specific Data Area information is emitted to.
const MCSection *LSDASection;
- /// EHFrameSection - If exception handling is supported by the target, this is
- /// the section the EH Frame is emitted to.
- const MCSection *EHFrameSection;
-
// Dwarf sections for debug info. If a target supports debug info, these must
// be set.
const MCSection *DwarfAbbrevSection;
@@ -143,7 +139,7 @@ public:
const MCSection *getStaticCtorSection() const { return StaticCtorSection; }
const MCSection *getStaticDtorSection() const { return StaticDtorSection; }
const MCSection *getLSDASection() const { return LSDASection; }
- const MCSection *getEHFrameSection() const { return EHFrameSection; }
+ virtual const MCSection *getEHFrameSection() const = 0;
const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
const MCSection *getDwarfLineSection() const { return DwarfLineSection; }
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 01dc1b0c41..030bf5b89f 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -29,7 +29,7 @@ class TargetIntrinsicInfo;
class TargetJITInfo;
class TargetLowering;
class TargetSelectionDAGInfo;
-class TargetFrameInfo;
+class TargetFrameLowering;
class JITCodeEmitter;
class MCContext;
class TargetRegisterInfo;
@@ -104,6 +104,8 @@ protected: // Can only create subclasses.
const MCAsmInfo *AsmInfo;
unsigned MCRelaxAll : 1;
+ unsigned MCNoExecStack : 1;
+ unsigned MCUseLoc : 1;
public:
virtual ~TargetMachine();
@@ -116,11 +118,11 @@ public:
// -- Stack frame information
// -- Selection DAG lowering information
//
- virtual const TargetInstrInfo *getInstrInfo() const { return 0; }
- virtual const TargetFrameInfo *getFrameInfo() const { return 0; }
+ virtual const TargetInstrInfo *getInstrInfo() const { return 0; }
+ virtual const TargetFrameLowering *getFrameLowering() const { return 0; }
virtual const TargetLowering *getTargetLowering() const { return 0; }
virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const{ return 0; }
- virtual const TargetData *getTargetData() const { return 0; }
+ virtual const TargetData *getTargetData() const { return 0; }
/// getMCAsmInfo - Return target specific asm information.
///
@@ -169,6 +171,18 @@ public:
/// relaxed.
void setMCRelaxAll(bool Value) { MCRelaxAll = Value; }
+ /// hasMCNoExecStack - Check whether an executable stack is not needed.
+ bool hasMCNoExecStack() const { return MCNoExecStack; }
+
+ /// setMCNoExecStack - Set whether an executabel stack is not needed.
+ void setMCNoExecStack(bool Value) { MCNoExecStack = Value; }
+
+ /// hasMCUseLoc - Check whether we should use dwarf's .loc directive.
+ bool hasMCUseLoc() const { return MCUseLoc; }
+
+ /// setMCUseLoc - Set whether all we should use dwarf's .loc directive.
+ void setMCUseLoc(bool Value) { MCUseLoc = Value; }
+
/// getRelocationModel - Returns the code generation relocation model. The
/// choices are static, PIC, and dynamic-no-pic, and target default.
static Reloc::Model getRelocationModel();
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 9be36238a1..af10748ef4 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -29,21 +29,21 @@ class MachineFunction;
class MachineMove;
class RegScavenger;
template<class T> class SmallVectorImpl;
+class raw_ostream;
/// TargetRegisterDesc - This record contains all of the information known about
-/// a particular register. The AliasSet field (if not null) contains a pointer
-/// to a Zero terminated array of registers that this register aliases. This is
-/// needed for architectures like X86 which have AL alias AX alias EAX.
-/// Registers that this does not apply to simply should set this to null.
-/// The SubRegs field is a zero terminated array of registers that are
-/// sub-registers of the specific register, e.g. AL, AH are sub-registers of AX.
-/// The SuperRegs field is a zero terminated array of registers that are
+/// a particular register. The Overlaps field contains a pointer to a zero
+/// terminated array of registers that this register aliases, starting with
+/// itself. This is needed for architectures like X86 which have AL alias AX
+/// alias EAX. The SubRegs field is a zero terminated array of registers that
+/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of
+/// AX. The SuperRegs field is a zero terminated array of registers that are
/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
/// of AX.
///
struct TargetRegisterDesc {
const char *Name; // Printable name for the reg (for debugging)
- const unsigned *AliasSet; // Register Alias Set, described above
+ const unsigned *Overlaps; // Overlapping registers, described above
const unsigned *SubRegs; // Sub-register set, described above
const unsigned *SuperRegs; // Super-register set, described above
};
@@ -295,30 +295,68 @@ protected:
virtual ~TargetRegisterInfo();
public:
- enum { // Define some target independent constants
- /// NoRegister - This physical register is not a real target register. It
- /// is useful as a sentinal.
- NoRegister = 0,
+ // Register numbers can represent physical registers, virtual registers, and
+ // sometimes stack slots. The unsigned values are divided into these ranges:
+ //
+ // 0 Not a register, can be used as a sentinel.
+ // [1;2^30) Physical registers assigned by TableGen.
+ // [2^30;2^31) Stack slots. (Rarely used.)
+ // [2^31;2^32) Virtual registers assigned by MachineRegisterInfo.
+ //
+ // Further sentinels can be allocated from the small negative integers.
+ // DenseMapInfo<unsigned> uses -1u and -2u.
+
+ /// isStackSlot - Sometimes it is useful the be able to store a non-negative
+ /// frame index in a variable that normally holds a register. isStackSlot()
+ /// returns true if Reg is in the range used for stack slots.
+ ///
+ /// Note that isVirtualRegister() and isPhysicalRegister() cannot handle stack
+ /// slots, so if a variable may contains a stack slot, always check
+ /// isStackSlot() first.
+ ///
+ static bool isStackSlot(unsigned Reg) {
+ return int(Reg) >= (1 << 30);
+ }
- /// FirstVirtualRegister - This is the first register number that is
- /// considered to be a 'virtual' register, which is part of the SSA
- /// namespace. This must be the same for all targets, which means that each
- /// target is limited to this fixed number of registers.
- FirstVirtualRegister = 16384
- };
+ /// stackSlot2Index - Compute the frame index from a register value
+ /// representing a stack slot.
+ static int stackSlot2Index(unsigned Reg) {
+ assert(isStackSlot(Reg) && "Not a stack slot");
+ return int(Reg - (1u << 30));
+ }
+
+ /// index2StackSlot - Convert a non-negative frame index to a stack slot
+ /// register value.
+ static unsigned index2StackSlot(int FI) {
+ assert(FI >= 0 && "Cannot hold a negative frame index.");
+ return FI + (1u << 30);
+ }
/// isPhysicalRegister - Return true if the specified register number is in
/// the physical register namespace.
static bool isPhysicalRegister(unsigned Reg) {
- assert(Reg && "this is not a register!");
- return Reg < FirstVirtualRegister;
+ assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.");
+ return int(Reg) > 0;
}
/// isVirtualRegister - Return true if the specified register number is in
/// the virtual register namespace.
static bool isVirtualRegister(unsigned Reg) {
- assert(Reg && "this is not a register!");
- return Reg >= FirstVirtualRegister;
+ assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.");
+ return int(Reg) < 0;
+ }
+
+ /// virtReg2Index - Convert a virtual register number to a 0-based index.
+ /// The first virtual register in a function will get the index 0.
+ static unsigned virtReg2Index(unsigned Reg) {
+ assert(isVirtualRegister(Reg) && "Not a virtual register");
+ return Reg - (1u << 31);
+ }
+
+ /// index2VirtReg - Convert a 0-based index to a virtual register number.
+ /// This is the inverse operation of VirtReg2IndexFunctor below.
+ static unsigned index2VirtReg(unsigned Index) {
+ return Index + (1u << 31);
}
/// getMinimalPhysRegClass - Returns the Register Class of a physical
@@ -351,7 +389,17 @@ public:
/// terminated.
///
const unsigned *getAliasSet(unsigned RegNo) const {
- return get(RegNo).AliasSet;
+ // The Overlaps set always begins with Reg itself.
+ return get(RegNo).Overlaps + 1;
+ }
+
+ /// getOverlaps - Return a list of registers that overlap Reg, including
+ /// itself. This is the same as the alias set except Reg is included in the
+ /// list.
+ /// These are exactly the registers in { x | regsOverlap(x, Reg) }.
+ ///
+ const unsigned *getOverlaps(unsigned RegNo) const {
+ return get(RegNo).Overlaps;
}
/// getSubRegisters - Return the list of registers that are sub-registers of
@@ -583,6 +631,13 @@ public:
return false;
}
+ /// useFPForScavengingIndex - returns true if the target wants to use
+ /// frame pointer based accesses to spill to the scavenger emergency spill
+ /// slot.
+ virtual bool useFPForScavengingIndex(const MachineFunction &MF) const {
+ return true;
+ }
+
/// requiresFrameIndexScavenging - returns true if the target requires post
/// PEI scavenging of registers for materializing frame index constants.
virtual bool requiresFrameIndexScavenging(const MachineFunction &MF) const {
@@ -596,31 +651,6 @@ public:
return false;
}
- /// hasFP - Return true if the specified function should have a dedicated
- /// frame pointer register. For most targets this is true only if the function
- /// has variable sized allocas or if frame pointer elimination is disabled.
- virtual bool hasFP(const MachineFunction &MF) const = 0;
-
- /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
- /// not required, we reserve argument space for call sites in the function
- /// immediately on entry to the current function. This eliminates the need for
- /// add/sub sp brackets around call sites. Returns true if the call frame is
- /// included as part of the stack frame.
- virtual bool hasReservedCallFrame(const MachineFunction &MF) const {
- return !hasFP(MF);
- }
-
- /// canSimplifyCallFramePseudos - When possible, it's best to simplify the
- /// call frame pseudo ops before doing frame index elimination. This is
- /// possible only when frame index references between the pseudos won't
- /// need adjusting for the call frame adjustments. Normally, that's true
- /// if the function has a reserved call frame or a frame pointer. Some
- /// targets (Thumb2, for example) may have more complicated criteria,
- /// however, and can override this behavior.
- virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const {
- return hasReservedCallFrame(MF) || hasFP(MF);
- }
-
/// hasReservedSpillSlot - Return true if target has reserved a spill slot in
/// the stack frame of the given function for the specified register. e.g. On
/// x86, if the frame register is required, the first fixed stack object is
@@ -640,7 +670,7 @@ public:
}
/// getFrameIndexInstrOffset - Get the offset from the referenced frame
- /// index in the instruction, if the is one.
+ /// index in the instruction, if there is one.
virtual int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
int Idx) const {
return 0;
@@ -656,7 +686,7 @@ public:
/// materializeFrameBaseRegister - Insert defining instruction(s) for
/// BaseReg to be a pointer to FrameIdx before insertion point I.
- virtual void materializeFrameBaseRegister(MachineBasicBlock::iterator I,
+ virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB,
unsigned BaseReg, int FrameIdx,
int64_t Offset) const {
assert(0 && "materializeFrameBaseRegister does not exist on this target");
@@ -703,21 +733,6 @@ public:
assert(0 && "Call Frame Pseudo Instructions do not exist on this target!");
}
- /// processFunctionBeforeCalleeSavedScan - This method is called immediately
- /// before PrologEpilogInserter scans the physical registers used to determine
- /// what callee saved registers should be spilled. This method is optional.
- virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS = NULL) const {
-
- }
-
- /// processFunctionBeforeFrameFinalized - This method is called immediately
- /// before the specified function's frame layout (MF.getFrameInfo()) is
- /// finalized. Once the frame is finalized, MO_FrameIndex operands are
- /// replaced with direct constants. This method is optional.
- ///
- virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
- }
/// saveScavengerRegister - Spill the register so it can be used by the
/// register scavenger. Return true if the register was spilled, false
@@ -755,37 +770,16 @@ public:
/// for values allocated in the current stack frame.
virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0;
- /// getFrameIndexOffset - Returns the displacement from the frame register to
- /// the stack frame of the specified index.
- virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
-
- /// getFrameIndexReference - This method should return the base register
- /// and offset used to reference a frame index location. The offset is
- /// returned directly, and the base register is returned via FrameReg.
- virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
- unsigned &FrameReg) const {
- // By default, assume all frame indices are referenced via whatever
- // getFrameRegister() says. The target can override this if it's doing
- // something different.
- FrameReg = getFrameRegister(MF);
- return getFrameIndexOffset(MF, FI);
- }
-
/// getRARegister - This method should return the register where the return
/// address can be found.
virtual unsigned getRARegister() const = 0;
-
- /// getInitialFrameState - Returns a list of machine moves that are assumed
- /// on entry to all functions. Note that LabelID is ignored (assumed to be
- /// the beginning of the function.)
- virtual void getInitialFrameState(std::vector<MachineMove> &Moves) const;
};
// This is useful when building IndexedMaps keyed on virtual registers
struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
unsigned operator()(unsigned Reg) const {
- return Reg - TargetRegisterInfo::FirstVirtualRegister;
+ return TargetRegisterInfo::virtReg2Index(Reg);
}
};
@@ -794,6 +788,33 @@ struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
const TargetRegisterClass *getCommonSubClass(const TargetRegisterClass *A,
const TargetRegisterClass *B);
+/// PrintReg - Helper class for printing registers on a raw_ostream.
+/// Prints virtual and physical registers with or without a TRI instance.
+///
+/// The format is:
+/// %noreg - NoRegister
+/// %vreg5 - a virtual register.
+/// %vreg5:sub_8bit - a virtual register with sub-register index (with TRI).
+/// %EAX - a physical register
+/// %physreg17 - a physical register when no TRI instance given.
+///
+/// Usage: OS << PrintReg(Reg, TRI) << '\n';
+///
+class PrintReg {
+ const TargetRegisterInfo *TRI;
+ unsigned Reg;
+ unsigned SubIdx;
+public:
+ PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, unsigned subidx = 0)
+ : TRI(tri), Reg(reg), SubIdx(subidx) {}
+ void print(raw_ostream&) const;
+};
+
+static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) {
+ PR.print(OS);
+ return OS;
+}
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
index abffb5852a..f851ad0a9b 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -42,9 +42,11 @@ namespace llvm {
class formatted_raw_ostream;
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
- bool isLittleEndian, bool isVerboseAsm,
+ bool isVerboseAsm,
+ bool useLoc,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
+ TargetAsmBackend *TAB,
bool ShowInst);
/// Target - Wrapper for Target specific information.
@@ -87,13 +89,15 @@ namespace llvm {
TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
- bool RelaxAll);
+ bool RelaxAll,
+ bool NoExecStack);
typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
formatted_raw_ostream &OS,
- bool isLittleEndian,
bool isVerboseAsm,
+ bool useLoc,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
+ TargetAsmBackend *TAB,
bool ShowInst);
private:
@@ -305,27 +309,31 @@ namespace llvm {
/// \arg _OS - The stream object.
/// \arg _Emitter - The target independent assembler object.Takes ownership.
/// \arg RelaxAll - Relax all fixups?
+ /// \arg NoExecStack - Mark file as not needing a executable stack.
MCStreamer *createObjectStreamer(const std::string &TT, MCContext &Ctx,
TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
- bool RelaxAll) const {
+ bool RelaxAll,
+ bool NoExecStack) const {
if (!ObjectStreamerCtorFn)
return 0;
- return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll);
+ return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll,
+ NoExecStack);
}
/// createAsmStreamer - Create a target specific MCStreamer.
MCStreamer *createAsmStreamer(MCContext &Ctx,
formatted_raw_ostream &OS,
- bool isLittleEndian,
bool isVerboseAsm,
+ bool useLoc,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
+ TargetAsmBackend *TAB,
bool ShowInst) const {
// AsmStreamerCtorFn is default to llvm::createAsmStreamer
- return AsmStreamerCtorFn(Ctx, OS, isLittleEndian, isVerboseAsm,
- InstPrint, CE, ShowInst);
+ return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc,
+ InstPrint, CE, TAB, ShowInst);
}
/// @}
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 7315e52ef0..c9be40d23f 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -1,10 +1,10 @@
//===- TargetSelectionDAG.td - Common code for DAG isels ---*- tablegen -*-===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file defines the target-independent interfaces used by SelectionDAG
@@ -61,6 +61,13 @@ class SDTCisEltOfVec<int ThisOp, int OtherOp>
int OtherOpNum = OtherOp;
}
+/// SDTCisSubVecOfVec - This indicates that ThisOp is a vector type
+/// with length less that of OtherOp, which is a vector type.
+class SDTCisSubVecOfVec<int ThisOp, int OtherOp>
+ : SDTypeConstraint<ThisOp> {
+ int OtherOpNum = OtherOp;
+}
+
//===----------------------------------------------------------------------===//
// Selection DAG Type Profile definitions.
//
@@ -123,10 +130,10 @@ def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround
def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend
SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>
]>;
-def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp
+def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp
SDTCisFP<0>, SDTCisInt<1>
]>;
-def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int
+def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int
SDTCisInt<0>, SDTCisFP<1>
]>;
def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg
@@ -138,7 +145,7 @@ def SDTSetCC : SDTypeProfile<1, 3, [ // setcc
SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>
]>;
-def SDTSelect : SDTypeProfile<1, 3, [ // select
+def SDTSelect : SDTypeProfile<1, 3, [ // select
SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>
]>;
@@ -162,11 +169,11 @@ def SDTBrind : SDTypeProfile<0, 1, [ // brind
def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap
def SDTLoad : SDTypeProfile<1, 1, [ // load
- SDTCisPtrTy<1>
+ SDTCisPtrTy<1>
]>;
def SDTStore : SDTypeProfile<0, 2, [ // store
- SDTCisPtrTy<1>
+ SDTCisPtrTy<1>
]>;
def SDTIStore : SDTypeProfile<1, 3, [ // indexed store
@@ -183,6 +190,13 @@ def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert
SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3>
]>;
+def SDTSubVecExtract : SDTypeProfile<1, 2, [// subvector extract
+ SDTCisSubVecOfVec<0,1>, SDTCisInt<2>
+]>;
+def SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert
+ SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3>
+]>;
+
def SDTPrefetch : SDTypeProfile<0, 3, [ // prefetch
SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisInt<1>
]>;
@@ -216,9 +230,9 @@ class SDNodeProperty;
def SDNPCommutative : SDNodeProperty; // X op Y == Y op X
def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z)
def SDNPHasChain : SDNodeProperty; // R/W chain operand and result
-def SDNPOutFlag : SDNodeProperty; // Write a flag result
-def SDNPInFlag : SDNodeProperty; // Read a flag operand
-def SDNPOptInFlag : SDNodeProperty; // Optionally read a flag operand
+def SDNPOutGlue : SDNodeProperty; // Write a flag result
+def SDNPInGlue : SDNodeProperty; // Read a flag operand
+def SDNPOptInGlue : SDNodeProperty; // Optionally read a flag operand
def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'.
def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'.
def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'.
@@ -235,7 +249,7 @@ class SDPatternOperator;
// Selection DAG Node definitions.
//
class SDNode<string opcode, SDTypeProfile typeprof,
- list<SDNodeProperty> props = [], string sdclass = "SDNode">
+ list<SDNodeProperty> props = [], string sdclass = "SDNode">
: SDPatternOperator {
string Opcode = opcode;
string SDClass = sdclass;
@@ -312,14 +326,14 @@ def or : SDNode<"ISD::OR" , SDTIntBinOp,
def xor : SDNode<"ISD::XOR" , SDTIntBinOp,
[SDNPCommutative, SDNPAssociative]>;
def addc : SDNode<"ISD::ADDC" , SDTIntBinOp,
- [SDNPCommutative, SDNPOutFlag]>;
+ [SDNPCommutative, SDNPOutGlue]>;
def adde : SDNode<"ISD::ADDE" , SDTIntBinOp,
- [SDNPCommutative, SDNPOutFlag, SDNPInFlag]>;
+ [SDNPCommutative, SDNPOutGlue, SDNPInGlue]>;
def subc : SDNode<"ISD::SUBC" , SDTIntBinOp,
- [SDNPOutFlag]>;
+ [SDNPOutGlue]>;
def sube : SDNode<"ISD::SUBE" , SDTIntBinOp,
- [SDNPOutFlag, SDNPInFlag]>;
-
+ [SDNPOutGlue, SDNPInGlue]>;
+
def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>;
def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>;
@@ -329,11 +343,11 @@ def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>;
def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>;
def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>;
def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>;
-def bitconvert : SDNode<"ISD::BIT_CONVERT", SDTUnaryOp>;
+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]>;
@@ -375,7 +389,8 @@ def trap : SDNode<"ISD::TRAP" , SDTNone,
[SDNPHasChain, SDNPSideEffect]>;
def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch,
- [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
+ [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
+ SDNPMemOperand]>;
def membarrier : SDNode<"ISD::MEMBARRIER" , SDTMemBarrier,
[SDNPHasChain, SDNPSideEffect]>;
@@ -422,16 +437,26 @@ def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT",
SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>;
def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>;
-
+
+// This operator does not do subvector type checking. The ARM
+// backend, at least, needs it.
+def vector_extract_subvec : SDNode<"ISD::EXTRACT_SUBVECTOR",
+ SDTypeProfile<1, 2, [SDTCisInt<2>, SDTCisVec<1>, SDTCisVec<0>]>,
+ []>;
+
+// This operator does subvector type checking.
+def extract_subvector : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract, []>;
+def insert_subvector : SDNode<"ISD::INSERT_SUBVECTOR", SDTSubVecInsert, []>;
+
// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use
// these internally. Don't reference these directly.
-def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID",
+def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID",
SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
[SDNPHasChain]>;
-def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
+def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>,
[SDNPHasChain]>;
-def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
+def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>;
// Do not use cvt directly. Use cvt forms below
diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h
index 40ef9bbbd6..12398813cc 100644
--- a/include/llvm/Transforms/IPO.h
+++ b/include/llvm/Transforms/IPO.h
@@ -189,12 +189,6 @@ ModulePass *createBlockExtractorPass();
ModulePass *createStripDeadPrototypesPass();
//===----------------------------------------------------------------------===//
-/// createPartialSpecializationPass - This pass specializes functions for
-/// constant arguments.
-///
-ModulePass *createPartialSpecializationPass();
-
-//===----------------------------------------------------------------------===//
/// createFunctionAttrsPass - This pass discovers functions that do not access
/// memory, or only read memory, and gives them the readnone/readonly attribute.
/// It also discovers function arguments that are not captured by the function
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index 9c579ac761..aa9873fb8a 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -25,6 +25,9 @@ ModulePass *createEdgeProfilerPass();
// Insert optimal edge profiling instrumentation
ModulePass *createOptimalEdgeProfilerPass();
+// Insert path profiling instrumentation
+ModulePass *createPathProfilerPass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/RSProfiling.h b/include/llvm/Transforms/RSProfiling.h
deleted file mode 100644
index 02439e8e23..0000000000
--- a/include/llvm/Transforms/RSProfiling.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===- RSProfiling.cpp - Various profiling using random sampling ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the abstract interface that a profiler must implement to
-// support the random profiling transform.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_RSPROFILING_H
-#define LLVM_TRANSFORMS_RSPROFILING_H
-
-#include "llvm/Pass.h"
-
-namespace llvm {
- class Value;
-
- //===--------------------------------------------------------------------===//
- /// RSProfilers - The basic Random Sampling Profiler Interface Any profiler
- /// that implements this interface can be transformed by the random sampling
- /// pass to be sample based rather than always on.
- ///
- /// The only exposed function can be queried to find out if an instruction
- /// was original or if it was inserted by the profiler. Implementations of
- /// this interface are expected to chain to other implementations, such that
- /// multiple profilers can be support simultaniously.
- struct RSProfilers : public ModulePass {
- static char ID; // Pass identification, replacement for typeinfo
- RSProfilers() : ModulePass(&ID) {}
-
- /// isProfiling - This method returns true if the value passed it was
- /// inserted by the profiler.
- virtual bool isProfiling(Value* v) = 0;
- };
-}
-
-#endif
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index fa848459a7..8d5ed44cff 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -73,7 +73,8 @@ FunctionPass *createAggressiveDCEPass();
// ScalarReplAggregates - Break up alloca's of aggregates into multiple allocas
// if possible.
//
-FunctionPass *createScalarReplAggregatesPass(signed Threshold = -1);
+FunctionPass *createScalarReplAggregatesPass(signed Threshold = -1,
+ bool UseDomTree = true);
//===----------------------------------------------------------------------===//
//
@@ -119,6 +120,12 @@ Pass *createLoopUnswitchPass(bool OptimizeForSize = false);
//===----------------------------------------------------------------------===//
//
+// LoopInstSimplify - This pass simplifies instructions in a loop's body.
+//
+Pass *createLoopInstSimplifyPass();
+
+//===----------------------------------------------------------------------===//
+//
// LoopUnroll - This pass is a simple loop unrolling pass.
//
Pass *createLoopUnrollPass();
@@ -131,6 +138,12 @@ Pass *createLoopRotatePass();
//===----------------------------------------------------------------------===//
//
+// LoopIdiom - This pass recognizes and replaces idioms in loops.
+//
+Pass *createLoopIdiomPass();
+
+//===----------------------------------------------------------------------===//
+//
// PromoteMemoryToRegister - This pass is used to promote memory references to
// be register references. A simple example of the transformation performed by
// this pass is:
@@ -254,6 +267,13 @@ extern char &LCSSAID;
//===----------------------------------------------------------------------===//
//
+// EarlyCSE - This pass performs a simple and fast CSE pass over the dominator
+// tree.
+//
+FunctionPass *createEarlyCSEPass();
+
+//===----------------------------------------------------------------------===//
+//
// GVN - This pass performs global value numbering and redundant load
// elimination cotemporaneously.
//
@@ -281,12 +301,6 @@ FunctionPass *createSimplifyLibCallsPass();
//===----------------------------------------------------------------------===//
//
-/// createSimplifyHalfPowrLibCallsPass - This is an experimental pass that
-/// optimizes specific half_pow functions.
-FunctionPass *createSimplifyHalfPowrLibCallsPass();
-
-//===----------------------------------------------------------------------===//
-//
// CodeGenPrepare - This pass prepares a function for instruction selection.
//
FunctionPass *createCodeGenPreparePass(const TargetLowering *TLI = 0);
@@ -322,6 +336,13 @@ Pass *createLowerAtomicPass();
//
Pass *createCorrelatedValuePropagationPass();
+//===----------------------------------------------------------------------===//
+//
+// InstructionSimplifier - Remove redundant instructions.
+//
+FunctionPass *createInstructionSimplifierPass();
+extern char &InstructionSimplifierID;
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/AddrModeMatcher.h b/include/llvm/Transforms/Utils/AddrModeMatcher.h
index be601e257b..0678eccb5d 100644
--- a/include/llvm/Transforms/Utils/AddrModeMatcher.h
+++ b/include/llvm/Transforms/Utils/AddrModeMatcher.h
@@ -39,6 +39,12 @@ struct ExtAddrMode : public TargetLowering::AddrMode {
ExtAddrMode() : BaseReg(0), ScaledReg(0) {}
void print(raw_ostream &OS) const;
void dump() const;
+
+ bool operator==(const ExtAddrMode& O) const {
+ return (BaseReg == O.BaseReg) && (ScaledReg == O.ScaledReg) &&
+ (BaseGV == O.BaseGV) && (BaseOffs == O.BaseOffs) &&
+ (HasBaseReg == O.HasBaseReg) && (Scale == O.Scale);
+ }
};
static inline raw_ostream &operator<<(raw_ostream &OS, const ExtAddrMode &AM) {
@@ -84,7 +90,7 @@ public:
bool Success =
AddressingModeMatcher(AddrModeInsts, TLI, AccessTy,
MemoryInst, Result).MatchAddr(V, 0);
- Success = Success; assert(Success && "Couldn't select *anything*?");
+ (void)Success; assert(Success && "Couldn't select *anything*?");
return Result;
}
private:
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 0f5445077b..5335860287 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -22,9 +22,10 @@
namespace llvm {
+class AliasAnalysis;
class Instruction;
class Pass;
-class AliasAnalysis;
+class ReturnInst;
/// DeleteDeadBlock - Delete the specified block, which must have no
/// predecessors.
@@ -35,7 +36,7 @@ void DeleteDeadBlock(BasicBlock *BB);
/// any single-entry PHI nodes in it, fold them away. This handles the case
/// when all entries to the PHI nodes in a block are guaranteed equal, such as
/// when the block has exactly one predecessor.
-void FoldSingleEntryPHINodes(BasicBlock *BB);
+void FoldSingleEntryPHINodes(BasicBlock *BB, Pass *P = 0);
/// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it
/// is dead. Also recursively delete any operands that become dead as
@@ -46,7 +47,7 @@ bool DeleteDeadPHIs(BasicBlock *BB);
/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
/// if possible. The return value indicates success or failure.
-bool MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P = 0);
+bool MergeBlockIntoPredecessor(BasicBlock *BB, Pass *P = 0);
// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
// with a value, then remove and delete the original instruction.
@@ -75,15 +76,6 @@ void FindFunctionBackedges(const Function &F,
SmallVectorImpl<std::pair<const BasicBlock*,const BasicBlock*> > &Result);
-// RemoveSuccessor - Change the specified terminator instruction such that its
-// successor #SuccNum no longer exists. Because this reduces the outgoing
-// degree of the current basic block, the actual terminator instruction itself
-// may have to be changed. In the case where the last successor of the block is
-// deleted, a return instruction is inserted in its place which can cause a
-// suprising change in program behavior if it is not expected.
-//
-void RemoveSuccessor(TerminatorInst *TI, unsigned SuccNum);
-
/// GetSuccessorNumber - Search for the specified successor of basic block BB
/// and return its position in the terminator instruction's list of
/// successors. It is an error to call this with a block that is not a
@@ -180,7 +172,15 @@ BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P);
BasicBlock *SplitBlockPredecessors(BasicBlock *BB, BasicBlock *const *Preds,
unsigned NumPreds, const char *Suffix,
Pass *P = 0);
-
+
+/// FoldReturnIntoUncondBranch - This method duplicates the specified return
+/// instruction into a predecessor which ends in an unconditional branch. If
+/// the return instruction returns a value defined by a PHI, propagate the
+/// right value into the return. It returns the new return instruction in the
+/// predecessor.
+ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
+ BasicBlock *Pred);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
index c75c14277f..e825938384 100644
--- a/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -47,11 +47,6 @@ namespace llvm {
/// specified pointer arguments and length.
Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
const TargetData *TD, StringRef Name = "strncpy");
-
- /// EmitMemCpy - Emit a call to the memcpy function to the builder. This
- /// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
- Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len, unsigned Align,
- bool isVolatile, IRBuilder<> &B, const TargetData *TD);
/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
@@ -59,11 +54,6 @@ namespace llvm {
Value *EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
IRBuilder<> &B, const TargetData *TD);
- /// EmitMemMove - Emit a call to the memmove function to the builder. This
- /// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
- Value *EmitMemMove(Value *Dst, Value *Src, Value *Len, unsigned Align,
- bool isVolatile, IRBuilder<> &B, const TargetData *TD);
-
/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
@@ -73,10 +63,6 @@ namespace llvm {
Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
const TargetData *TD);
- /// EmitMemSet - Emit a call to the memset function
- Value *EmitMemSet(Value *Dst, Value *Val, Value *Len, bool isVolatile,
- IRBuilder<> &B, const TargetData *TD);
-
/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name'
/// (e.g. 'floor'). This function is known to take a single of type matching
/// 'Op' and returns one value with the same type. If 'Op' is a long double,
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index dc18f3c4c7..2823fbb719 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -60,7 +60,7 @@ bool RecursivelyDeleteTriviallyDeadInstructions(Value *V);
/// dead PHI node, due to being a def-use chain of single-use nodes that
/// either forms a cycle or is terminated by a trivially dead instruction,
/// delete it. If that makes any of its operands trivially dead, delete them
-/// too, recursively. Return true if the PHI node is actually deleted.
+/// too, recursively. Return true if a change was made.
bool RecursivelyDeleteDeadPHINode(PHINode *PN);
@@ -145,6 +145,18 @@ AllocaInst *DemoteRegToStack(Instruction &X,
/// The phi node is deleted and it returns the pointer to the alloca inserted.
AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0);
+/// getOrEnforceKnownAlignment - If the specified pointer has an alignment that
+/// we can determine, return it, otherwise return 0. If PrefAlign is specified,
+/// and it is more than the alignment of the ultimate object, see if we can
+/// increase the alignment of the ultimate object, making this check succeed.
+unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
+ const TargetData *TD = 0);
+
+/// getKnownAlignment - Try to infer an alignment for the specified pointer.
+static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) {
+ return getOrEnforceKnownAlignment(V, 0, TD);
+}
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h
index 35cfaddb73..98d51a29ad 100644
--- a/include/llvm/Transforms/Utils/PromoteMemToReg.h
+++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -38,8 +38,7 @@ bool isAllocaPromotable(const AllocaInst *AI);
/// made to the IR.
///
void PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
- DominatorTree &DT, DominanceFrontier &DF,
- AliasSetTracker *AST = 0);
+ DominatorTree &DT, AliasSetTracker *AST = 0);
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h
index e50a6b15df..b4048b9b44 100644
--- a/include/llvm/Transforms/Utils/SSAUpdater.h
+++ b/include/llvm/Transforms/Utils/SSAUpdater.h
@@ -108,6 +108,55 @@ private:
void operator=(const SSAUpdater&); // DO NOT IMPLEMENT
SSAUpdater(const SSAUpdater&); // DO NOT IMPLEMENT
};
+
+/// LoadAndStorePromoter - This little helper class provides a convenient way to
+/// promote a collection of loads and stores into SSA Form using the SSAUpdater.
+/// This handles complexities that SSAUpdater doesn't, such as multiple loads
+/// and stores in one block.
+///
+/// Clients of this class are expected to subclass this and implement the
+/// virtual methods.
+///
+class LoadAndStorePromoter {
+protected:
+ SSAUpdater &SSA;
+public:
+ LoadAndStorePromoter(const SmallVectorImpl<Instruction*> &Insts,
+ SSAUpdater &S, StringRef Name = StringRef());
+ virtual ~LoadAndStorePromoter() {}
+
+ /// run - This does the promotion. Insts is a list of loads and stores to
+ /// promote, and Name is the basename for the PHIs to insert. After this is
+ /// complete, the loads and stores are removed from the code.
+ void run(const SmallVectorImpl<Instruction*> &Insts) const;
+
+
+ /// Return true if the specified instruction is in the Inst list (which was
+ /// passed into the run method). Clients should implement this with a more
+ /// efficient version if possible.
+ virtual bool isInstInList(Instruction *I,
+ const SmallVectorImpl<Instruction*> &Insts) const {
+ for (unsigned i = 0, e = Insts.size(); i != e; ++i)
+ if (Insts[i] == I)
+ return true;
+ return false;
+ }
+
+ /// doExtraRewritesBeforeFinalDeletion - This hook is invoked after all the
+ /// stores are found and inserted as available values, but
+ virtual void doExtraRewritesBeforeFinalDeletion() const {
+ }
+
+ /// replaceLoadWithValue - Clients can choose to implement this to get
+ /// notified right before a load is RAUW'd another value.
+ virtual void replaceLoadWithValue(LoadInst *LI, Value *V) const {
+ }
+
+ /// This is called before each instruction is deleted.
+ virtual void instructionDeleted(Instruction *I) const {
+ }
+
+};
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h
index dd320a3fb4..d612213a87 100644
--- a/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/include/llvm/Transforms/Utils/ValueMapper.h
@@ -22,10 +22,29 @@ namespace llvm {
class Instruction;
typedef ValueMap<const Value *, TrackingVH<Value> > ValueToValueMapTy;
+ /// RemapFlags - These are flags that the value mapping APIs allow.
+ enum RemapFlags {
+ RF_None = 0,
+
+ /// RF_NoModuleLevelChanges - If this flag is set, the remapper knows that
+ /// only local values within a function (such as an instruction or argument)
+ /// are mapped, not global values like functions and global metadata.
+ RF_NoModuleLevelChanges = 1,
+
+ /// RF_IgnoreMissingEntries - If this flag is set, the remapper ignores
+ /// entries that are not in the value map. If it is unset, it aborts if an
+ /// operand is asked to be remapped which doesn't exist in the mapping.
+ RF_IgnoreMissingEntries = 2
+ };
+
+ static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
+ return RemapFlags(unsigned(LHS)|unsigned(RHS));
+ }
+
Value *MapValue(const Value *V, ValueToValueMapTy &VM,
- bool ModuleLevelChanges);
+ RemapFlags Flags = RF_None);
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
- bool ModuleLevelChanges);
+ RemapFlags Flags = RF_None);
} // End llvm namespace
#endif
diff --git a/include/llvm/TypeSymbolTable.h b/include/llvm/TypeSymbolTable.h
index 55b8b7a3d9..9fdcb98323 100644
--- a/include/llvm/TypeSymbolTable.h
+++ b/include/llvm/TypeSymbolTable.h
@@ -16,7 +16,7 @@
#include "llvm/Type.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <map>
namespace llvm {
diff --git a/include/llvm/Use.h b/include/llvm/Use.h
index e1ebc6a51b..ccbdd7fcae 100644
--- a/include/llvm/Use.h
+++ b/include/llvm/Use.h
@@ -25,7 +25,6 @@
#ifndef LLVM_USE_H
#define LLVM_USE_H
-#include "llvm/Support/Casting.h"
#include "llvm/ADT/PointerIntPair.h"
#include <cstddef>
#include <iterator>
@@ -35,9 +34,8 @@ namespace llvm {
class Value;
class User;
class Use;
-
-/// Tag - generic tag type for (at least 32 bit) pointers
-enum Tag { noTag, tagOne, tagTwo, tagThree };
+template<typename>
+struct simplify_type;
// Use** is only 4-byte aligned.
template<>
@@ -67,17 +65,19 @@ private:
Use(const Use &U);
/// Destructor - Only for zap()
- inline ~Use() {
+ ~Use() {
if (Val) removeFromList();
}
- /// Default ctor - This leaves the Use completely uninitialized. The only
- /// thing that is valid to do with this use is to call the "init" method.
- inline Use() {}
- enum PrevPtrTag { zeroDigitTag = noTag
- , oneDigitTag = tagOne
- , stopTag = tagTwo
- , fullStopTag = tagThree };
+ enum PrevPtrTag { zeroDigitTag
+ , oneDigitTag
+ , stopTag
+ , fullStopTag };
+
+ /// Constructor
+ Use(PrevPtrTag tag) : Val(0) {
+ Prev.setInt(tag);
+ }
public:
/// Normally Use will just implicitly convert to a Value* that it holds.
@@ -112,11 +112,9 @@ public:
/// a User changes.
static void zap(Use *Start, const Use *Stop, bool del = false);
- /// getPrefix - Return deletable pointer if appropriate
- Use *getPrefix();
private:
const Use* getImpliedUser() const;
- static Use *initTags(Use *Start, Use *Stop, ptrdiff_t Done = 0);
+ static Use *initTags(Use *Start, Use *Stop);
Value *Val;
Use *Next;
@@ -210,6 +208,15 @@ public:
unsigned getOperandNo() const;
};
+//===----------------------------------------------------------------------===//
+// AugmentedUse layout struct
+//===----------------------------------------------------------------------===//
+
+struct AugmentedUse : public Use {
+ PointerIntPair<User*, 1, unsigned> ref;
+ AugmentedUse(); // not implemented
+};
+
} // End llvm namespace
#endif
diff --git a/include/llvm/User.h b/include/llvm/User.h
index f8277952ee..1363495f7c 100644
--- a/include/llvm/User.h
+++ b/include/llvm/User.h
@@ -29,20 +29,6 @@ namespace llvm {
template <class>
struct OperandTraits;
-class User;
-
-/// OperandTraits<User> - specialization to User
-template <>
-struct OperandTraits<User> {
- static inline Use *op_begin(User*);
- static inline Use *op_end(User*);
- static inline unsigned operands(const User*);
- template <class U>
- struct Layout {
- typedef U overlay;
- };
-};
-
class User : public Value {
User(const User &); // Do not implement
void *operator new(size_t); // Do not implement
@@ -61,21 +47,18 @@ protected:
unsigned NumOperands;
void *operator new(size_t s, unsigned Us);
- void *operator new(size_t s, unsigned Us, bool Prefix);
User(const Type *ty, unsigned vty, Use *OpList, unsigned NumOps)
: Value(ty, vty), OperandList(OpList), NumOperands(NumOps) {}
Use *allocHungoffUses(unsigned) const;
- void dropHungoffUses(Use *U) {
- if (OperandList == U) {
- OperandList = 0;
- NumOperands = 0;
- }
- Use::zap(U, U->getImpliedUser(), true);
+ void dropHungoffUses() {
+ Use::zap(OperandList, OperandList + NumOperands, true);
+ OperandList = 0;
+ // Reset NumOperands so User::operator delete() does the right thing.
+ NumOperands = 0;
}
public:
~User() {
- if ((intptr_t(OperandList) & 1) == 0)
- Use::zap(OperandList, OperandList + NumOperands);
+ Use::zap(OperandList, OperandList + NumOperands);
}
/// operator delete - free memory allocated for User and Use objects
void operator delete(void *Usr);
@@ -158,18 +141,6 @@ public:
}
};
-inline Use *OperandTraits<User>::op_begin(User *U) {
- return U->op_begin();
-}
-
-inline Use *OperandTraits<User>::op_end(User *U) {
- return U->op_end();
-}
-
-inline unsigned OperandTraits<User>::operands(const User *U) {
- return U->getNumOperands();
-}
-
template<> struct simplify_type<User::op_iterator> {
typedef Value* SimpleType;
diff --git a/include/llvm/Value.h b/include/llvm/Value.h
index 8dc4105b9e..130e2735f5 100644
--- a/include/llvm/Value.h
+++ b/include/llvm/Value.h
@@ -252,6 +252,12 @@ public:
return SubclassOptionalData;
}
+ /// clearSubclassOptionalData - Clear the optional flags contained in
+ /// this value.
+ void clearSubclassOptionalData() {
+ SubclassOptionalData = 0;
+ }
+
/// hasSameSubclassOptionalData - Test whether the optional flags contained
/// in this value are equal to the optional flags in the given value.
bool hasSameSubclassOptionalData(const Value *V) const {
@@ -285,16 +291,6 @@ public:
return const_cast<Value*>(this)->stripPointerCasts();
}
- /// getUnderlyingObject - This method strips off any GEP address adjustments
- /// and pointer casts from the specified value, returning the original object
- /// being addressed. Note that the returned value has pointer type if the
- /// specified value does. If the MaxLookup value is non-zero, it limits the
- /// number of instructions to be stripped off.
- Value *getUnderlyingObject(unsigned MaxLookup = 6);
- const Value *getUnderlyingObject(unsigned MaxLookup = 6) const {
- return const_cast<Value*>(this)->getUnderlyingObject(MaxLookup);
- }
-
/// isDereferenceablePointer - Test if this value is always a pointer to
/// allocated and suitably aligned memory for a simple load or store.
bool isDereferenceablePointer() const;
diff --git a/include/llvm/ValueSymbolTable.h b/include/llvm/ValueSymbolTable.h
index 35fc97b2d3..1738cc4a7a 100644
--- a/include/llvm/ValueSymbolTable.h
+++ b/include/llvm/ValueSymbolTable.h
@@ -16,7 +16,7 @@
#include "llvm/Value.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
template<typename ValueSubClass, typename ItemParentClass>