aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-07-21 00:45:20 -0700
committerStephen Hines <srhines@google.com>2014-07-21 00:45:20 -0700
commitc6a4f5e819217e1e12c458aed8e7b122e23a3a58 (patch)
tree81b7dd2bb4370a392f31d332a566c903b5744764 /include
parent19c6fbb3e8aaf74093afa08013134b61fa08f245 (diff)
downloadexternal_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.zip
external_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.tar.gz
external_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.tar.bz2
Update LLVM for rebase to r212749.
Includes a cherry-pick of: r212948 - fixes a small issue with atomic calls Change-Id: Ib97bd980b59f18142a69506400911a6009d9df18
Diffstat (limited to 'include')
-rw-r--r--include/llvm-c/Core.h16
-rw-r--r--include/llvm-c/module.modulemap1
-rw-r--r--include/llvm/ADT/APSInt.h2
-rw-r--r--include/llvm/ADT/ArrayRef.h6
-rw-r--r--include/llvm/ADT/BitVector.h5
-rw-r--r--include/llvm/ADT/DenseMap.h9
-rw-r--r--include/llvm/ADT/DenseSet.h6
-rw-r--r--include/llvm/ADT/FoldingSet.h8
-rw-r--r--include/llvm/ADT/Hashing.h4
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h47
-rw-r--r--include/llvm/ADT/MapVector.h15
-rw-r--r--include/llvm/ADT/OwningPtr.h165
-rw-r--r--include/llvm/ADT/ScopedHashTable.h4
-rw-r--r--include/llvm/ADT/SmallBitVector.h3
-rw-r--r--include/llvm/ADT/SmallPtrSet.h5
-rw-r--r--include/llvm/ADT/SmallSet.h5
-rw-r--r--include/llvm/ADT/SmallVector.h15
-rw-r--r--include/llvm/ADT/SparseBitVector.h3
-rw-r--r--include/llvm/ADT/SparseMultiSet.h5
-rw-r--r--include/llvm/ADT/SparseSet.h5
-rw-r--r--include/llvm/ADT/StringMap.h64
-rw-r--r--include/llvm/ADT/Triple.h11
-rw-r--r--include/llvm/ADT/Twine.h4
-rw-r--r--include/llvm/ADT/UniqueVector.h19
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h8
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfoImpl.h691
-rw-r--r--include/llvm/Analysis/JumpInstrTableInfo.h60
-rw-r--r--include/llvm/Analysis/Passes.h4
-rw-r--r--include/llvm/Analysis/RegionInfo.h10
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h1
-rw-r--r--include/llvm/Analysis/ValueTracking.h5
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h14
-rw-r--r--include/llvm/Bitcode/ReaderWriter.h11
-rw-r--r--include/llvm/CodeGen/Analysis.h4
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h1
-rw-r--r--include/llvm/CodeGen/CommandFlags.h16
-rw-r--r--include/llvm/CodeGen/FastISel.h13
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h37
-rw-r--r--include/llvm/CodeGen/JumpInstrTables.h104
-rw-r--r--include/llvm/CodeGen/LexicalScopes.h6
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h11
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h4
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h3
-rw-r--r--include/llvm/CodeGen/MachineInstr.h5
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h217
-rw-r--r--include/llvm/CodeGen/Passes.h19
-rw-r--r--include/llvm/CodeGen/RegisterPressure.h2
-rw-r--r--include/llvm/CodeGen/ScheduleDFS.h2
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h87
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h86
-rw-r--r--include/llvm/CodeGen/StackMapLivenessAnalysis.h15
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h12
-rw-r--r--include/llvm/Config/config.h.cmake155
-rw-r--r--include/llvm/Config/config.h.in156
-rw-r--r--include/llvm/Config/llvm-config.h.cmake41
-rw-r--r--include/llvm/Config/llvm-config.h.in41
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h29
-rw-r--r--include/llvm/ExecutionEngine/ObjectBuffer.h3
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h2
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyldChecker.h98
-rw-r--r--include/llvm/ExecutionEngine/SectionMemoryManager.h5
-rw-r--r--include/llvm/IR/Attributes.h1
-rw-r--r--include/llvm/IR/AutoUpgrade.h5
-rw-r--r--include/llvm/IR/Comdat.h66
-rw-r--r--include/llvm/IR/Constant.h14
-rw-r--r--include/llvm/IR/DIBuilder.h13
-rw-r--r--include/llvm/IR/DataLayout.h4
-rw-r--r--include/llvm/IR/DebugInfo.h16
-rw-r--r--include/llvm/IR/DebugLoc.h2
-rw-r--r--include/llvm/IR/DiagnosticInfo.h8
-rw-r--r--include/llvm/IR/Dominators.h4
-rw-r--r--include/llvm/IR/GVMaterializer.h9
-rw-r--r--include/llvm/IR/GlobalAlias.h34
-rw-r--r--include/llvm/IR/GlobalObject.h14
-rw-r--r--include/llvm/IR/GlobalValue.h53
-rw-r--r--include/llvm/IR/GlobalVariable.h21
-rw-r--r--include/llvm/IR/IRBuilder.h29
-rw-r--r--include/llvm/IR/Instructions.h36
-rw-r--r--include/llvm/IR/Intrinsics.h3
-rw-r--r--include/llvm/IR/Intrinsics.td4
-rw-r--r--include/llvm/IR/IntrinsicsAArch64.td7
-rw-r--r--include/llvm/IR/IntrinsicsARM.td17
-rw-r--r--include/llvm/IR/IntrinsicsNVVM.td183
-rw-r--r--include/llvm/IR/IntrinsicsR600.td36
-rw-r--r--include/llvm/IR/IntrinsicsX86.td36
-rw-r--r--include/llvm/IR/LegacyPassNameParser.h2
-rw-r--r--include/llvm/IR/Module.h31
-rw-r--r--include/llvm/IR/User.h10
-rw-r--r--include/llvm/IR/Value.h26
-rw-r--r--include/llvm/IR/ValueMap.h19
-rw-r--r--include/llvm/IRReader/IRReader.h10
-rw-r--r--include/llvm/InitializePasses.h3
-rw-r--r--include/llvm/LTO/LTOModule.h95
-rw-r--r--include/llvm/LinkAllPasses.h2
-rw-r--r--include/llvm/Linker/Linker.h2
-rw-r--r--include/llvm/MC/ConstantPools.h80
-rw-r--r--include/llvm/MC/MCAnalysis/MCAtom.h (renamed from include/llvm/MC/MCAtom.h)6
-rw-r--r--include/llvm/MC/MCAnalysis/MCFunction.h (renamed from include/llvm/MC/MCFunction.h)6
-rw-r--r--include/llvm/MC/MCAnalysis/MCModule.h (renamed from include/llvm/MC/MCModule.h)6
-rw-r--r--include/llvm/MC/MCAnalysis/MCModuleYAML.h (renamed from include/llvm/MC/MCModuleYAML.h)6
-rw-r--r--include/llvm/MC/MCAsmInfo.h1006
-rw-r--r--include/llvm/MC/MCAssembler.h2
-rw-r--r--include/llvm/MC/MCContext.h37
-rw-r--r--include/llvm/MC/MCDwarf.h7
-rw-r--r--include/llvm/MC/MCELFStreamer.h1
-rw-r--r--include/llvm/MC/MCELFSymbolFlags.h1
-rw-r--r--include/llvm/MC/MCExpr.h3
-rw-r--r--include/llvm/MC/MCLinkerOptimizationHint.h15
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h2
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h15
-rw-r--r--include/llvm/MC/MCObjectStreamer.h9
-rw-r--r--include/llvm/MC/MCParser/AsmLexer.h4
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h32
-rw-r--r--include/llvm/MC/MCSectionCOFF.h18
-rw-r--r--include/llvm/MC/MCStreamer.h114
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h20
-rw-r--r--include/llvm/MC/MCTargetOptions.h4
-rw-r--r--include/llvm/MC/MCTargetOptionsCommandFlags.h9
-rw-r--r--include/llvm/MC/MCWinCOFFStreamer.h3
-rw-r--r--include/llvm/MC/StringTableBuilder.h (renamed from include/llvm/Object/StringTableBuilder.h)4
-rw-r--r--include/llvm/MC/YAML.h (renamed from include/llvm/Object/YAML.h)33
-rw-r--r--include/llvm/Object/Archive.h18
-rw-r--r--include/llvm/Object/Binary.h8
-rw-r--r--include/llvm/Object/COFF.h134
-rw-r--r--include/llvm/Object/COFFYAML.h4
-rw-r--r--include/llvm/Object/ELF.h60
-rw-r--r--include/llvm/Object/ELFObjectFile.h240
-rw-r--r--include/llvm/Object/ELFYAML.h13
-rw-r--r--include/llvm/Object/Error.h34
-rw-r--r--include/llvm/Object/IRObjectFile.h21
-rw-r--r--include/llvm/Object/MachO.h123
-rw-r--r--include/llvm/Object/MachOUniversal.h19
-rw-r--r--include/llvm/Object/ObjectFile.h231
-rw-r--r--include/llvm/Object/RelocVisitor.h6
-rw-r--r--include/llvm/Object/SymbolicFile.h36
-rw-r--r--include/llvm/Option/ArgList.h8
-rw-r--r--include/llvm/PassInfo.h147
-rw-r--r--include/llvm/PassRegistry.h27
-rw-r--r--include/llvm/PassSupport.h128
-rw-r--r--include/llvm/ProfileData/InstrProf.h26
-rw-r--r--include/llvm/ProfileData/InstrProfReader.h49
-rw-r--r--include/llvm/ProfileData/InstrProfWriter.h5
-rw-r--r--include/llvm/Support/ARMBuildAttributes.h15
-rw-r--r--include/llvm/Support/ARMWinEH.h384
-rw-r--r--include/llvm/Support/COFF.h10
-rw-r--r--include/llvm/Support/Compiler.h6
-rw-r--r--include/llvm/Support/ConvertUTF.h14
-rw-r--r--include/llvm/Support/CrashRecoveryContext.h3
-rw-r--r--include/llvm/Support/DataTypes.h.cmake121
-rw-r--r--include/llvm/Support/DataTypes.h.in119
-rw-r--r--include/llvm/Support/Dwarf.h1
-rw-r--r--include/llvm/Support/ELF.h27
-rw-r--r--include/llvm/Support/Endian.h2
-rw-r--r--include/llvm/Support/Errc.h86
-rw-r--r--include/llvm/Support/ErrorHandling.h5
-rw-r--r--include/llvm/Support/ErrorOr.h42
-rw-r--r--include/llvm/Support/FEnv.h56
-rw-r--r--include/llvm/Support/FileOutputBuffer.h10
-rw-r--r--include/llvm/Support/FileSystem.h237
-rw-r--r--include/llvm/Support/Format.h102
-rw-r--r--include/llvm/Support/GenericDomTree.h4
-rw-r--r--include/llvm/Support/GraphWriter.h2
-rw-r--r--include/llvm/Support/LockFileManager.h5
-rw-r--r--include/llvm/Support/MachO.h23
-rw-r--r--include/llvm/Support/ManagedStatic.h3
-rw-r--r--include/llvm/Support/MathExtras.h9
-rw-r--r--include/llvm/Support/Memory.h10
-rw-r--r--include/llvm/Support/MemoryBuffer.h52
-rw-r--r--include/llvm/Support/Process.h11
-rw-r--r--include/llvm/Support/Program.h7
-rw-r--r--include/llvm/Support/RandomNumberGenerator.h57
-rw-r--r--include/llvm/Support/ScaledNumber.h897
-rw-r--r--include/llvm/Support/SourceMgr.h122
-rw-r--r--include/llvm/Support/SpecialCaseList.h96
-rw-r--r--include/llvm/Support/StreamableMemoryObject.h7
-rw-r--r--include/llvm/Support/StringPool.h7
-rw-r--r--include/llvm/Support/SwapByteOrder.h31
-rw-r--r--include/llvm/Support/TargetRegistry.h27
-rw-r--r--include/llvm/Support/Threading.h29
-rw-r--r--include/llvm/Support/WindowsError.h19
-rw-r--r--include/llvm/Support/YAMLTraits.h8
-rw-r--r--include/llvm/Support/system_error.h901
-rw-r--r--include/llvm/TableGen/SetTheory.h142
-rw-r--r--include/llvm/Target/Target.td5
-rw-r--r--include/llvm/Target/TargetFrameLowering.h13
-rw-r--r--include/llvm/Target/TargetInstrInfo.h18
-rw-r--r--include/llvm/Target/TargetLowering.h70
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h6
-rw-r--r--include/llvm/Target/TargetOptions.h17
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h6
-rw-r--r--include/llvm/Target/TargetSelectionDAGInfo.h2
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h16
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h1
-rw-r--r--include/llvm/Transforms/Instrumentation.h12
-rw-r--r--include/llvm/Transforms/Scalar.h7
-rw-r--r--include/llvm/Transforms/Utils/Local.h2
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h4
-rw-r--r--include/llvm/Transforms/Utils/SpecialCaseList.h114
-rw-r--r--include/llvm/Transforms/Utils/VectorUtils.h15
199 files changed, 5437 insertions, 4580 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index f37e3f8..8693a30 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -166,7 +166,8 @@ typedef enum {
LLVMCold = 1ULL << 34,
LLVMOptimizeNone = 1ULL << 35,
LLVMInAllocaAttribute = 1ULL << 36,
- LLVMNonNullAttribute = 1ULL << 37
+ LLVMNonNullAttribute = 1ULL << 37,
+ LLVMJumpTableAttribute = 1ULL << 38,
*/
} LLVMAttribute;
@@ -2847,16 +2848,13 @@ void LLVMDisposePassManager(LLVMPassManagerRef PM);
* @{
*/
-/** Allocate and initialize structures needed to make LLVM safe for
- multithreading. The return value indicates whether multithreaded
- initialization succeeded. Must be executed in isolation from all
- other LLVM api calls.
- @see llvm::llvm_start_multithreaded */
+/** Deprecated: Multi-threading can only be enabled/disabled with the compile
+ time define LLVM_ENABLE_THREADS. This function always returns
+ LLVMIsMultithreaded(). */
LLVMBool LLVMStartMultithreaded(void);
-/** Deallocate structures necessary to make LLVM safe for multithreading.
- Must be executed in isolation from all other LLVM api calls.
- @see llvm::llvm_stop_multithreaded */
+/** Deprecated: Multi-threading can only be enabled/disabled with the compile
+ time define LLVM_ENABLE_THREADS. */
void LLVMStopMultithreaded(void);
/** Check whether LLVM is executing in thread-safe mode or not.
diff --git a/include/llvm-c/module.modulemap b/include/llvm-c/module.modulemap
index 2bcdbc1..a456119 100644
--- a/include/llvm-c/module.modulemap
+++ b/include/llvm-c/module.modulemap
@@ -1,5 +1,4 @@
module LLVM_C {
- requires cplusplus
umbrella "."
module * { export * }
}
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index 053deff..ee34e9b 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -56,7 +56,7 @@ public:
APInt::toString(Str, Radix, isSigned());
}
/// toString - Converts an APInt to a std::string. This is an inefficient
- /// method, your should prefer passing in a SmallString instead.
+ /// method; you should prefer passing in a SmallString instead.
std::string toString(unsigned Radix) const {
return APInt::toString(Radix, isSigned());
}
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
index 1b64fee..0fff505 100644
--- a/include/llvm/ADT/ArrayRef.h
+++ b/include/llvm/ADT/ArrayRef.h
@@ -147,6 +147,12 @@ namespace llvm {
return ArrayRef<T>(data()+N, M);
}
+ // \brief Drop the last \p N elements of the array.
+ ArrayRef<T> drop_back(unsigned N = 1) const {
+ assert(size() >= N && "Dropping more elements than exist");
+ return slice(0, size() - N);
+ }
+
/// @}
/// @name Operator Overloads
/// @{
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index da2b3ad..34e2284 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -34,6 +34,7 @@ class BitVector {
unsigned Capacity; // Size of allocated memory in BitWord.
public:
+ typedef unsigned size_type;
// Encapsulation of a single bit.
class reference {
friend class BitVector;
@@ -111,10 +112,10 @@ public:
bool empty() const { return Size == 0; }
/// size - Returns the number of bits in this bitvector.
- unsigned size() const { return Size; }
+ size_type size() const { return Size; }
/// count - Returns the number of bits which are set.
- unsigned count() const {
+ size_type count() const {
unsigned NumBits = 0;
for (unsigned i = 0; i < NumBitWords(size()); ++i)
if (sizeof(BitWord) == 4)
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 8269132..85f37b9 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -43,6 +43,7 @@ protected:
typedef std::pair<KeyT, ValueT> BucketT;
public:
+ typedef unsigned size_type;
typedef KeyT key_type;
typedef ValueT mapped_type;
typedef BucketT value_type;
@@ -70,7 +71,7 @@ public:
unsigned size() const { return getNumEntries(); }
/// Grow the densemap so that it has at least Size buckets. Does not shrink
- void resize(size_t Size) {
+ void resize(size_type Size) {
if (Size > getNumBuckets())
grow(Size);
}
@@ -99,10 +100,10 @@ public:
setNumTombstones(0);
}
- /// count - Return true if the specified key is in the map.
- bool count(const KeyT &Val) const {
+ /// Return 1 if the specified key is in the map, 0 otherwise.
+ size_type count(const KeyT &Val) const {
const BucketT *TheBucket;
- return LookupBucketFor(Val, TheBucket);
+ return LookupBucketFor(Val, TheBucket) ? 1 : 0;
}
iterator find(const KeyT &Val) {
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
index 1d8c39c..37a81b0 100644
--- a/include/llvm/ADT/DenseSet.h
+++ b/include/llvm/ADT/DenseSet.h
@@ -29,11 +29,12 @@ class DenseSet {
public:
typedef ValueT key_type;
typedef ValueT value_type;
+ typedef unsigned size_type;
explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {}
bool empty() const { return TheMap.empty(); }
- unsigned size() const { return TheMap.size(); }
+ size_type size() const { return TheMap.size(); }
size_t getMemorySize() const { return TheMap.getMemorySize(); }
/// Grow the DenseSet so that it has at least Size buckets. Will not shrink
@@ -44,7 +45,8 @@ public:
TheMap.clear();
}
- bool count(const ValueT &V) const {
+ /// Return 1 if the specified key is in the set, 0 otherwise.
+ size_type count(const ValueT &V) const {
return TheMap.count(V);
}
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
index 9b7ee85..14c5933 100644
--- a/include/llvm/ADT/FoldingSet.h
+++ b/include/llvm/ADT/FoldingSet.h
@@ -794,6 +794,14 @@ template<typename T> struct FoldingSetTrait<T*> {
ID.AddPointer(X);
}
};
+template <typename T1, typename T2>
+struct FoldingSetTrait<std::pair<T1, T2>> {
+ static inline void Profile(const std::pair<T1, T2> &P,
+ llvm::FoldingSetNodeID &ID) {
+ ID.Add(P.first);
+ ID.Add(P.second);
+ }
+};
} // End of namespace llvm.
#endif
diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h
index b11e3c1..abf02b8 100644
--- a/include/llvm/ADT/Hashing.h
+++ b/include/llvm/ADT/Hashing.h
@@ -152,7 +152,7 @@ inline uint64_t fetch64(const char *p) {
uint64_t result;
memcpy(&result, p, sizeof(result));
if (sys::IsBigEndianHost)
- return sys::SwapByteOrder(result);
+ sys::swapByteOrder(result);
return result;
}
@@ -160,7 +160,7 @@ inline uint32_t fetch32(const char *p) {
uint32_t result;
memcpy(&result, p, sizeof(result));
if (sys::IsBigEndianHost)
- return sys::SwapByteOrder(result);
+ sys::swapByteOrder(result);
return result;
}
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index cd1946c..f9df378 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -154,13 +154,13 @@ public:
}
template <class X>
- IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.getPtr()) {
+ IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.get()) {
S.Obj = 0;
}
template <class X>
IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S)
- : Obj(S.getPtr()) {
+ : Obj(S.get()) {
retain();
}
@@ -175,12 +175,9 @@ public:
T* operator->() const { return Obj; }
- T* getPtr() const { return Obj; }
+ T* get() const { return Obj; }
- typedef T* (IntrusiveRefCntPtr::*unspecified_bool_type) () const;
- operator unspecified_bool_type() const {
- return Obj ? &IntrusiveRefCntPtr::getPtr : nullptr;
- }
+ LLVM_EXPLICIT operator bool() const { return Obj; }
void swap(IntrusiveRefCntPtr& other) {
T* tmp = other.Obj;
@@ -206,42 +203,62 @@ public:
inline bool operator==(const IntrusiveRefCntPtr<T>& A,
const IntrusiveRefCntPtr<U>& B)
{
- return A.getPtr() == B.getPtr();
+ return A.get() == B.get();
}
template<class T, class U>
inline bool operator!=(const IntrusiveRefCntPtr<T>& A,
const IntrusiveRefCntPtr<U>& B)
{
- return A.getPtr() != B.getPtr();
+ return A.get() != B.get();
}
template<class T, class U>
inline bool operator==(const IntrusiveRefCntPtr<T>& A,
U* B)
{
- return A.getPtr() == B;
+ return A.get() == B;
}
template<class T, class U>
inline bool operator!=(const IntrusiveRefCntPtr<T>& A,
U* B)
{
- return A.getPtr() != B;
+ return A.get() != B;
}
template<class T, class U>
inline bool operator==(T* A,
const IntrusiveRefCntPtr<U>& B)
{
- return A == B.getPtr();
+ return A == B.get();
}
template<class T, class U>
inline bool operator!=(T* A,
const IntrusiveRefCntPtr<U>& B)
{
- return A != B.getPtr();
+ return A != B.get();
+ }
+
+ template <class T>
+ bool operator==(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) {
+ return !B;
+ }
+
+ template <class T>
+ bool operator==(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
+ return B == A;
+ }
+
+ template <class T>
+ bool operator!=(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) {
+ return !(A == B);
+ }
+
+ template <class T>
+ bool operator!=(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
+ return !(A == B);
}
//===----------------------------------------------------------------------===//
@@ -251,14 +268,14 @@ public:
template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
typedef T* SimpleType;
static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) {
- return Val.getPtr();
+ return Val.get();
}
};
template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
typedef /*const*/ T* SimpleType;
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
- return Val.getPtr();
+ return Val.get();
}
};
diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h
index 7fd1570..2eae22c 100644
--- a/include/llvm/ADT/MapVector.h
+++ b/include/llvm/ADT/MapVector.h
@@ -29,7 +29,7 @@ template<typename KeyT, typename ValueT,
typename MapType = llvm::DenseMap<KeyT, unsigned>,
typename VectorType = std::vector<std::pair<KeyT, ValueT> > >
class MapVector {
- typedef typename VectorType::size_type SizeType;
+ typedef typename VectorType::size_type size_type;
MapType Map;
VectorType Vector;
@@ -38,7 +38,7 @@ public:
typedef typename VectorType::iterator iterator;
typedef typename VectorType::const_iterator const_iterator;
- SizeType size() const {
+ size_type size() const {
return Vector.size();
}
@@ -100,7 +100,7 @@ public:
return std::make_pair(begin() + I, false);
}
- unsigned count(const KeyT &Key) const {
+ size_type count(const KeyT &Key) const {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? 0 : 1;
}
@@ -123,6 +123,15 @@ public:
Map.erase(Pos);
Vector.pop_back();
}
+
+ /// \brief Remove the element given by Iterator.
+ /// Returns an iterator to the element following the one which was removed,
+ /// which may be end().
+ typename VectorType::iterator erase(typename VectorType::iterator Iterator) {
+ typename MapType::iterator MapIterator = Map.find(Iterator->first);
+ Map.erase(MapIterator);
+ return Vector.erase(Iterator);
+ }
};
}
diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h
deleted file mode 100644
index 5e83358..0000000
--- a/include/llvm/ADT/OwningPtr.h
+++ /dev/null
@@ -1,165 +0,0 @@
-//===- llvm/ADT/OwningPtr.h - Smart ptr that owns the pointee ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines and implements the OwningPtr class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ADT_OWNINGPTR_H
-#define LLVM_ADT_OWNINGPTR_H
-
-#include "llvm/Support/Compiler.h"
-#include <cassert>
-#include <cstddef>
-#include <memory>
-
-namespace llvm {
-
-/// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it
-/// guarantees deletion of the object pointed to, either on destruction of the
-/// OwningPtr or via an explicit reset(). Once created, ownership of the
-/// pointee object can be taken away from OwningPtr by using the take method.
-template<class T>
-class OwningPtr {
- OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION;
- OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION;
- T *Ptr;
-public:
- explicit OwningPtr(T *P = 0) : Ptr(P) {}
-
- OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
-
- OwningPtr &operator=(OwningPtr &&Other) {
- reset(Other.take());
- return *this;
- }
-
- OwningPtr(std::unique_ptr<T> Other) : Ptr(Other.release()) {}
-
- OwningPtr &operator=(std::unique_ptr<T> Other) {
- reset(Other.release());
- return *this;
- }
-
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
- operator std::unique_ptr<T>() && { return std::unique_ptr<T>(take()); }
-#endif
-
- ~OwningPtr() {
- delete Ptr;
- }
-
- /// reset - Change the current pointee to the specified pointer. Note that
- /// calling this with any pointer (including a null pointer) deletes the
- /// current pointer.
- void reset(T *P = 0) {
- if (P == Ptr) return;
- T *Tmp = Ptr;
- Ptr = P;
- delete Tmp;
- }
-
- /// take - Reset the owning pointer to null and return its pointer. This does
- /// not delete the pointer before returning it.
- T *take() {
- T *Tmp = Ptr;
- Ptr = nullptr;
- return Tmp;
- }
-
- T *release() { return take(); }
-
- std::unique_ptr<T> take_unique() { return std::unique_ptr<T>(take()); }
-
- T &operator*() const {
- assert(Ptr && "Cannot dereference null pointer");
- return *Ptr;
- }
-
- T *operator->() const { return Ptr; }
- T *get() const { return Ptr; }
- LLVM_EXPLICIT operator bool() const { return Ptr != nullptr; }
- bool operator!() const { return Ptr == nullptr; }
- bool isValid() const { return Ptr != nullptr; }
-
- void swap(OwningPtr &RHS) {
- T *Tmp = RHS.Ptr;
- RHS.Ptr = Ptr;
- Ptr = Tmp;
- }
-};
-
-template<class T>
-inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
- a.swap(b);
-}
-
-/// OwningArrayPtr smart pointer - OwningArrayPtr provides the same
-/// functionality as OwningPtr, except that it works for array types.
-template<class T>
-class OwningArrayPtr {
- OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
- OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
- T *Ptr;
-public:
- explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
-
- OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
-
- OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
- reset(Other.take());
- return *this;
- }
-
- ~OwningArrayPtr() {
- delete [] Ptr;
- }
-
- /// reset - Change the current pointee to the specified pointer. Note that
- /// calling this with any pointer (including a null pointer) deletes the
- /// current pointer.
- void reset(T *P = 0) {
- if (P == Ptr) return;
- T *Tmp = Ptr;
- Ptr = P;
- delete [] Tmp;
- }
-
- /// take - Reset the owning pointer to null and return its pointer. This does
- /// not delete the pointer before returning it.
- T *take() {
- T *Tmp = Ptr;
- Ptr = 0;
- return Tmp;
- }
-
- T &operator[](std::ptrdiff_t i) const {
- assert(Ptr && "Cannot dereference null pointer");
- return Ptr[i];
- }
-
- T *get() const { return Ptr; }
- LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
- bool operator!() const { return Ptr == nullptr; }
-
- void swap(OwningArrayPtr &RHS) {
- T *Tmp = RHS.Ptr;
- RHS.Ptr = Ptr;
- Ptr = Tmp;
- }
-};
-
-template<class T>
-inline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) {
- a.swap(b);
-}
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h
index 3cc7738..02a6ea3 100644
--- a/include/llvm/ADT/ScopedHashTable.h
+++ b/include/llvm/ADT/ScopedHashTable.h
@@ -148,6 +148,7 @@ 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;
+ typedef unsigned size_type;
private:
typedef ScopedHashTableVal<K, V> ValTy;
DenseMap<K, ValTy*, KInfo> TopLevelMap;
@@ -170,7 +171,8 @@ public:
AllocatorTy &getAllocator() { return Allocator; }
const AllocatorTy &getAllocator() const { return Allocator; }
- bool count(const K &Key) const {
+ /// Return 1 if the specified key is in the table, 0 otherwise.
+ size_type count(const K &Key) const {
return TopLevelMap.count(Key);
}
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index e965bc4..0922017 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -54,6 +54,7 @@ class SmallBitVector {
};
public:
+ typedef unsigned size_type;
// Encapsulation of a single bit.
class reference {
SmallBitVector &TheVector;
@@ -173,7 +174,7 @@ public:
}
/// count - Returns the number of bits which are set.
- unsigned count() const {
+ size_type count() const {
if (isSmall()) {
uintptr_t Bits = getSmallBits();
if (NumBaseBits == 32)
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index 67104f3..74f3fd4 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -73,8 +73,9 @@ protected:
~SmallPtrSetImplBase();
public:
+ typedef unsigned size_type;
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return size() == 0; }
- unsigned size() const { return NumElements; }
+ size_type size() const { return NumElements; }
void clear() {
// If the capacity of the array is huge, and the # elements used is small,
@@ -263,7 +264,7 @@ public:
}
/// count - Return 1 if the specified pointer is in the set, 0 otherwise.
- unsigned count(PtrType Ptr) const {
+ size_type count(PtrType Ptr) const {
return count_imp(PtrTraits::getAsVoidPointer(Ptr)) ? 1 : 0;
}
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
index 6f36234..bb1971e 100644
--- a/include/llvm/ADT/SmallSet.h
+++ b/include/llvm/ADT/SmallSet.h
@@ -37,18 +37,19 @@ class SmallSet {
typedef typename SmallVector<T, N>::const_iterator VIterator;
typedef typename SmallVector<T, N>::iterator mutable_iterator;
public:
+ typedef size_t size_type;
SmallSet() {}
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
return Vector.empty() && Set.empty();
}
- unsigned size() const {
+ size_type size() const {
return isSmall() ? Vector.size() : Set.size();
}
/// count - Return 1 if the element is in the set, 0 otherwise.
- unsigned count(const T &V) const {
+ size_type count(const T &V) const {
if (isSmall()) {
// Since the collection is small, just do a linear search.
return vfind(V) == Vector.end() ? 0 : 1;
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index dcf0354..82538e9 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -380,7 +380,8 @@ public:
} else if (N > this->size()) {
if (this->capacity() < N)
this->grow(N);
- std::uninitialized_fill(this->end(), this->begin()+N, T());
+ for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
+ new (&*I) T();
this->setEnd(this->begin()+N);
}
}
@@ -488,9 +489,9 @@ public:
}
::new ((void*) this->end()) T(::std::move(this->back()));
- this->setEnd(this->end()+1);
// Push everything else over.
this->move_backward(I, this->end()-1, this->end());
+ this->setEnd(this->end()+1);
// If we just moved the element we're inserting, be sure to update
// the reference.
@@ -516,10 +517,10 @@ public:
this->grow();
I = this->begin()+EltNo;
}
- ::new ((void*) this->end()) T(this->back());
- this->setEnd(this->end()+1);
+ ::new ((void*) this->end()) T(std::move(this->back()));
// Push everything else over.
this->move_backward(I, this->end()-1, this->end());
+ this->setEnd(this->end()+1);
// If we just moved the element we're inserting, be sure to update
// the reference.
@@ -555,7 +556,8 @@ public:
// reallocate the vector.
if (size_t(this->end()-I) >= NumToInsert) {
T *OldEnd = this->end();
- append(this->end()-NumToInsert, this->end());
+ append(std::move_iterator<iterator>(this->end() - NumToInsert),
+ std::move_iterator<iterator>(this->end()));
// Copy the existing elements that get replaced.
this->move_backward(I, OldEnd-NumToInsert, OldEnd);
@@ -608,7 +610,8 @@ public:
// reallocate the vector.
if (size_t(this->end()-I) >= NumToInsert) {
T *OldEnd = this->end();
- append(this->end()-NumToInsert, this->end());
+ append(std::move_iterator<iterator>(this->end() - NumToInsert),
+ std::move_iterator<iterator>(this->end()));
// Copy the existing elements that get replaced.
this->move_backward(I, OldEnd-NumToInsert, OldEnd);
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
index 706f248..36754d6 100644
--- a/include/llvm/ADT/SparseBitVector.h
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -45,6 +45,7 @@ struct SparseBitVectorElement
: public ilist_node<SparseBitVectorElement<ElementSize> > {
public:
typedef unsigned long BitWord;
+ typedef unsigned size_type;
enum {
BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
@@ -120,7 +121,7 @@ public:
return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
}
- unsigned count() const {
+ size_type count() const {
unsigned NumBits = 0;
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
if (sizeof(BitWord) == 4)
diff --git a/include/llvm/ADT/SparseMultiSet.h b/include/llvm/ADT/SparseMultiSet.h
index d2b2f8d..dc1273e 100644
--- a/include/llvm/ADT/SparseMultiSet.h
+++ b/include/llvm/ADT/SparseMultiSet.h
@@ -185,6 +185,7 @@ public:
typedef const ValueT &const_reference;
typedef ValueT *pointer;
typedef const ValueT *const_pointer;
+ typedef unsigned size_type;
SparseMultiSet()
: Sparse(nullptr), Universe(0), FreelistIdx(SMSNode::INVALID), NumFree(0) {}
@@ -327,7 +328,7 @@ public:
/// This is not the same as BitVector::size() which returns the size of the
/// universe.
///
- unsigned size() const {
+ size_type size() const {
assert(NumFree <= Dense.size() && "Out-of-bounds free entries");
return Dense.size() - NumFree;
}
@@ -378,7 +379,7 @@ public:
/// Returns the number of elements identified by Key. This will be linear in
/// the number of elements of that key.
- unsigned count(const KeyT &Key) const {
+ size_type count(const KeyT &Key) const {
unsigned Ret = 0;
for (const_iterator It = find(Key); It != end(); ++It)
++Ret;
diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h
index 899f2e4..632d52a 100644
--- a/include/llvm/ADT/SparseSet.h
+++ b/include/llvm/ADT/SparseSet.h
@@ -124,6 +124,7 @@ class SparseSet {
typedef typename KeyFunctorT::argument_type KeyT;
typedef SmallVector<ValueT, 8> DenseT;
+ typedef unsigned size_type;
DenseT Dense;
SparseT *Sparse;
unsigned Universe;
@@ -186,7 +187,7 @@ public:
/// This is not the same as BitVector::size() which returns the size of the
/// universe.
///
- unsigned size() const { return Dense.size(); }
+ size_type size() const { return Dense.size(); }
/// clear - Clears the set. This is a very fast constant time operation.
///
@@ -231,7 +232,7 @@ public:
/// count - Returns 1 if this set contains an element identified by Key,
/// 0 otherwise.
///
- unsigned count(const KeyT &Key) const {
+ size_type count(const KeyT &Key) const {
return find(Key) == end() ? 0 : 1;
}
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index ecac5dd..c40e5e2 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -64,7 +64,7 @@ protected:
}
StringMapImpl(unsigned InitSize, unsigned ItemSize);
- void RehashTable();
+ unsigned RehashTable(unsigned BucketNo = 0);
/// LookupBucketFor - Look up the bucket that the specified string should end
/// up in. If it already exists as a key in the map, the Item pointer for the
@@ -139,10 +139,10 @@ public:
/// Create - Create a StringMapEntry for the specified key and default
/// construct the value.
template<typename AllocatorTy, typename InitType>
- static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
+ static StringMapEntry *Create(StringRef Key,
AllocatorTy &Allocator,
InitType InitVal) {
- unsigned KeyLength = static_cast<unsigned>(KeyEnd-KeyStart);
+ unsigned KeyLength = Key.size();
// Allocate a new item with space for the string at the end and a null
// terminator.
@@ -158,27 +158,25 @@ public:
// Copy the string information.
char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
- memcpy(StrBuffer, KeyStart, KeyLength);
+ memcpy(StrBuffer, Key.data(), KeyLength);
StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients.
return NewItem;
}
template<typename AllocatorTy>
- static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
- AllocatorTy &Allocator) {
- return Create(KeyStart, KeyEnd, Allocator, 0);
+ static StringMapEntry *Create(StringRef Key, AllocatorTy &Allocator) {
+ return Create(Key, Allocator, ValueTy());
}
/// Create - Create a StringMapEntry with normal malloc/free.
template<typename InitType>
- static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
- InitType InitVal) {
+ static StringMapEntry *Create(StringRef Key, InitType InitVal) {
MallocAllocator A;
- return Create(KeyStart, KeyEnd, A, std::move(InitVal));
+ return Create(Key, A, std::move(InitVal));
}
- static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd) {
- return Create(KeyStart, KeyEnd, ValueTy());
+ static StringMapEntry *Create(StringRef Key) {
+ return Create(Key, ValueTy());
}
/// GetStringMapEntryFromValue - Given a value that is known to be embedded
@@ -325,6 +323,28 @@ public:
return true;
}
+ /// insert - Inserts the specified key/value pair into the map if the key
+ /// isn't already in the map. The bool component of the returned pair is true
+ /// if and only if the insertion takes place, and the iterator component of
+ /// the pair points to the element with key equivalent to the key of the pair.
+ std::pair<iterator, bool> insert(std::pair<StringRef, ValueTy> KV) {
+ unsigned BucketNo = LookupBucketFor(KV.first);
+ StringMapEntryBase *&Bucket = TheTable[BucketNo];
+ if (Bucket && Bucket != getTombstoneVal())
+ return std::make_pair(iterator(TheTable + BucketNo, false),
+ false); // Already exists in map.
+
+ if (Bucket == getTombstoneVal())
+ --NumTombstones;
+ Bucket =
+ MapEntryTy::Create(KV.first, Allocator, std::move(KV.second));
+ ++NumItems;
+ assert(NumItems + NumTombstones <= NumBuckets);
+
+ BucketNo = RehashTable(BucketNo);
+ return std::make_pair(iterator(TheTable + BucketNo, false), true);
+ }
+
// clear - Empties out the StringMap
void clear() {
if (empty()) return;
@@ -348,25 +368,7 @@ public:
/// return.
template <typename InitTy>
MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) {
- unsigned BucketNo = LookupBucketFor(Key);
- StringMapEntryBase *&Bucket = TheTable[BucketNo];
- if (Bucket && Bucket != getTombstoneVal())
- return *static_cast<MapEntryTy*>(Bucket);
-
- MapEntryTy *NewItem =
- MapEntryTy::Create(Key.begin(), Key.end(), Allocator, std::move(Val));
-
- if (Bucket == getTombstoneVal())
- --NumTombstones;
- ++NumItems;
- assert(NumItems + NumTombstones <= NumBuckets);
-
- // Fill in the bucket for the hash table. The FullHashValue was already
- // filled in by LookupBucketFor.
- Bucket = NewItem;
-
- RehashTable();
- return *NewItem;
+ return *insert(std::make_pair(Key, std::move(Val))).first;
}
MapEntryTy &GetOrCreateValue(StringRef Key) {
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 95f3380..2867a0e 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -76,7 +76,8 @@ public:
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
amdil, // amdil: amd IL
spir, // SPIR: standard portable IR for OpenCL 32-bit version
- spir64 // SPIR: standard portable IR for OpenCL 64-bit version
+ spir64, // SPIR: standard portable IR for OpenCL 64-bit version
+ kalimba // Kalimba: generic kalimba
};
enum VendorType {
UnknownVendor,
@@ -88,7 +89,9 @@ public:
BGQ,
Freescale,
IBM,
- NVIDIA
+ ImaginationTechnologies,
+ NVIDIA,
+ CSR
};
enum OSType {
UnknownOS,
@@ -350,6 +353,10 @@ public:
return getOS() == Triple::Win32 && getEnvironment() == Triple::MSVC;
}
+ bool isWindowsItaniumEnvironment() const {
+ return getOS() == Triple::Win32 && getEnvironment() == Triple::Itanium;
+ }
+
bool isWindowsCygwinEnvironment() const {
return getOS() == Triple::Cygwin ||
(getOS() == Triple::Win32 && getEnvironment() == Triple::Cygnus);
diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h
index a54fd74..4be3ee6 100644
--- a/include/llvm/ADT/Twine.h
+++ b/include/llvm/ADT/Twine.h
@@ -182,6 +182,10 @@ namespace llvm {
assert(isValid() && "Invalid twine!");
}
+ /// Since the intended use of twines is as temporary objects, assignments
+ /// when concatenating might cause undefined behavior or stack corruptions
+ Twine &operator=(const Twine &Other) LLVM_DELETED_FUNCTION;
+
/// isNull - Check for the null twine.
bool isNull() const {
return getLHSKind() == NullKind;
diff --git a/include/llvm/ADT/UniqueVector.h b/include/llvm/ADT/UniqueVector.h
index 2d02d1c..a9cb2f5 100644
--- a/include/llvm/ADT/UniqueVector.h
+++ b/include/llvm/ADT/UniqueVector.h
@@ -22,13 +22,18 @@ namespace llvm {
/// class should have an implementation of operator== and of operator<.
/// Entries can be fetched using operator[] with the entry ID.
template<class T> class UniqueVector {
+public:
+ typedef typename std::vector<T> VectorType;
+ typedef typename VectorType::iterator iterator;
+ typedef typename VectorType::const_iterator const_iterator;
+
private:
// Map - Used to handle the correspondence of entry to ID.
std::map<T, unsigned> Map;
// Vector - ID ordered vector of entries. Entries can be indexed by ID - 1.
//
- std::vector<T> Vector;
+ VectorType Vector;
public:
/// insert - Append entry to the vector if it doesn't already exist. Returns
@@ -68,6 +73,18 @@ public:
return Vector[ID - 1];
}
+ /// \brief Return an iterator to the start of the vector.
+ iterator begin() { return Vector.begin(); }
+
+ /// \brief Return an iterator to the start of the vector.
+ const_iterator begin() const { return Vector.begin(); }
+
+ /// \brief Return an iterator to the end of the vector.
+ iterator end() { return Vector.end(); }
+
+ /// \brief Return an iterator to the end of the vector.
+ const_iterator end() const { return Vector.end(); }
+
/// size - Returns the number of entries in the vector.
///
size_t size() const { return Vector.size(); }
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index 8852866..79d52fc 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -274,6 +274,14 @@ public:
UnknownModRefBehavior = Anywhere | ModRef
};
+ /// Get the location associated with a pointer argument of a callsite.
+ /// The mask bits are set to indicate the allowed aliasing ModRef kinds.
+ /// Note that these mask bits do not necessarily account for the overall
+ /// behavior of the function, but rather only provide additional
+ /// per-argument information.
+ virtual Location getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
+ ModRefResult &Mask);
+
/// getModRefBehavior - Return the behavior when calling the given call site.
virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
index bd72d3e..7340801 100644
--- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -22,6 +22,7 @@
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ScaledNumber.h"
#include "llvm/Support/raw_ostream.h"
#include <deque>
#include <list>
@@ -32,676 +33,6 @@
//===----------------------------------------------------------------------===//
//
-// UnsignedFloat definition.
-//
-// TODO: Make this private to BlockFrequencyInfoImpl or delete.
-//
-//===----------------------------------------------------------------------===//
-namespace llvm {
-
-class UnsignedFloatBase {
-public:
- static const int32_t MaxExponent = 16383;
- static const int32_t MinExponent = -16382;
- static const int DefaultPrecision = 10;
-
- static void dump(uint64_t D, int16_t E, int Width);
- static raw_ostream &print(raw_ostream &OS, uint64_t D, int16_t E, int Width,
- unsigned Precision);
- static std::string toString(uint64_t D, int16_t E, int Width,
- unsigned Precision);
- static int countLeadingZeros32(uint32_t N) { return countLeadingZeros(N); }
- static int countLeadingZeros64(uint64_t N) { return countLeadingZeros(N); }
- static uint64_t getHalf(uint64_t N) { return (N >> 1) + (N & 1); }
-
- static std::pair<uint64_t, bool> splitSigned(int64_t N) {
- if (N >= 0)
- return std::make_pair(N, false);
- uint64_t Unsigned = N == INT64_MIN ? UINT64_C(1) << 63 : uint64_t(-N);
- return std::make_pair(Unsigned, true);
- }
- static int64_t joinSigned(uint64_t U, bool IsNeg) {
- if (U > uint64_t(INT64_MAX))
- return IsNeg ? INT64_MIN : INT64_MAX;
- return IsNeg ? -int64_t(U) : int64_t(U);
- }
-
- static int32_t extractLg(const std::pair<int32_t, int> &Lg) {
- return Lg.first;
- }
- static int32_t extractLgFloor(const std::pair<int32_t, int> &Lg) {
- return Lg.first - (Lg.second > 0);
- }
- static int32_t extractLgCeiling(const std::pair<int32_t, int> &Lg) {
- return Lg.first + (Lg.second < 0);
- }
-
- static std::pair<uint64_t, int16_t> divide64(uint64_t L, uint64_t R);
- static std::pair<uint64_t, int16_t> multiply64(uint64_t L, uint64_t R);
-
- static int compare(uint64_t L, uint64_t R, int Shift) {
- assert(Shift >= 0);
- assert(Shift < 64);
-
- uint64_t L_adjusted = L >> Shift;
- if (L_adjusted < R)
- return -1;
- if (L_adjusted > R)
- return 1;
-
- return L > L_adjusted << Shift ? 1 : 0;
- }
-};
-
-/// \brief Simple representation of an unsigned floating point.
-///
-/// UnsignedFloat is a unsigned floating point number. It uses simple
-/// saturation arithmetic, and every operation is well-defined for every value.
-///
-/// The number is split into a signed exponent and unsigned digits. The number
-/// represented is \c getDigits()*2^getExponent(). In this way, the digits are
-/// much like the mantissa in the x87 long double, but there is no canonical
-/// form, so the same number can be represented by many bit representations
-/// (it's always in "denormal" mode).
-///
-/// UnsignedFloat is templated on the underlying integer type for digits, which
-/// is expected to be one of uint64_t, uint32_t, uint16_t or uint8_t.
-///
-/// Unlike builtin floating point types, UnsignedFloat is portable.
-///
-/// Unlike APFloat, UnsignedFloat does not model architecture floating point
-/// behaviour (this should make it a little faster), and implements most
-/// operators (this makes it usable).
-///
-/// UnsignedFloat is totally ordered. However, there is no canonical form, so
-/// there are multiple representations of most scalars. E.g.:
-///
-/// UnsignedFloat(8u, 0) == UnsignedFloat(4u, 1)
-/// UnsignedFloat(4u, 1) == UnsignedFloat(2u, 2)
-/// UnsignedFloat(2u, 2) == UnsignedFloat(1u, 3)
-///
-/// UnsignedFloat implements most arithmetic operations. Precision is kept
-/// where possible. Uses simple saturation arithmetic, so that operations
-/// saturate to 0.0 or getLargest() rather than under or overflowing. It has
-/// some extra arithmetic for unit inversion. 0.0/0.0 is defined to be 0.0.
-/// Any other division by 0.0 is defined to be getLargest().
-///
-/// As a convenience for modifying the exponent, left and right shifting are
-/// both implemented, and both interpret negative shifts as positive shifts in
-/// the opposite direction.
-///
-/// Exponents are limited to the range accepted by x87 long double. This makes
-/// it trivial to add functionality to convert to APFloat (this is already
-/// relied on for the implementation of printing).
-///
-/// The current plan is to gut this and make the necessary parts of it (even
-/// more) private to BlockFrequencyInfo.
-template <class DigitsT> class UnsignedFloat : UnsignedFloatBase {
-public:
- static_assert(!std::numeric_limits<DigitsT>::is_signed,
- "only unsigned floats supported");
-
- typedef DigitsT DigitsType;
-
-private:
- typedef std::numeric_limits<DigitsType> DigitsLimits;
-
- static const int Width = sizeof(DigitsType) * 8;
- static_assert(Width <= 64, "invalid integer width for digits");
-
-private:
- DigitsType Digits;
- int16_t Exponent;
-
-public:
- UnsignedFloat() : Digits(0), Exponent(0) {}
-
- UnsignedFloat(DigitsType Digits, int16_t Exponent)
- : Digits(Digits), Exponent(Exponent) {}
-
-private:
- UnsignedFloat(const std::pair<uint64_t, int16_t> &X)
- : Digits(X.first), Exponent(X.second) {}
-
-public:
- static UnsignedFloat getZero() { return UnsignedFloat(0, 0); }
- static UnsignedFloat getOne() { return UnsignedFloat(1, 0); }
- static UnsignedFloat getLargest() {
- return UnsignedFloat(DigitsLimits::max(), MaxExponent);
- }
- static UnsignedFloat getFloat(uint64_t N) { return adjustToWidth(N, 0); }
- static UnsignedFloat getInverseFloat(uint64_t N) {
- return getFloat(N).invert();
- }
- static UnsignedFloat getFraction(DigitsType N, DigitsType D) {
- return getQuotient(N, D);
- }
-
- int16_t getExponent() const { return Exponent; }
- DigitsType getDigits() const { return Digits; }
-
- /// \brief Convert to the given integer type.
- ///
- /// Convert to \c IntT using simple saturating arithmetic, truncating if
- /// necessary.
- template <class IntT> IntT toInt() const;
-
- bool isZero() const { return !Digits; }
- bool isLargest() const { return *this == getLargest(); }
- bool isOne() const {
- if (Exponent > 0 || Exponent <= -Width)
- return false;
- return Digits == DigitsType(1) << -Exponent;
- }
-
- /// \brief The log base 2, rounded.
- ///
- /// Get the lg of the scalar. lg 0 is defined to be INT32_MIN.
- int32_t lg() const { return extractLg(lgImpl()); }
-
- /// \brief The log base 2, rounded towards INT32_MIN.
- ///
- /// Get the lg floor. lg 0 is defined to be INT32_MIN.
- int32_t lgFloor() const { return extractLgFloor(lgImpl()); }
-
- /// \brief The log base 2, rounded towards INT32_MAX.
- ///
- /// Get the lg ceiling. lg 0 is defined to be INT32_MIN.
- int32_t lgCeiling() const { return extractLgCeiling(lgImpl()); }
-
- bool operator==(const UnsignedFloat &X) const { return compare(X) == 0; }
- bool operator<(const UnsignedFloat &X) const { return compare(X) < 0; }
- bool operator!=(const UnsignedFloat &X) const { return compare(X) != 0; }
- bool operator>(const UnsignedFloat &X) const { return compare(X) > 0; }
- bool operator<=(const UnsignedFloat &X) const { return compare(X) <= 0; }
- bool operator>=(const UnsignedFloat &X) const { return compare(X) >= 0; }
-
- bool operator!() const { return isZero(); }
-
- /// \brief Convert to a decimal representation in a string.
- ///
- /// Convert to a string. Uses scientific notation for very large/small
- /// numbers. Scientific notation is used roughly for numbers outside of the
- /// range 2^-64 through 2^64.
- ///
- /// \c Precision indicates the number of decimal digits of precision to use;
- /// 0 requests the maximum available.
- ///
- /// As a special case to make debugging easier, if the number is small enough
- /// to convert without scientific notation and has more than \c Precision
- /// digits before the decimal place, it's printed accurately to the first
- /// digit past zero. E.g., assuming 10 digits of precision:
- ///
- /// 98765432198.7654... => 98765432198.8
- /// 8765432198.7654... => 8765432198.8
- /// 765432198.7654... => 765432198.8
- /// 65432198.7654... => 65432198.77
- /// 5432198.7654... => 5432198.765
- std::string toString(unsigned Precision = DefaultPrecision) {
- return UnsignedFloatBase::toString(Digits, Exponent, Width, Precision);
- }
-
- /// \brief Print a decimal representation.
- ///
- /// Print a string. See toString for documentation.
- raw_ostream &print(raw_ostream &OS,
- unsigned Precision = DefaultPrecision) const {
- return UnsignedFloatBase::print(OS, Digits, Exponent, Width, Precision);
- }
- void dump() const { return UnsignedFloatBase::dump(Digits, Exponent, Width); }
-
- UnsignedFloat &operator+=(const UnsignedFloat &X);
- UnsignedFloat &operator-=(const UnsignedFloat &X);
- UnsignedFloat &operator*=(const UnsignedFloat &X);
- UnsignedFloat &operator/=(const UnsignedFloat &X);
- UnsignedFloat &operator<<=(int16_t Shift) { shiftLeft(Shift); return *this; }
- UnsignedFloat &operator>>=(int16_t Shift) { shiftRight(Shift); return *this; }
-
-private:
- void shiftLeft(int32_t Shift);
- void shiftRight(int32_t Shift);
-
- /// \brief Adjust two floats to have matching exponents.
- ///
- /// Adjust \c this and \c X to have matching exponents. Returns the new \c X
- /// by value. Does nothing if \a isZero() for either.
- ///
- /// The value that compares smaller will lose precision, and possibly become
- /// \a isZero().
- UnsignedFloat matchExponents(UnsignedFloat X);
-
- /// \brief Increase exponent to match another float.
- ///
- /// Increases \c this to have an exponent matching \c X. May decrease the
- /// exponent of \c X in the process, and \c this may possibly become \a
- /// isZero().
- void increaseExponentToMatch(UnsignedFloat &X, int32_t ExponentDiff);
-
-public:
- /// \brief Scale a large number accurately.
- ///
- /// Scale N (multiply it by this). Uses full precision multiplication, even
- /// if Width is smaller than 64, so information is not lost.
- uint64_t scale(uint64_t N) const;
- uint64_t scaleByInverse(uint64_t N) const {
- // TODO: implement directly, rather than relying on inverse. Inverse is
- // expensive.
- return inverse().scale(N);
- }
- int64_t scale(int64_t N) const {
- std::pair<uint64_t, bool> Unsigned = splitSigned(N);
- return joinSigned(scale(Unsigned.first), Unsigned.second);
- }
- int64_t scaleByInverse(int64_t N) const {
- std::pair<uint64_t, bool> Unsigned = splitSigned(N);
- return joinSigned(scaleByInverse(Unsigned.first), Unsigned.second);
- }
-
- int compare(const UnsignedFloat &X) const;
- int compareTo(uint64_t N) const {
- UnsignedFloat Float = getFloat(N);
- int Compare = compare(Float);
- if (Width == 64 || Compare != 0)
- return Compare;
-
- // Check for precision loss. We know *this == RoundTrip.
- uint64_t RoundTrip = Float.template toInt<uint64_t>();
- return N == RoundTrip ? 0 : RoundTrip < N ? -1 : 1;
- }
- int compareTo(int64_t N) const { return N < 0 ? 1 : compareTo(uint64_t(N)); }
-
- UnsignedFloat &invert() { return *this = UnsignedFloat::getFloat(1) / *this; }
- UnsignedFloat inverse() const { return UnsignedFloat(*this).invert(); }
-
-private:
- static UnsignedFloat getProduct(DigitsType L, DigitsType R);
- static UnsignedFloat getQuotient(DigitsType Dividend, DigitsType Divisor);
-
- std::pair<int32_t, int> lgImpl() const;
- static int countLeadingZerosWidth(DigitsType Digits) {
- if (Width == 64)
- return countLeadingZeros64(Digits);
- if (Width == 32)
- return countLeadingZeros32(Digits);
- return countLeadingZeros32(Digits) + Width - 32;
- }
-
- static UnsignedFloat adjustToWidth(uint64_t N, int32_t S) {
- assert(S >= MinExponent);
- assert(S <= MaxExponent);
- if (Width == 64 || N <= DigitsLimits::max())
- return UnsignedFloat(N, S);
-
- // Shift right.
- int Shift = 64 - Width - countLeadingZeros64(N);
- DigitsType Shifted = N >> Shift;
-
- // Round.
- assert(S + Shift <= MaxExponent);
- return getRounded(UnsignedFloat(Shifted, S + Shift),
- N & UINT64_C(1) << (Shift - 1));
- }
-
- static UnsignedFloat getRounded(UnsignedFloat P, bool Round) {
- if (!Round)
- return P;
- if (P.Digits == DigitsLimits::max())
- // Careful of overflow in the exponent.
- return UnsignedFloat(1, P.Exponent) <<= Width;
- return UnsignedFloat(P.Digits + 1, P.Exponent);
- }
-};
-
-#define UNSIGNED_FLOAT_BOP(op, base) \
- template <class DigitsT> \
- UnsignedFloat<DigitsT> operator op(const UnsignedFloat<DigitsT> &L, \
- const UnsignedFloat<DigitsT> &R) { \
- return UnsignedFloat<DigitsT>(L) base R; \
- }
-UNSIGNED_FLOAT_BOP(+, += )
-UNSIGNED_FLOAT_BOP(-, -= )
-UNSIGNED_FLOAT_BOP(*, *= )
-UNSIGNED_FLOAT_BOP(/, /= )
-UNSIGNED_FLOAT_BOP(<<, <<= )
-UNSIGNED_FLOAT_BOP(>>, >>= )
-#undef UNSIGNED_FLOAT_BOP
-
-template <class DigitsT>
-raw_ostream &operator<<(raw_ostream &OS, const UnsignedFloat<DigitsT> &X) {
- return X.print(OS, 10);
-}
-
-#define UNSIGNED_FLOAT_COMPARE_TO_TYPE(op, T1, T2) \
- template <class DigitsT> \
- bool operator op(const UnsignedFloat<DigitsT> &L, T1 R) { \
- return L.compareTo(T2(R)) op 0; \
- } \
- template <class DigitsT> \
- bool operator op(T1 L, const UnsignedFloat<DigitsT> &R) { \
- return 0 op R.compareTo(T2(L)); \
- }
-#define UNSIGNED_FLOAT_COMPARE_TO(op) \
- UNSIGNED_FLOAT_COMPARE_TO_TYPE(op, uint64_t, uint64_t) \
- UNSIGNED_FLOAT_COMPARE_TO_TYPE(op, uint32_t, uint64_t) \
- UNSIGNED_FLOAT_COMPARE_TO_TYPE(op, int64_t, int64_t) \
- UNSIGNED_FLOAT_COMPARE_TO_TYPE(op, int32_t, int64_t)
-UNSIGNED_FLOAT_COMPARE_TO(< )
-UNSIGNED_FLOAT_COMPARE_TO(> )
-UNSIGNED_FLOAT_COMPARE_TO(== )
-UNSIGNED_FLOAT_COMPARE_TO(!= )
-UNSIGNED_FLOAT_COMPARE_TO(<= )
-UNSIGNED_FLOAT_COMPARE_TO(>= )
-#undef UNSIGNED_FLOAT_COMPARE_TO
-#undef UNSIGNED_FLOAT_COMPARE_TO_TYPE
-
-template <class DigitsT>
-uint64_t UnsignedFloat<DigitsT>::scale(uint64_t N) const {
- if (Width == 64 || N <= DigitsLimits::max())
- return (getFloat(N) * *this).template toInt<uint64_t>();
-
- // Defer to the 64-bit version.
- return UnsignedFloat<uint64_t>(Digits, Exponent).scale(N);
-}
-
-template <class DigitsT>
-UnsignedFloat<DigitsT> UnsignedFloat<DigitsT>::getProduct(DigitsType L,
- DigitsType R) {
- // Check for zero.
- if (!L || !R)
- return getZero();
-
- // Check for numbers that we can compute with 64-bit math.
- if (Width <= 32 || (L <= UINT32_MAX && R <= UINT32_MAX))
- return adjustToWidth(uint64_t(L) * uint64_t(R), 0);
-
- // Do the full thing.
- return UnsignedFloat(multiply64(L, R));
-}
-template <class DigitsT>
-UnsignedFloat<DigitsT> UnsignedFloat<DigitsT>::getQuotient(DigitsType Dividend,
- DigitsType Divisor) {
- // Check for zero.
- if (!Dividend)
- return getZero();
- if (!Divisor)
- return getLargest();
-
- if (Width == 64)
- return UnsignedFloat(divide64(Dividend, Divisor));
-
- // We can compute this with 64-bit math.
- int Shift = countLeadingZeros64(Dividend);
- uint64_t Shifted = uint64_t(Dividend) << Shift;
- uint64_t Quotient = Shifted / Divisor;
-
- // If Quotient needs to be shifted, then adjustToWidth will round.
- if (Quotient > DigitsLimits::max())
- return adjustToWidth(Quotient, -Shift);
-
- // Round based on the value of the next bit.
- return getRounded(UnsignedFloat(Quotient, -Shift),
- Shifted % Divisor >= getHalf(Divisor));
-}
-
-template <class DigitsT>
-template <class IntT>
-IntT UnsignedFloat<DigitsT>::toInt() const {
- typedef std::numeric_limits<IntT> Limits;
- if (*this < 1)
- return 0;
- if (*this >= Limits::max())
- return Limits::max();
-
- IntT N = Digits;
- if (Exponent > 0) {
- assert(size_t(Exponent) < sizeof(IntT) * 8);
- return N << Exponent;
- }
- if (Exponent < 0) {
- assert(size_t(-Exponent) < sizeof(IntT) * 8);
- return N >> -Exponent;
- }
- return N;
-}
-
-template <class DigitsT>
-std::pair<int32_t, int> UnsignedFloat<DigitsT>::lgImpl() const {
- if (isZero())
- return std::make_pair(INT32_MIN, 0);
-
- // Get the floor of the lg of Digits.
- int32_t LocalFloor = Width - countLeadingZerosWidth(Digits) - 1;
-
- // Get the floor of the lg of this.
- int32_t Floor = Exponent + LocalFloor;
- if (Digits == UINT64_C(1) << LocalFloor)
- return std::make_pair(Floor, 0);
-
- // Round based on the next digit.
- assert(LocalFloor >= 1);
- bool Round = Digits & UINT64_C(1) << (LocalFloor - 1);
- return std::make_pair(Floor + Round, Round ? 1 : -1);
-}
-
-template <class DigitsT>
-UnsignedFloat<DigitsT> UnsignedFloat<DigitsT>::matchExponents(UnsignedFloat X) {
- if (isZero() || X.isZero() || Exponent == X.Exponent)
- return X;
-
- int32_t Diff = int32_t(X.Exponent) - int32_t(Exponent);
- if (Diff > 0)
- increaseExponentToMatch(X, Diff);
- else
- X.increaseExponentToMatch(*this, -Diff);
- return X;
-}
-template <class DigitsT>
-void UnsignedFloat<DigitsT>::increaseExponentToMatch(UnsignedFloat &X,
- int32_t ExponentDiff) {
- assert(ExponentDiff > 0);
- if (ExponentDiff >= 2 * Width) {
- *this = getZero();
- return;
- }
-
- // Use up any leading zeros on X, and then shift this.
- int32_t ShiftX = std::min(countLeadingZerosWidth(X.Digits), ExponentDiff);
- assert(ShiftX < Width);
-
- int32_t ShiftThis = ExponentDiff - ShiftX;
- if (ShiftThis >= Width) {
- *this = getZero();
- return;
- }
-
- X.Digits <<= ShiftX;
- X.Exponent -= ShiftX;
- Digits >>= ShiftThis;
- Exponent += ShiftThis;
- return;
-}
-
-template <class DigitsT>
-UnsignedFloat<DigitsT> &UnsignedFloat<DigitsT>::
-operator+=(const UnsignedFloat &X) {
- if (isLargest() || X.isZero())
- return *this;
- if (isZero() || X.isLargest())
- return *this = X;
-
- // Normalize exponents.
- UnsignedFloat Scaled = matchExponents(X);
-
- // Check for zero again.
- if (isZero())
- return *this = Scaled;
- if (Scaled.isZero())
- return *this;
-
- // Compute sum.
- DigitsType Sum = Digits + Scaled.Digits;
- bool DidOverflow = Sum < Digits;
- Digits = Sum;
- if (!DidOverflow)
- return *this;
-
- if (Exponent == MaxExponent)
- return *this = getLargest();
-
- ++Exponent;
- Digits = UINT64_C(1) << (Width - 1) | Digits >> 1;
-
- return *this;
-}
-template <class DigitsT>
-UnsignedFloat<DigitsT> &UnsignedFloat<DigitsT>::
-operator-=(const UnsignedFloat &X) {
- if (X.isZero())
- return *this;
- if (*this <= X)
- return *this = getZero();
-
- // Normalize exponents.
- UnsignedFloat Scaled = matchExponents(X);
- assert(Digits >= Scaled.Digits);
-
- // Compute difference.
- if (!Scaled.isZero()) {
- Digits -= Scaled.Digits;
- return *this;
- }
-
- // Check if X just barely lost its last bit. E.g., for 32-bit:
- //
- // 1*2^32 - 1*2^0 == 0xffffffff != 1*2^32
- if (*this == UnsignedFloat(1, X.lgFloor() + Width)) {
- Digits = DigitsType(0) - 1;
- --Exponent;
- }
- return *this;
-}
-template <class DigitsT>
-UnsignedFloat<DigitsT> &UnsignedFloat<DigitsT>::
-operator*=(const UnsignedFloat &X) {
- if (isZero())
- return *this;
- if (X.isZero())
- return *this = X;
-
- // Save the exponents.
- int32_t Exponents = int32_t(Exponent) + int32_t(X.Exponent);
-
- // Get the raw product.
- *this = getProduct(Digits, X.Digits);
-
- // Combine with exponents.
- return *this <<= Exponents;
-}
-template <class DigitsT>
-UnsignedFloat<DigitsT> &UnsignedFloat<DigitsT>::
-operator/=(const UnsignedFloat &X) {
- if (isZero())
- return *this;
- if (X.isZero())
- return *this = getLargest();
-
- // Save the exponents.
- int32_t Exponents = int32_t(Exponent) - int32_t(X.Exponent);
-
- // Get the raw quotient.
- *this = getQuotient(Digits, X.Digits);
-
- // Combine with exponents.
- return *this <<= Exponents;
-}
-template <class DigitsT>
-void UnsignedFloat<DigitsT>::shiftLeft(int32_t Shift) {
- if (!Shift || isZero())
- return;
- assert(Shift != INT32_MIN);
- if (Shift < 0) {
- shiftRight(-Shift);
- return;
- }
-
- // Shift as much as we can in the exponent.
- int32_t ExponentShift = std::min(Shift, MaxExponent - Exponent);
- Exponent += ExponentShift;
- if (ExponentShift == Shift)
- return;
-
- // Check this late, since it's rare.
- if (isLargest())
- return;
-
- // Shift the digits themselves.
- Shift -= ExponentShift;
- if (Shift > countLeadingZerosWidth(Digits)) {
- // Saturate.
- *this = getLargest();
- return;
- }
-
- Digits <<= Shift;
- return;
-}
-
-template <class DigitsT>
-void UnsignedFloat<DigitsT>::shiftRight(int32_t Shift) {
- if (!Shift || isZero())
- return;
- assert(Shift != INT32_MIN);
- if (Shift < 0) {
- shiftLeft(-Shift);
- return;
- }
-
- // Shift as much as we can in the exponent.
- int32_t ExponentShift = std::min(Shift, Exponent - MinExponent);
- Exponent -= ExponentShift;
- if (ExponentShift == Shift)
- return;
-
- // Shift the digits themselves.
- Shift -= ExponentShift;
- if (Shift >= Width) {
- // Saturate.
- *this = getZero();
- return;
- }
-
- Digits >>= Shift;
- return;
-}
-
-template <class DigitsT>
-int UnsignedFloat<DigitsT>::compare(const UnsignedFloat &X) const {
- // Check for zero.
- if (isZero())
- return X.isZero() ? 0 : -1;
- if (X.isZero())
- return 1;
-
- // Check for the scale. Use lgFloor to be sure that the exponent difference
- // is always lower than 64.
- int32_t lgL = lgFloor(), lgR = X.lgFloor();
- if (lgL != lgR)
- return lgL < lgR ? -1 : 1;
-
- // Compare digits.
- if (Exponent < X.Exponent)
- return UnsignedFloatBase::compare(Digits, X.Digits, X.Exponent - Exponent);
-
- return -UnsignedFloatBase::compare(X.Digits, Digits, Exponent - X.Exponent);
-}
-
-template <class T> struct isPodLike<UnsignedFloat<T>> {
- static const bool value = true;
-};
-}
-
-//===----------------------------------------------------------------------===//
-//
// BlockMass definition.
//
// TODO: Make this private to BlockFrequencyInfoImpl or delete.
@@ -770,11 +101,11 @@ public:
bool operator<(const BlockMass &X) const { return Mass < X.Mass; }
bool operator>(const BlockMass &X) const { return Mass > X.Mass; }
- /// \brief Convert to floating point.
+ /// \brief Convert to scaled number.
///
- /// Convert to a float. \a isFull() gives 1.0, while \a isEmpty() gives
- /// slightly above 0.0.
- UnsignedFloat<uint64_t> toFloat() const;
+ /// Convert to \a ScaledNumber. \a isFull() gives 1.0, while \a isEmpty()
+ /// gives slightly above 0.0.
+ ScaledNumber<uint64_t> toScaled() const;
void dump() const;
raw_ostream &print(raw_ostream &OS) const;
@@ -837,7 +168,7 @@ template <class BT> struct BlockEdgesAdder;
/// BlockFrequencyInfoImpl. See there for details.
class BlockFrequencyInfoImplBase {
public:
- typedef UnsignedFloat<uint64_t> Float;
+ typedef ScaledNumber<uint64_t> Scaled64;
/// \brief Representative of a block.
///
@@ -866,7 +197,7 @@ public:
/// \brief Stats about a block itself.
struct FrequencyData {
- Float Floating;
+ Scaled64 Scaled;
uint64_t Integer;
};
@@ -884,7 +215,7 @@ public:
NodeList Nodes; ///< Header and the members of the loop.
BlockMass BackedgeMass; ///< Mass returned to loop header.
BlockMass Mass;
- Float Scale;
+ Scaled64 Scale;
LoopData(LoopData *Parent, const BlockNode &Header)
: Parent(Parent), IsPackaged(false), NumHeaders(1), Nodes(1, Header) {}
@@ -1131,7 +462,7 @@ public:
virtual raw_ostream &print(raw_ostream &OS) const { return OS; }
void dump() const { print(dbgs()); }
- Float getFloatingBlockFreq(const BlockNode &Node) const;
+ Scaled64 getFloatingBlockFreq(const BlockNode &Node) const;
BlockFrequency getBlockFreq(const BlockNode &Node) const;
@@ -1310,7 +641,7 @@ void IrreducibleGraph::addEdges(const BlockNode &Node,
/// entries point to this block. Its successors are the headers, which split
/// the frequency evenly.
///
-/// This algorithm leverages BlockMass and UnsignedFloat to maintain precision,
+/// This algorithm leverages BlockMass and ScaledNumber to maintain precision,
/// separates mass distribution from loop scaling, and dithers to eliminate
/// probability mass loss.
///
@@ -1568,7 +899,7 @@ public:
BlockFrequency getBlockFreq(const BlockT *BB) const {
return BlockFrequencyInfoImplBase::getBlockFreq(getNode(BB));
}
- Float getFloatingBlockFreq(const BlockT *BB) const {
+ Scaled64 getFloatingBlockFreq(const BlockT *BB) const {
return BlockFrequencyInfoImplBase::getFloatingBlockFreq(getNode(BB));
}
diff --git a/include/llvm/Analysis/JumpInstrTableInfo.h b/include/llvm/Analysis/JumpInstrTableInfo.h
new file mode 100644
index 0000000..54760aa
--- /dev/null
+++ b/include/llvm/Analysis/JumpInstrTableInfo.h
@@ -0,0 +1,60 @@
+//===-- JumpInstrTableInfo.h: Info for Jump-Instruction Tables --*- C++ -*-===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Information about jump-instruction tables that have been created by
+/// JumpInstrTables pass.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H
+#define LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Pass.h"
+
+#include <vector>
+
+namespace llvm {
+class Function;
+class FunctionType;
+
+/// This class stores information about jump-instruction tables created by the
+/// JumpInstrTables pass (in lib/CodeGen/JumpInstrTables.cpp). Each table is a
+/// map from a function type to a vector of pairs. The first element of each
+/// pair is the function that has the jumptable annotation. The second element
+/// is a function that was declared by JumpInstrTables and used to replace all
+/// address-taking sites for the original function.
+///
+/// The information in this pass is used in AsmPrinter
+/// (lib/CodeGen/AsmPrinter/AsmPrinter.cpp) to generate the required assembly
+/// for the jump-instruction tables.
+class JumpInstrTableInfo : public ImmutablePass {
+public:
+ static char ID;
+
+ JumpInstrTableInfo();
+ virtual ~JumpInstrTableInfo();
+ const char *getPassName() const override {
+ return "Jump-Instruction Table Info";
+ }
+
+ typedef std::pair<Function *, Function *> JumpPair;
+ typedef DenseMap<FunctionType *, std::vector<JumpPair> > JumpTables;
+
+ /// Inserts an entry in a table, adding the table if it doesn't exist.
+ void insertEntry(FunctionType *TableFunTy, Function *Target, Function *Jump);
+
+ /// Gets the tables.
+ const JumpTables &getTables() const { return Tables; }
+
+private:
+ JumpTables Tables;
+};
+}
+
+#endif /* LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H */
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
index 9494b7d..fd65ae5 100644
--- a/include/llvm/Analysis/Passes.h
+++ b/include/llvm/Analysis/Passes.h
@@ -142,6 +142,10 @@ namespace llvm {
// information and prints it with -analyze.
//
FunctionPass *createMemDepPrinter();
+
+ // createJumpInstrTableInfoPass - This creates a pass that stores information
+ // about the jump tables created by JumpInstrTables
+ ImmutablePass *createJumpInstrTableInfoPass();
}
#endif
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index 82a788d..93a1a48 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -22,6 +22,16 @@
// itself is not, but in practice runtime seems to be in the order of magnitude
// of dominance tree calculation.
//
+// WARNING: LLVM is generally very concerned about compile time such that
+// the use of additional analysis passes in the default
+// optimization sequence is avoided as much as possible.
+// Specifically, if you do not need the RegionInfo, but dominance
+// information could be sufficient please base your work only on
+// the dominator tree. Most passes maintain it, such that using
+// it has often near zero cost. In contrast RegionInfo is by
+// default not available, is not maintained by existing
+// transformations and there is no intention to do so.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGIONINFO_H
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index 79fe1dc..f57f3eb 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -322,6 +322,7 @@ public:
enum ShuffleKind {
SK_Broadcast, ///< Broadcast element 0 to all other elements.
SK_Reverse, ///< Reverse the order of the vector.
+ SK_Alternate, ///< Choose alternate elements from vector.
SK_InsertSubvector, ///< InsertSubvector. Index indicates start offset.
SK_ExtractSubvector ///< ExtractSubvector Index indicates start offset.
};
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index ce78967..83b5408 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -37,7 +37,10 @@ namespace llvm {
/// for all of the elements in the vector.
void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
const DataLayout *TD = nullptr, unsigned Depth = 0);
- void computeKnownBitsLoad(const MDNode &Ranges, APInt &KnownZero);
+ /// Compute known bits from the range metadata.
+ /// \p KnownZero the set of bits that are known to be zero
+ void computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
+ APInt &KnownZero);
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
/// one. Convenience wrapper around computeKnownBits.
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index 04c08ab..f7e30ef 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -71,7 +71,8 @@ namespace bitc {
// MODULE_CODE_PURGEVALS: [numvals]
MODULE_CODE_PURGEVALS = 10,
- MODULE_CODE_GCNAME = 11 // GCNAME: [strchr x N]
+ MODULE_CODE_GCNAME = 11, // GCNAME: [strchr x N]
+ MODULE_CODE_COMDAT = 12, // COMDAT: [selection_kind, name]
};
/// PARAMATTR blocks have code for defining a parameter attribute set.
@@ -372,7 +373,16 @@ namespace bitc {
ATTR_KIND_COLD = 36,
ATTR_KIND_OPTIMIZE_NONE = 37,
ATTR_KIND_IN_ALLOCA = 38,
- ATTR_KIND_NON_NULL = 39
+ ATTR_KIND_NON_NULL = 39,
+ ATTR_KIND_JUMP_TABLE = 40
+ };
+
+ enum ComdatSelectionKindCodes {
+ COMDAT_SELECTION_KIND_ANY = 1,
+ COMDAT_SELECTION_KIND_EXACT_MATCH = 2,
+ COMDAT_SELECTION_KIND_LARGEST = 3,
+ COMDAT_SELECTION_KIND_NO_DUPLICATES = 4,
+ COMDAT_SELECTION_KIND_SAME_SIZE = 5,
};
} // End bitc namespace
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h
index 4c194a6..8cf5735 100644
--- a/include/llvm/Bitcode/ReaderWriter.h
+++ b/include/llvm/Bitcode/ReaderWriter.h
@@ -41,14 +41,11 @@ namespace llvm {
LLVMContext &Context,
std::string *ErrMsg = nullptr);
- /// getBitcodeTargetTriple - Read the header of the specified bitcode
- /// buffer and extract just the triple information. If successful,
- /// this returns a string and *does not* take ownership
- /// of 'buffer'. On error, this returns "", and fills in *ErrMsg
- /// if ErrMsg is non-null.
+ /// Read the header of the specified bitcode buffer and extract just the
+ /// triple information. If successful, this returns a string and *does not*
+ /// take ownership of 'buffer'. On error, this returns "".
std::string getBitcodeTargetTriple(MemoryBuffer *Buffer,
- LLVMContext &Context,
- std::string *ErrMsg = nullptr);
+ LLVMContext &Context);
/// Read the specified bitcode file, returning the module.
/// This method *never* takes ownership of Buffer.
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h
index c3aefd4..c5060fb 100644
--- a/include/llvm/CodeGen/Analysis.h
+++ b/include/llvm/CodeGen/Analysis.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares several CodeGen-specific LLVM IR analysis utilties.
+// This file declares several CodeGen-specific LLVM IR analysis utilities.
//
//===----------------------------------------------------------------------===//
@@ -86,7 +86,7 @@ ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred);
/// between it and the return.
///
/// This function only tests target-independent requirements.
-bool isInTailCallPosition(ImmutableCallSite CS, const TargetLowering &TLI);
+bool isInTailCallPosition(ImmutableCallSite CS, const SelectionDAG &DAG);
/// Test if given that the input instruction is in the tail call position if the
/// return type or any attributes of the function will inhibit tail call
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index b53fb42..e1c9a14 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -52,7 +52,6 @@ class MCSubtargetInfo;
class MCSymbol;
class MDNode;
class DwarfDebug;
-class DwarfException;
class Mangler;
class TargetLoweringObjectFile;
class DataLayout;
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
index 2956ad8..449d934 100644
--- a/include/llvm/CodeGen/CommandFlags.h
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -202,6 +202,21 @@ FunctionSections("function-sections",
cl::desc("Emit functions into separate sections"),
cl::init(false));
+cl::opt<llvm::JumpTable::JumpTableType>
+JTableType("jump-table-type",
+ cl::desc("Choose the type of Jump-Instruction Table for jumptable."),
+ cl::init(JumpTable::Single),
+ cl::values(
+ clEnumValN(JumpTable::Single, "single",
+ "Create a single table for all jumptable functions"),
+ clEnumValN(JumpTable::Arity, "arity",
+ "Create one table per number of parameters."),
+ clEnumValN(JumpTable::Simplified, "simplified",
+ "Create one table per simplified function type."),
+ clEnumValN(JumpTable::Full, "full",
+ "Create one table per unique function type."),
+ clEnumValEnd));
+
// Common utility function tightly tied to the options listed here. Initializes
// a TargetOptions object with CodeGen flags and returns it.
static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
@@ -228,6 +243,7 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
Options.FunctionSections = FunctionSections;
Options.MCOptions = InitMCTargetOptionsFromFlags();
+ Options.JTType = JTableType;
return Options;
}
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index bfeede2..2bebae6 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -23,6 +23,7 @@ namespace llvm {
class AllocaInst;
class Constant;
class ConstantFP;
+class CallInst;
class DataLayout;
class FunctionLoweringInfo;
class Instruction;
@@ -48,6 +49,7 @@ class FastISel {
protected:
DenseMap<const Value *, unsigned> LocalValueMap;
FunctionLoweringInfo &FuncInfo;
+ MachineFunction *MF;
MachineRegisterInfo &MRI;
MachineFrameInfo &MFI;
MachineConstantPool &MCP;
@@ -373,6 +375,12 @@ protected:
/// - \c Add has a constant operand.
bool canFoldAddIntoGEP(const User *GEP, const Value *Add);
+ /// Test whether the given value has exactly one use.
+ bool hasTrivialKill(const Value *V) const;
+
+ /// \brief Create a machine mem operand from the given instruction.
+ MachineMemOperand *createMachineMemOperandFor(const Instruction *I) const;
+
private:
bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
@@ -380,6 +388,7 @@ private:
bool SelectGetElementPtr(const User *I);
+ bool SelectStackmap(const CallInst *I);
bool SelectCall(const User *I);
bool SelectBitCast(const User *I);
@@ -409,8 +418,8 @@ private:
/// heavy instructions like calls.
void flushLocalValueMap();
- /// Test whether the given value has exactly one use.
- bool hasTrivialKill(const Value *V) const;
+ bool addStackMapLiveVars(SmallVectorImpl<MachineOperand> &Ops,
+ const CallInst *CI, unsigned StartIdx);
};
}
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index 49891b2..a8f2368 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -379,6 +379,37 @@ namespace ISD {
/// operand, a ValueType node.
SIGN_EXTEND_INREG,
+ /// ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an
+ /// in-register any-extension of the low lanes of an integer vector. The
+ /// result type must have fewer elements than the operand type, and those
+ /// elements must be larger integer types such that the total size of the
+ /// operand type and the result type match. Each of the low operand
+ /// elements is any-extended into the corresponding, wider result
+ /// elements with the high bits becoming undef.
+ ANY_EXTEND_VECTOR_INREG,
+
+ /// SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an
+ /// in-register sign-extension of the low lanes of an integer vector. The
+ /// result type must have fewer elements than the operand type, and those
+ /// elements must be larger integer types such that the total size of the
+ /// operand type and the result type match. Each of the low operand
+ /// elements is sign-extended into the corresponding, wider result
+ /// elements.
+ // FIXME: The SIGN_EXTEND_INREG node isn't specifically limited to
+ // scalars, but it also doesn't handle vectors well. Either it should be
+ // restricted to scalars or this node (and its handling) should be merged
+ // into it.
+ SIGN_EXTEND_VECTOR_INREG,
+
+ /// ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an
+ /// in-register zero-extension of the low lanes of an integer vector. The
+ /// result type must have fewer elements than the operand type, and those
+ /// elements must be larger integer types such that the total size of the
+ /// operand type and the result type match. Each of the low operand
+ /// elements is zero-extended into the corresponding, wider result
+ /// elements.
+ ZERO_EXTEND_VECTOR_INREG,
+
/// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
/// integer.
FP_TO_SINT,
@@ -619,6 +650,12 @@ namespace ISD {
/// This corresponds to the cmpxchg instruction.
ATOMIC_CMP_SWAP,
+ /// Val, Success, OUTCHAIN
+ /// = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap)
+ /// N.b. this is still a strong cmpxchg operation, so
+ /// Success == "Val == cmp".
+ ATOMIC_CMP_SWAP_WITH_SUCCESS,
+
/// Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
/// Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
/// For double-word atomic operations:
diff --git a/include/llvm/CodeGen/JumpInstrTables.h b/include/llvm/CodeGen/JumpInstrTables.h
new file mode 100644
index 0000000..6ca3d7d
--- /dev/null
+++ b/include/llvm/CodeGen/JumpInstrTables.h
@@ -0,0 +1,104 @@
+//===-- JumpInstrTables.h: Jump-Instruction Tables --------------*- C++ -*-===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief An implementation of tables consisting of jump instructions
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_JUMPINSTRTABLES_H
+#define LLVM_CODEGEN_JUMPINSTRTABLES_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Pass.h"
+#include "llvm/Target/TargetOptions.h"
+
+namespace llvm {
+class Constant;
+class Function;
+class FunctionType;
+class JumpInstrTableInfo;
+class Module;
+
+/// A class to manage a set of jump tables indexed on function type. It looks at
+/// each function in the module to find all the functions that have the
+/// jumptable attribute set. For each such function, it creates a new
+/// jump-instruction-table function and stores the mapping in the ImmutablePass
+/// JumpInstrTableInfo.
+///
+/// These special functions get lowered in AsmPrinter to assembly of the form:
+/// \verbatim
+/// .globl f
+/// .type f,@function
+/// .align 8,0x90
+/// f:
+/// jmp f_orig@PLT
+/// \endverbatim
+///
+/// Support for an architecture depends on two functions in TargetInstrInfo:
+/// getUnconditionalBranch, and getTrap. AsmPrinter uses these to generate the
+/// appropriate instructions for the jump statement (an unconditional branch)
+/// and for padding to make the table have a size that is a power of two. This
+/// padding uses a trap instruction to ensure that calls to this area halt the
+/// program. The default implementations of these functions call
+/// llvm_unreachable.
+class JumpInstrTables : public ModulePass {
+public:
+ static char ID;
+
+ JumpInstrTables();
+ JumpInstrTables(JumpTable::JumpTableType JTT);
+ virtual ~JumpInstrTables();
+ bool runOnModule(Module &M) override;
+ const char *getPassName() const override { return "Jump-Instruction Tables"; }
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ /// Creates a jump-instruction table function for the Target and adds it to
+ /// the tables.
+ Function *insertEntry(Module &M, Function *Target);
+
+ /// Checks to see if there is already a table for the given FunctionType.
+ bool hasTable(FunctionType *FunTy);
+
+private:
+ /// The metadata used while a jump table is being built
+ struct TableMeta {
+ /// The number of this table
+ unsigned TableNum;
+
+ /// The current number of jump entries in the table.
+ unsigned Count;
+ };
+
+ typedef DenseMap<FunctionType *, struct TableMeta> JumpMap;
+
+ /// Maps the function into a subset of function types, depending on the
+ /// jump-instruction table style selected from JumpTableTypes in
+ /// JumpInstrTables.cpp. The choice of mapping determines the number of
+ /// jump-instruction tables generated by this pass. E.g., the simplest mapping
+ /// converts every function type into void f(); so, all functions end up in a
+ /// single table.
+ FunctionType *transformType(FunctionType *FunTy);
+
+ /// The current state of functions and jump entries in the table(s).
+ JumpMap Metadata;
+
+ /// The ImmutablePass that stores information about the generated tables.
+ JumpInstrTableInfo *JITI;
+
+ /// The total number of tables.
+ unsigned TableCount;
+
+ /// The type of tables to build.
+ JumpTable::JumpTableType JTType;
+};
+
+/// Creates a JumpInstrTables pass for the given type of jump table.
+ModulePass *createJumpInstrTablesPass(JumpTable::JumpTableType JTT);
+}
+
+#endif /* LLVM_CODEGEN_JUMPINSTRTABLES_H */
diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h
index 31d6872..036aea3 100644
--- a/include/llvm/CodeGen/LexicalScopes.h
+++ b/include/llvm/CodeGen/LexicalScopes.h
@@ -197,6 +197,9 @@ public:
/// dump - Print data structures to dbgs().
void dump();
+ /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
+ LexicalScope *getOrCreateAbstractScope(const MDNode *N);
+
private:
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
/// not available then create new lexical scope.
@@ -208,9 +211,6 @@ private:
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt);
- /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
- LexicalScope *getOrCreateAbstractScope(const MDNode *N);
-
/// extractLexicalScopes - Extract instruction ranges for each lexical scopes
/// for the given machine function.
void extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index ddd623c..176665b 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -155,6 +155,17 @@ namespace llvm {
bool shrinkToUses(LiveInterval *li,
SmallVectorImpl<MachineInstr*> *dead = nullptr);
+ /// \brief Walk the values in the given interval and compute which ones
+ /// are dead. Dead values are not deleted, however:
+ /// - Dead PHIDef values are marked as unused.
+ /// - New dead machine instructions are added to the dead vector.
+ /// - CanSeparate is set to true if the interval may have been separated
+ /// into multiple connected components.
+ void computeDeadValues(LiveInterval *li,
+ LiveRange &LR,
+ bool *CanSeparate,
+ SmallVectorImpl<MachineInstr*> *dead);
+
/// extendToIndices - Extend the live range of LI to reach all points in
/// Indices. The points in the Indices array must be jointly dominated by
/// existing defs in LI. PHI-defs are added as needed to maintain SSA form.
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 90bdeee4..a08cc2e 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -620,7 +620,7 @@ public:
/// computeRegisterLiveness - Return whether (physical) register \c Reg
/// has been <def>ined and not <kill>ed as of just before \c MI.
- ///
+ ///
/// Search is localised to a neighborhood of
/// \c Neighborhood instructions before (searching for defs or kills) and
/// Neighborhood instructions after (searching just for defs) MI.
@@ -635,7 +635,7 @@ public:
void print(raw_ostream &OS, SlotIndexes* = nullptr) const;
// Printing method used by LoopInfo.
- void printAsOperand(raw_ostream &OS, bool PrintType = true);
+ void printAsOperand(raw_ostream &OS, bool PrintType = true) const;
/// getNumber - MachineBasicBlocks are uniquely numbered at the function
/// level, unless they're not in a MachineFunction yet, in which case this
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index bd0ea11..c51f8fe 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -484,6 +484,9 @@ public:
///
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable);
+ /// CreateFixedSpillStackObject - Create a spill slot at a fixed location
+ /// on the stack. Returns an index with a negative value.
+ int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset);
/// isFixedObjectIndex - Returns true if the specified index corresponds to a
/// fixed stack object.
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index b0d3e02..3c82811 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -727,6 +727,9 @@ public:
bool isFullCopy() const {
return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg();
}
+ bool isExtractSubreg() const {
+ return getOpcode() == TargetOpcode::EXTRACT_SUBREG;
+ }
/// isCopyLike - Return true if the instruction behaves like a copy.
/// This does not include native copy instructions.
@@ -947,7 +950,7 @@ public:
}
/// isRegTiedToDefOperand - Return true if the use operand of the specified
- /// index is tied to an def operand. It also returns the def operand index by
+ /// index is tied to a def operand. It also returns the def operand index by
/// reference if DefOpIdx is not null.
bool isRegTiedToDefOperand(unsigned UseOpIdx,
unsigned *DefOpIdx = nullptr) const {
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
index acd37e1..7d85432 100644
--- a/include/llvm/CodeGen/MachineScheduler.h
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -518,9 +518,7 @@ public:
return Queue.begin() + idx;
}
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void dump();
-#endif
};
/// Summarize the unscheduled region.
@@ -624,9 +622,9 @@ private:
SmallVector<unsigned, 16> ReservedCycles;
#ifndef NDEBUG
- // Remember the greatest operand latency as an upper bound on the number of
+ // Remember the greatest possible stall as an upper bound on the number of
// times we should retry the pending queue because of a hazard.
- unsigned MaxObservedLatency;
+ unsigned MaxObservedStall;
#endif
public:
@@ -739,6 +737,217 @@ public:
#endif
};
+/// Base class for GenericScheduler. This class maintains information about
+/// scheduling candidates based on TargetSchedModel making it easy to implement
+/// heuristics for either preRA or postRA scheduling.
+class GenericSchedulerBase : public MachineSchedStrategy {
+public:
+ /// Represent the type of SchedCandidate found within a single queue.
+ /// pickNodeBidirectional depends on these listed by decreasing priority.
+ enum CandReason {
+ NoCand, PhysRegCopy, RegExcess, RegCritical, Stall, Cluster, Weak, RegMax,
+ ResourceReduce, ResourceDemand, BotHeightReduce, BotPathReduce,
+ TopDepthReduce, TopPathReduce, NextDefUse, NodeOrder};
+
+#ifndef NDEBUG
+ static const char *getReasonStr(GenericSchedulerBase::CandReason Reason);
+#endif
+
+ /// Policy for scheduling the next instruction in the candidate's zone.
+ struct CandPolicy {
+ bool ReduceLatency;
+ unsigned ReduceResIdx;
+ unsigned DemandResIdx;
+
+ CandPolicy(): ReduceLatency(false), ReduceResIdx(0), DemandResIdx(0) {}
+ };
+
+ /// Status of an instruction's critical resource consumption.
+ struct SchedResourceDelta {
+ // Count critical resources in the scheduled region required by SU.
+ unsigned CritResources;
+
+ // Count critical resources from another region consumed by SU.
+ unsigned DemandedResources;
+
+ SchedResourceDelta(): CritResources(0), DemandedResources(0) {}
+
+ bool operator==(const SchedResourceDelta &RHS) const {
+ return CritResources == RHS.CritResources
+ && DemandedResources == RHS.DemandedResources;
+ }
+ bool operator!=(const SchedResourceDelta &RHS) const {
+ return !operator==(RHS);
+ }
+ };
+
+ /// Store the state used by GenericScheduler heuristics, required for the
+ /// lifetime of one invocation of pickNode().
+ struct SchedCandidate {
+ CandPolicy Policy;
+
+ // The best SUnit candidate.
+ SUnit *SU;
+
+ // The reason for this candidate.
+ CandReason Reason;
+
+ // Set of reasons that apply to multiple candidates.
+ uint32_t RepeatReasonSet;
+
+ // Register pressure values for the best candidate.
+ RegPressureDelta RPDelta;
+
+ // Critical resource consumption of the best candidate.
+ SchedResourceDelta ResDelta;
+
+ SchedCandidate(const CandPolicy &policy)
+ : Policy(policy), SU(nullptr), Reason(NoCand), RepeatReasonSet(0) {}
+
+ bool isValid() const { return SU; }
+
+ // Copy the status of another candidate without changing policy.
+ void setBest(SchedCandidate &Best) {
+ assert(Best.Reason != NoCand && "uninitialized Sched candidate");
+ SU = Best.SU;
+ Reason = Best.Reason;
+ RPDelta = Best.RPDelta;
+ ResDelta = Best.ResDelta;
+ }
+
+ bool isRepeat(CandReason R) { return RepeatReasonSet & (1 << R); }
+ void setRepeat(CandReason R) { RepeatReasonSet |= (1 << R); }
+
+ void initResourceDelta(const ScheduleDAGMI *DAG,
+ const TargetSchedModel *SchedModel);
+ };
+
+protected:
+ const MachineSchedContext *Context;
+ const TargetSchedModel *SchedModel;
+ const TargetRegisterInfo *TRI;
+
+ SchedRemainder Rem;
+protected:
+ GenericSchedulerBase(const MachineSchedContext *C):
+ Context(C), SchedModel(nullptr), TRI(nullptr) {}
+
+ void setPolicy(CandPolicy &Policy, bool IsPostRA, SchedBoundary &CurrZone,
+ SchedBoundary *OtherZone);
+
+#ifndef NDEBUG
+ void traceCandidate(const SchedCandidate &Cand);
+#endif
+};
+
+/// GenericScheduler shrinks the unscheduled zone using heuristics to balance
+/// the schedule.
+class GenericScheduler : public GenericSchedulerBase {
+ ScheduleDAGMILive *DAG;
+
+ // State of the top and bottom scheduled instruction boundaries.
+ SchedBoundary Top;
+ SchedBoundary Bot;
+
+ MachineSchedPolicy RegionPolicy;
+public:
+ GenericScheduler(const MachineSchedContext *C):
+ GenericSchedulerBase(C), DAG(nullptr), Top(SchedBoundary::TopQID, "TopQ"),
+ Bot(SchedBoundary::BotQID, "BotQ") {}
+
+ void initPolicy(MachineBasicBlock::iterator Begin,
+ MachineBasicBlock::iterator End,
+ unsigned NumRegionInstrs) override;
+
+ bool shouldTrackPressure() const override {
+ return RegionPolicy.ShouldTrackPressure;
+ }
+
+ void initialize(ScheduleDAGMI *dag) override;
+
+ SUnit *pickNode(bool &IsTopNode) override;
+
+ void schedNode(SUnit *SU, bool IsTopNode) override;
+
+ void releaseTopNode(SUnit *SU) override {
+ Top.releaseTopNode(SU);
+ }
+
+ void releaseBottomNode(SUnit *SU) override {
+ Bot.releaseBottomNode(SU);
+ }
+
+ void registerRoots() override;
+
+protected:
+ void checkAcyclicLatency();
+
+ void tryCandidate(SchedCandidate &Cand,
+ SchedCandidate &TryCand,
+ SchedBoundary &Zone,
+ const RegPressureTracker &RPTracker,
+ RegPressureTracker &TempTracker);
+
+ SUnit *pickNodeBidirectional(bool &IsTopNode);
+
+ void pickNodeFromQueue(SchedBoundary &Zone,
+ const RegPressureTracker &RPTracker,
+ SchedCandidate &Candidate);
+
+ void reschedulePhysRegCopies(SUnit *SU, bool isTop);
+};
+
+/// PostGenericScheduler - Interface to the scheduling algorithm used by
+/// ScheduleDAGMI.
+///
+/// Callbacks from ScheduleDAGMI:
+/// initPolicy -> initialize(DAG) -> registerRoots -> pickNode ...
+class PostGenericScheduler : public GenericSchedulerBase {
+ ScheduleDAGMI *DAG;
+ SchedBoundary Top;
+ SmallVector<SUnit*, 8> BotRoots;
+public:
+ PostGenericScheduler(const MachineSchedContext *C):
+ GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ") {}
+
+ virtual ~PostGenericScheduler() {}
+
+ void initPolicy(MachineBasicBlock::iterator Begin,
+ MachineBasicBlock::iterator End,
+ unsigned NumRegionInstrs) override {
+ /* no configurable policy */
+ };
+
+ /// PostRA scheduling does not track pressure.
+ bool shouldTrackPressure() const override { return false; }
+
+ void initialize(ScheduleDAGMI *Dag) override;
+
+ void registerRoots() override;
+
+ SUnit *pickNode(bool &IsTopNode) override;
+
+ void scheduleTree(unsigned SubtreeID) override {
+ llvm_unreachable("PostRA scheduler does not support subtree analysis.");
+ }
+
+ void schedNode(SUnit *SU, bool IsTopNode) override;
+
+ void releaseTopNode(SUnit *SU) override {
+ Top.releaseTopNode(SU);
+ }
+
+ // Only called for roots.
+ void releaseBottomNode(SUnit *SU) override {
+ BotRoots.push_back(SU);
+ }
+
+protected:
+ void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand);
+
+ void pickNodeFromQueue(SchedCandidate &Cand);
+};
+
} // namespace llvm
#endif
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 35210f1..17477fe 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -588,6 +588,25 @@ namespace llvm {
/// the intrinsic for later emission to the StackMap.
extern char &StackMapLivenessID;
+ /// createJumpInstrTables - This pass creates jump-instruction tables.
+ ModulePass *createJumpInstrTablesPass();
} // End llvm namespace
+/// This initializer registers TargetMachine constructor, so the pass being
+/// initialized can use target dependent interfaces. Please do not move this
+/// macro to be together with INITIALIZE_PASS, which is a complete target
+/// independent initializer, and we don't want to make libScalarOpts depend
+/// on libCodeGen.
+#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \
+ static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
+ PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
+ PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis, \
+ PassInfo::TargetMachineCtor_t(callTargetMachineCtor< passName >)); \
+ Registry.registerPass(*PI, true); \
+ return PI; \
+ } \
+ void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+ CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+ }
+
#endif
diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h
index c11a6ac..cc9e000 100644
--- a/include/llvm/CodeGen/RegisterPressure.h
+++ b/include/llvm/CodeGen/RegisterPressure.h
@@ -434,10 +434,8 @@ protected:
void bumpDownwardPressure(const MachineInstr *MI);
};
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
const TargetRegisterInfo *TRI);
-#endif
} // end namespace llvm
#endif
diff --git a/include/llvm/CodeGen/ScheduleDFS.h b/include/llvm/CodeGen/ScheduleDFS.h
index 73ce99f..b2108ad 100644
--- a/include/llvm/CodeGen/ScheduleDFS.h
+++ b/include/llvm/CodeGen/ScheduleDFS.h
@@ -57,11 +57,9 @@ struct ILPValue {
return RHS <= *this;
}
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void print(raw_ostream &OS) const;
void dump() const;
-#endif
};
/// \brief Compute the values of each DAG node for various metrics during DFS.
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index d9c38c0..5effb82 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -151,8 +151,7 @@ public:
};
class SelectionDAG;
-void checkForCycles(const SDNode *N);
-void checkForCycles(const SelectionDAG *DAG);
+void checkForCycles(const SelectionDAG *DAG, bool force = false);
/// SelectionDAG class - This is used to represent a portion of an LLVM function
/// in a low-level Data Dependence DAG representation suitable for instruction
@@ -335,7 +334,7 @@ public:
assert((!N.getNode() || N.getValueType() == MVT::Other) &&
"DAG root value is not a chain!");
if (N.getNode())
- checkForCycles(N.getNode());
+ checkForCycles(N.getNode(), this);
Root = N;
if (N.getNode())
checkForCycles(this);
@@ -540,6 +539,12 @@ public:
/// undefined.
SDValue getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, SDValue N2,
const int *MaskElts);
+ SDValue getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, SDValue N2,
+ ArrayRef<int> MaskElts) {
+ assert(VT.getVectorNumElements() == MaskElts.size() &&
+ "Must have the same number of vector elements as mask elements!");
+ return getVectorShuffle(VT, dl, N1, N2, MaskElts.data());
+ }
/// getAnyExtOrTrunc - Convert Op, which must be of integer type, to the
/// integer type VT, by either any-extending or truncating it.
@@ -557,10 +562,28 @@ public:
/// value assuming it was the smaller SrcTy value.
SDValue getZeroExtendInReg(SDValue Op, SDLoc DL, EVT SrcTy);
+ /// getAnyExtendVectorInReg - Return an operation which will any-extend the
+ /// low lanes of the operand into the specified vector type. For example,
+ /// this can convert a v16i8 into a v4i32 by any-extending the low four
+ /// lanes of the operand from i8 to i32.
+ SDValue getAnyExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT);
+
+ /// getSignExtendVectorInReg - Return an operation which will sign extend the
+ /// low lanes of the operand into the specified vector type. For example,
+ /// this can convert a v16i8 into a v4i32 by sign extending the low four
+ /// lanes of the operand from i8 to i32.
+ SDValue getSignExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT);
+
+ /// getZeroExtendVectorInReg - Return an operation which will zero extend the
+ /// low lanes of the operand into the specified vector type. For example,
+ /// this can convert a v16i8 into a v4i32 by zero extending the low four
+ /// lanes of the operand from i8 to i32.
+ SDValue getZeroExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT);
+
/// getBoolExtOrTrunc - Convert Op, which must be of integer type, to the
/// integer type VT, by using an extension appropriate for the target's
- /// BooleanContent or truncating it.
- SDValue getBoolExtOrTrunc(SDValue Op, SDLoc SL, EVT VT);
+ /// BooleanContent for type OpVT or truncating it.
+ SDValue getBoolExtOrTrunc(SDValue Op, SDLoc SL, EVT VT, EVT OpVT);
/// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
SDValue getNOT(SDLoc DL, SDValue Val, EVT VT);
@@ -607,14 +630,14 @@ public:
///
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT);
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N);
- SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2);
- SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT,
- SDValue N1, SDValue N2, SDValue N3);
- SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT,
- SDValue N1, SDValue N2, SDValue N3, SDValue N4);
- SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT,
- SDValue N1, SDValue N2, SDValue N3, SDValue N4,
- SDValue N5);
+ SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2,
+ bool nuw = false, bool nsw = false, bool exact = false);
+ SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2,
+ SDValue N3);
+ SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2,
+ SDValue N3, SDValue N4);
+ SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2,
+ SDValue N3, SDValue N4, SDValue N5);
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, ArrayRef<SDUse> Ops);
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT,
ArrayRef<SDValue> Ops);
@@ -695,20 +718,22 @@ public:
SDValue getVAArg(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr,
SDValue SV, unsigned Align);
- /// getAtomic - Gets a node for an atomic op, produces result and chain and
- /// takes 3 operands
- SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDValue Chain,
- SDValue Ptr, SDValue Cmp, SDValue Swp,
- MachinePointerInfo PtrInfo, unsigned Alignment,
- AtomicOrdering SuccessOrdering,
- AtomicOrdering FailureOrdering,
- SynchronizationScope SynchScope);
- SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDValue Chain,
- SDValue Ptr, SDValue Cmp, SDValue Swp,
- MachineMemOperand *MMO,
- AtomicOrdering SuccessOrdering,
- AtomicOrdering FailureOrdering,
- SynchronizationScope SynchScope);
+ /// getAtomicCmpSwap - Gets a node for an atomic cmpxchg op. There are two
+ /// valid Opcodes. ISD::ATOMIC_CMO_SWAP produces a the value loaded and a
+ /// chain result. ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS produces the value loaded,
+ /// a success flag (initially i1), and a chain.
+ SDValue getAtomicCmpSwap(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTs,
+ SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp,
+ MachinePointerInfo PtrInfo, unsigned Alignment,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
+ SynchronizationScope SynchScope);
+ SDValue getAtomicCmpSwap(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTs,
+ SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp,
+ MachineMemOperand *MMO,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
+ SynchronizationScope SynchScope);
/// getAtomic - Gets a node for an atomic op, produces result (if relevant)
/// and chain and takes 2 operands.
@@ -922,7 +947,9 @@ public:
/// getNodeIfExists - Get the specified node if it's already available, or
/// else return NULL.
- SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, ArrayRef<SDValue> Ops);
+ SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, ArrayRef<SDValue> Ops,
+ bool nuw = false, bool nsw = false,
+ bool exact = false);
/// getDbgValue - Creates a SDDbgValue node.
///
@@ -1179,6 +1206,10 @@ private:
void allnodes_clear();
+ BinarySDNode *GetBinarySDNode(unsigned Opcode, SDLoc DL, SDVTList VTs,
+ SDValue N1, SDValue N2, bool nuw, bool nsw,
+ bool exact);
+
/// VTList - List of non-single value types.
FoldingSet<SDVTListNode> VTListMap;
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 4f0ddb7..2231511 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -20,6 +20,7 @@
#define LLVM_CODEGEN_SELECTIONDAGNODES_H
#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
@@ -49,7 +50,26 @@ template <typename T> struct DenseMapInfo;
template <typename T> struct simplify_type;
template <typename T> struct ilist_traits;
-void checkForCycles(const SDNode *N);
+/// isBinOpWithFlags - Returns true if the opcode is a binary operation
+/// with flags.
+static bool isBinOpWithFlags(unsigned Opcode) {
+ switch (Opcode) {
+ case ISD::SDIV:
+ case ISD::UDIV:
+ case ISD::SRA:
+ case ISD::SRL:
+ case ISD::MUL:
+ case ISD::ADD:
+ case ISD::SUB:
+ case ISD::SHL:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr,
+ bool force = false);
/// SDVTList - This represents a list of ValueType's that has been intern'd by
/// a SelectionDAG. Instances of this simple value class are returned by
@@ -123,6 +143,9 @@ public:
bool operator<(const SDValue &O) const {
return std::tie(Node, ResNo) < std::tie(O.Node, O.ResNo);
}
+ LLVM_EXPLICIT operator bool() const {
+ return Node != nullptr;
+ }
SDValue getValue(unsigned R) const {
return SDValue(Node, R);
@@ -574,6 +597,7 @@ public:
typedef SDUse* op_iterator;
op_iterator op_begin() const { return OperandList; }
op_iterator op_end() const { return OperandList+NumOperands; }
+ ArrayRef<SDUse> ops() const { return makeArrayRef(op_begin(), op_end()); }
SDVTList getVTList() const {
SDVTList X = { ValueList, NumValues };
@@ -938,6 +962,36 @@ public:
}
};
+/// BinaryWithFlagsSDNode - This class is an extension of BinarySDNode
+/// used from those opcodes that have associated extra flags.
+class BinaryWithFlagsSDNode : public BinarySDNode {
+ enum { NUW = (1 << 0), NSW = (1 << 1), EXACT = (1 << 2) };
+
+public:
+ BinaryWithFlagsSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,
+ SDValue X, SDValue Y)
+ : BinarySDNode(Opc, Order, dl, VTs, X, Y) {}
+ /// getRawSubclassData - Return the SubclassData value, which contains an
+ /// encoding of the flags.
+ /// This function should be used to add subclass data to the NodeID value.
+ unsigned getRawSubclassData() const { return SubclassData; }
+ void setHasNoUnsignedWrap(bool b) {
+ SubclassData = (SubclassData & ~NUW) | (b ? NUW : 0);
+ }
+ void setHasNoSignedWrap(bool b) {
+ SubclassData = (SubclassData & ~NSW) | (b ? NSW : 0);
+ }
+ void setIsExact(bool b) {
+ SubclassData = (SubclassData & ~EXACT) | (b ? EXACT : 0);
+ }
+ bool hasNoUnsignedWrap() const { return SubclassData & NUW; }
+ bool hasNoSignedWrap() const { return SubclassData & NSW; }
+ bool isExact() const { return SubclassData & EXACT; }
+ static bool classof(const SDNode *N) {
+ return isBinOpWithFlags(N->getOpcode());
+ }
+};
+
/// TernarySDNode - This class is used for three-operand SDNodes. This is solely
/// to allow co-allocation of node operands with the node itself.
class TernarySDNode : public SDNode {
@@ -1077,6 +1131,7 @@ public:
N->getOpcode() == ISD::STORE ||
N->getOpcode() == ISD::PREFETCH ||
N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
+ N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
N->getOpcode() == ISD::ATOMIC_SWAP ||
N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
@@ -1185,12 +1240,13 @@ public:
bool isCompareAndSwap() const {
unsigned Op = getOpcode();
- return Op == ISD::ATOMIC_CMP_SWAP;
+ return Op == ISD::ATOMIC_CMP_SWAP || Op == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS;
}
// Methods to support isa and dyn_cast
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
+ N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
N->getOpcode() == ISD::ATOMIC_SWAP ||
N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
@@ -1528,11 +1584,27 @@ public:
unsigned MinSplatBits = 0,
bool isBigEndian = false) const;
- /// getConstantSplatValue - Check if this is a constant splat, and if so,
- /// return the splat value only if it is a ConstantSDNode. Otherwise
- /// return nullptr. This is a simpler form of isConstantSplat.
- /// Get the constant splat only if you care about the splat value.
- ConstantSDNode *getConstantSplatValue() const;
+ /// \brief Returns the splatted value or a null value if this is not a splat.
+ ///
+ /// If passed a non-null UndefElements bitvector, it will resize it to match
+ /// the vector width and set the bits where elements are undef.
+ SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
+
+ /// \brief Returns the splatted constant or null if this is not a constant
+ /// splat.
+ ///
+ /// If passed a non-null UndefElements bitvector, it will resize it to match
+ /// the vector width and set the bits where elements are undef.
+ ConstantSDNode *
+ getConstantSplatNode(BitVector *UndefElements = nullptr) const;
+
+ /// \brief Returns the splatted constant FP or null if this is not a constant
+ /// FP splat.
+ ///
+ /// If passed a non-null UndefElements bitvector, it will resize it to match
+ /// the vector width and set the bits where elements are undef.
+ ConstantFPSDNode *
+ getConstantFPSplatNode(BitVector *UndefElements = nullptr) const;
bool isConstant() const;
diff --git a/include/llvm/CodeGen/StackMapLivenessAnalysis.h b/include/llvm/CodeGen/StackMapLivenessAnalysis.h
index 6ba7256..6f07546 100644
--- a/include/llvm/CodeGen/StackMapLivenessAnalysis.h
+++ b/include/llvm/CodeGen/StackMapLivenessAnalysis.h
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
//
// This pass calculates the liveness for each basic block in a function and
-// attaches the register live-out information to a stackmap or patchpoint
-// intrinsic if present.
+// attaches the register live-out information to a patchpoint intrinsic (if
+// present).
//
//===----------------------------------------------------------------------===//
@@ -23,14 +23,13 @@
namespace llvm {
/// \brief This pass calculates the liveness information for each basic block in
-/// a function and attaches the register live-out information to a stackmap or
-/// patchpoint intrinsic if present.
+/// a function and attaches the register live-out information to a patchpoint
+/// intrinsic if present.
///
-/// This is an optional pass that has to be explicitly enabled via the
-/// -enable-stackmap-liveness and/or -enable-patchpoint-liveness flag. The pass
-/// skips functions that don't have any stackmap or patchpoint intrinsics. The
+/// This pass can be disabled via the -enable-patchpoint-liveness=false flag.
+/// The pass skips functions that don't have any patchpoint intrinsics. The
/// information provided by this pass is optional and not required by the
-/// aformentioned intrinsics to function.
+/// aformentioned intrinsic to function.
class StackMapLiveness : public MachineFunctionPass {
MachineFunction *MF;
const TargetRegisterInfo *TRI;
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 9f1cbaa..230d1ed 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -68,11 +68,9 @@ public:
void InitializeELF(bool UseInitArray_);
const MCSection *getStaticCtorSection(unsigned Priority,
- const MCSymbol *KeySym,
- const MCSection *KeySec) const override;
+ const MCSymbol *KeySym) const override;
const MCSection *getStaticDtorSection(unsigned Priority,
- const MCSymbol *KeySym,
- const MCSection *KeySec) const override;
+ const MCSymbol *KeySym) const override;
};
@@ -144,11 +142,9 @@ public:
Mangler &Mang, const TargetMachine &TM) const override;
const MCSection *getStaticCtorSection(unsigned Priority,
- const MCSymbol *KeySym,
- const MCSection *KeySec) const override;
+ const MCSymbol *KeySym) const override;
const MCSection *getStaticDtorSection(unsigned Priority,
- const MCSymbol *KeySym,
- const MCSection *KeySec) const override;
+ const MCSymbol *KeySym) const override;
};
} // end namespace llvm
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index ea1e75a..e9f6702 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -3,20 +3,14 @@
#ifndef CONFIG_H
#define CONFIG_H
-/* Bug report URL. */
-#define BUG_REPORT_URL "${BUG_REPORT_URL}"
-
-/* Define if we have libxml2 */
-#cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML}
-
-/* Relative directory for resource files */
-#define CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}"
+/* Exported configuration */
+#include "llvm/Config/llvm-config.h"
-/* Directories clang will search for headers */
-#define C_INCLUDE_DIRS "${C_INCLUDE_DIRS}"
+/* Patch version of the LLVM API */
+#cmakedefine LLVM_VERSION_PATCH ${LLVM_VERSION_PATCH}
-/* Default <path> to all compiler invocations for --sysroot=<path>. */
-#undef DEFAULT_SYSROOT
+/* Bug report URL. */
+#define BUG_REPORT_URL "${BUG_REPORT_URL}"
/* Define if you want backtraces on crash */
#cmakedefine ENABLE_BACKTRACES
@@ -30,9 +24,6 @@
/* Define if timestamp information (e.g., __DATE__) is allowed */
#cmakedefine ENABLE_TIMESTAMPS ${ENABLE_TIMESTAMPS}
-/* Directory where gcc is installed. */
-#undef GCC_INSTALL_PREFIX
-
/* Define to 1 if you have the `arc4random' function. */
#cmakedefine HAVE_ARC4RANDOM
@@ -45,9 +36,6 @@
/* Define to 1 if you have the `ceilf' function. */
#cmakedefine HAVE_CEILF ${HAVE_CEILF}
-/* Define if the neat program is available */
-#cmakedefine HAVE_CIRCO ${HAVE_CIRCO}
-
/* Define to 1 if you have the `closedir' function. */
#cmakedefine HAVE_CLOSEDIR ${HAVE_CLOSEDIR}
@@ -80,12 +68,6 @@
/* Define if dlopen() is available on this platform. */
#cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN}
-/* Define if the dot program is available */
-#cmakedefine HAVE_DOT ${HAVE_DOT}
-
-/* Define if the dotty program is available */
-#cmakedefine HAVE_DOTTY ${HAVE_DOTTY}
-
/* Define if you have the _dyld_func_lookup function. */
#undef HAVE_DYLD
@@ -98,9 +80,6 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H ${HAVE_FCNTL_H}
-/* 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}
@@ -161,12 +140,6 @@
/* Define to 1 if you have the `gettimeofday' function. */
#cmakedefine HAVE_GETTIMEOFDAY ${HAVE_GETTIMEOFDAY}
-/* Define if the Graphviz program is available */
-#cmakedefine HAVE_GRAPHVIZ ${HAVE_GRAPHVIZ}
-
-/* Define if the gv program is available */
-#cmakedefine HAVE_GV ${HAVE_GV}
-
/* Define to 1 if the system has the type `int64_t'. */
#cmakedefine HAVE_INT64_T ${HAVE_INT64_T}
@@ -271,9 +244,6 @@
/* Define to 1 if you have the `nearbyintf' function. */
#cmakedefine HAVE_NEARBYINTF ${HAVE_NEARBYINTF}
-/* Define if the neat program is available */
-#cmakedefine HAVE_NEATO ${HAVE_NEATO}
-
/* Define to 1 if you have the `opendir' function. */
#cmakedefine HAVE_OPENDIR ${HAVE_OPENDIR}
@@ -417,9 +387,6 @@
/* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H}
-/* 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}
@@ -438,9 +405,6 @@
/* 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 ${HAVE_XDOT}
-
/* Define to 1 if you have the <zlib.h> header file. */
#cmakedefine HAVE_ZLIB_H ${HAVE_ZLIB_H}
@@ -501,114 +465,9 @@
/* Define if we link Polly to the tools */
#cmakedefine LINK_POLLY_INTO_TOOLS
-/* Installation directory for binary executables */
-#cmakedefine LLVM_BINDIR "${LLVM_BINDIR}"
-
-/* Time at which LLVM was configured */
-#cmakedefine LLVM_CONFIGTIME "${LLVM_CONFIGTIME}"
-
-/* Installation directory for data files */
-#cmakedefine LLVM_DATADIR "${LLVM_DATADIR}"
-
-/* Target triple LLVM will generate code for by default */
-#cmakedefine LLVM_DEFAULT_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}"
-
-/* Installation directory for documentation */
-#cmakedefine LLVM_DOCSDIR "${LLVM_DOCSDIR}"
-
-/* Define if threads enabled */
-#cmakedefine01 LLVM_ENABLE_THREADS
-
/* Define if zlib compression is available */
#cmakedefine01 LLVM_ENABLE_ZLIB
-/* Installation directory for config files */
-#cmakedefine LLVM_ETCDIR "${LLVM_ETCDIR}"
-
-/* Has gcc/MSVC atomic intrinsics */
-#cmakedefine01 LLVM_HAS_ATOMICS
-
-/* Host triple LLVM will be executed on */
-#cmakedefine LLVM_HOST_TRIPLE "${LLVM_HOST_TRIPLE}"
-
-/* Installation directory for include files */
-#cmakedefine LLVM_INCLUDEDIR "${LLVM_INCLUDEDIR}"
-
-/* Installation directory for .info files */
-#cmakedefine LLVM_INFODIR "${LLVM_INFODIR}"
-
-/* Installation directory for man pages */
-#cmakedefine LLVM_MANDIR "${LLVM_MANDIR}"
-
-/* LLVM architecture name for the native architecture, if available */
-#cmakedefine LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}
-
-/* LLVM name for the native AsmParser init function, if available */
-#cmakedefine LLVM_NATIVE_ASMPARSER LLVMInitialize${LLVM_NATIVE_ARCH}AsmParser
-
-/* LLVM name for the native AsmPrinter init function, if available */
-#cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter
-
-/* LLVM name for the native Disassembler init function, if available */
-#cmakedefine LLVM_NATIVE_DISASSEMBLER LLVMInitialize${LLVM_NATIVE_ARCH}Disassembler
-
-/* 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 target MC init function, if available */
-#cmakedefine LLVM_NATIVE_TARGETMC LLVMInitialize${LLVM_NATIVE_ARCH}TargetMC
-
-/* 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}
-
-/* Define to path to circo program if found or 'echo circo' otherwise */
-#cmakedefine LLVM_PATH_CIRCO "${LLVM_PATH_CIRCO}"
-
-/* Define to path to dot program if found or 'echo dot' otherwise */
-#cmakedefine LLVM_PATH_DOT "${LLVM_PATH_DOT}"
-
-/* Define to path to dotty program if found or 'echo dotty' otherwise */
-#cmakedefine LLVM_PATH_DOTTY "${LLVM_PATH_DOTTY}"
-
-/* Define to path to fdp program if found or 'echo fdp' otherwise */
-#cmakedefine LLVM_PATH_FDP "${LLVM_PATH_FDP}"
-
-/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
-#cmakedefine LLVM_PATH_GRAPHVIZ "${LLVM_PATH_GRAPHVIZ}"
-
-/* Define to path to gv program if found or 'echo gv' otherwise */
-#cmakedefine LLVM_PATH_GV "${LLVM_PATH_GV}"
-
-/* Define to path to neato program if found or 'echo neato' otherwise */
-#cmakedefine LLVM_PATH_NEATO "${LLVM_PATH_NEATO}"
-
-/* 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' otherwise */
-#cmakedefine LLVM_PATH_XDOT "${LLVM_PATH_XDOT}"
-
-/* Installation prefix directory */
-#cmakedefine LLVM_PREFIX "${LLVM_PREFIX}"
-
-/* Define if we have the Intel JIT API runtime support library */
-#cmakedefine LLVM_USE_INTEL_JITEVENTS 1
-
-/* Define if we have the oprofile JIT-support library */
-#cmakedefine LLVM_USE_OPROFILE 1
-
-/* Major version of the LLVM API */
-#cmakedefine LLVM_VERSION_MAJOR ${LLVM_VERSION_MAJOR}
-
-/* Minor version of the LLVM API */
-#cmakedefine LLVM_VERSION_MINOR ${LLVM_VERSION_MINOR}
-
/* Define if the OS needs help to load dependent libraries for dlopen(). */
#cmakedefine LTDL_DLOPEN_DEPLIBS ${LTDL_DLOPEN_DEPLIBS}
@@ -689,7 +548,7 @@
/* Define to 1 if you have the `_chsize_s' function. */
#cmakedefine HAVE__CHSIZE_S ${HAVE__CHSIZE_S}
-/* Added by Kevin -- Maximum path length */
+/* Maximum path length */
#cmakedefine MAXPATHLEN ${MAXPATHLEN}
#endif
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index 6b8dbb7..b5f7297 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -3,20 +3,14 @@
#ifndef CONFIG_H
#define CONFIG_H
-/* Bug report URL. */
-#undef BUG_REPORT_URL
-
-/* Define if we have libxml2 */
-#undef CLANG_HAVE_LIBXML
-
-/* Relative directory for resource files */
-#undef CLANG_RESOURCE_DIR
+/* Exported configuration */
+#include "llvm/Config/llvm-config.h"
-/* Directories clang will search for headers */
-#undef C_INCLUDE_DIRS
+/* Patch version of the LLVM API */
+#undef LLVM_VERSION_PATCH
-/* Default <path> to all compiler invocations for --sysroot=<path>. */
-#undef DEFAULT_SYSROOT
+/* Bug report URL. */
+#undef BUG_REPORT_URL
/* Define if you want backtraces on crash */
#undef ENABLE_BACKTRACES
@@ -30,18 +24,12 @@
/* Define if timestamp information (e.g., __DATE__) is allowed */
#undef ENABLE_TIMESTAMPS
-/* Directory where gcc is installed. */
-#undef GCC_INSTALL_PREFIX
-
/* Define to 1 if you have the `backtrace' function. */
#undef HAVE_BACKTRACE
/* Define to 1 if you have the `ceilf' function. */
#undef HAVE_CEILF
-/* Define if the neat program is available */
-#undef HAVE_CIRCO
-
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
#undef HAVE_CRASHREPORTERCLIENT_H
@@ -77,12 +65,6 @@
/* Define if dlopen() is available on this platform. */
#undef HAVE_DLOPEN
-/* Define if the dot program is available */
-#undef HAVE_DOT
-
-/* Define if the dotty program is available */
-#undef HAVE_DOTTY
-
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
@@ -98,9 +80,6 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
-/* Define if the neat program is available */
-#undef HAVE_FDP
-
/* Define to 1 if you have the <fenv.h> header file. */
#undef HAVE_FENV_H
@@ -143,12 +122,6 @@
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
-/* Define if the Graphviz program is available */
-#undef HAVE_GRAPHVIZ
-
-/* Define if the gv program is available */
-#undef HAVE_GV
-
/* Define to 1 if the system has the type `int64_t'. */
#undef HAVE_INT64_T
@@ -259,9 +232,6 @@
/* Define to 1 if you have the `nearbyintf' function. */
#undef HAVE_NEARBYINTF
-/* Define if the neat program is available */
-#undef HAVE_NEATO
-
/* Define to 1 if you have the `posix_spawn' function. */
#undef HAVE_POSIX_SPAWN
@@ -402,9 +372,6 @@
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
-/* Define if the neat program is available */
-#undef HAVE_TWOPI
-
/* Define to 1 if the system has the type `uint64_t'. */
#undef HAVE_UINT64_T
@@ -423,9 +390,6 @@
/* Define to 1 if you have the `writev' function. */
#undef HAVE_WRITEV
-/* Define if the xdot program is available */
-#undef HAVE_XDOT
-
/* Define to 1 if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
@@ -483,117 +447,9 @@
/* Linker version detected at compile time. */
#undef HOST_LINK_VERSION
-/* Installation directory for binary executables */
-#undef LLVM_BINDIR
-
-/* Time at which LLVM was configured */
-#undef LLVM_CONFIGTIME
-
-/* Installation directory for data files */
-#undef LLVM_DATADIR
-
-/* Target triple LLVM will generate code for by default */
-#undef LLVM_DEFAULT_TARGET_TRIPLE
-
-/* Installation directory for documentation */
-#undef LLVM_DOCSDIR
-
-/* Define if threads enabled */
-#undef LLVM_ENABLE_THREADS
-
/* Define if zlib is enabled */
#undef LLVM_ENABLE_ZLIB
-/* Installation directory for config files */
-#undef LLVM_ETCDIR
-
-/* Has gcc/MSVC atomic intrinsics */
-#undef LLVM_HAS_ATOMICS
-
-/* Host triple LLVM will be executed on */
-#undef LLVM_HOST_TRIPLE
-
-/* Installation directory for include files */
-#undef LLVM_INCLUDEDIR
-
-/* Installation directory for .info files */
-#undef LLVM_INFODIR
-
-/* Installation directory for man pages */
-#undef LLVM_MANDIR
-
-/* LLVM architecture name for the native architecture, if available */
-#undef LLVM_NATIVE_ARCH
-
-/* LLVM name for the native AsmParser init function, if available */
-#undef LLVM_NATIVE_ASMPARSER
-
-/* LLVM name for the native AsmPrinter init function, if available */
-#undef LLVM_NATIVE_ASMPRINTER
-
-/* LLVM name for the native Disassembler init function, if available */
-#undef LLVM_NATIVE_DISASSEMBLER
-
-/* LLVM name for the native Target init function, if available */
-#undef LLVM_NATIVE_TARGET
-
-/* LLVM name for the native TargetInfo init function, if available */
-#undef LLVM_NATIVE_TARGETINFO
-
-/* LLVM name for the native target MC init function, if available */
-#undef LLVM_NATIVE_TARGETMC
-
-/* Define if this is Unixish platform */
-#undef LLVM_ON_UNIX
-
-/* Define if this is Win32ish platform */
-#undef LLVM_ON_WIN32
-
-/* Define to path to circo program if found or 'echo circo' otherwise */
-#undef LLVM_PATH_CIRCO
-
-/* Define to path to dot program if found or 'echo dot' otherwise */
-#undef LLVM_PATH_DOT
-
-/* Define to path to dotty program if found or 'echo dotty' otherwise */
-#undef LLVM_PATH_DOTTY
-
-/* Define to path to fdp program if found or 'echo fdp' otherwise */
-#undef LLVM_PATH_FDP
-
-/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
-#undef LLVM_PATH_GRAPHVIZ
-
-/* Define to path to gv program if found or 'echo gv' otherwise */
-#undef LLVM_PATH_GV
-
-/* Define to path to neato program if found or 'echo neato' otherwise */
-#undef LLVM_PATH_NEATO
-
-/* Define to path to twopi program if found or 'echo twopi' otherwise */
-#undef LLVM_PATH_TWOPI
-
-/* Define to path to xdot program if found or 'echo xdot' otherwise */
-#undef LLVM_PATH_XDOT
-
-/* Installation prefix directory */
-#undef LLVM_PREFIX
-
-/* Define if we have the Intel JIT API runtime support library */
-#undef LLVM_USE_INTEL_JITEVENTS
-
-/* Define if we have the oprofile JIT-support library */
-#undef LLVM_USE_OPROFILE
-
-/* Major version of the LLVM API */
-#undef LLVM_VERSION_MAJOR
-
-/* Minor version of the LLVM API */
-#undef LLVM_VERSION_MINOR
-
-/* Patch version of the LLVM API */
-#undef LLVM_VERSION_PATCH
-
/* The shared library extension */
#undef LTDL_SHLIB_EXT
diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake
index 65116cb..5811164 100644
--- a/include/llvm/Config/llvm-config.h.cmake
+++ b/include/llvm/Config/llvm-config.h.cmake
@@ -1,4 +1,4 @@
-/*===-- llvm/config/llvm-config.h - llvm configure variable -------*- C -*-===*/
+/*===------- llvm/Config/llvm-config.h - llvm configuration -------*- C -*-===*/
/* */
/* The LLVM Compiler Infrastructure */
/* */
@@ -7,14 +7,12 @@
/* */
/*===----------------------------------------------------------------------===*/
-/* This file enumerates all of the llvm variables from configure so that
- they can be in exported headers and won't override package specific
- directives. This is a C file so we can include it in the llvm-c headers. */
+/* This file enumerates variables from the LLVM configuration so that they
+ can be in exported headers and won't override package specific directives.
+ This is a C header that can be included in the llvm-c headers. */
-/* To avoid multiple inclusions of these variables when we include the exported
- headers and config.h, conditionally include these. */
-/* TODO: This is a bit of a hack. */
-#ifndef CONFIG_H
+#ifndef LLVM_CONFIG_H
+#define LLVM_CONFIG_H
/* Installation directory for binary executables */
#cmakedefine LLVM_BINDIR "${LLVM_BINDIR}"
@@ -79,33 +77,6 @@
/* Define if this is Win32ish platform */
#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}"
-
-/* Define to path to dot program if found or 'echo dot' otherwise */
-#cmakedefine LLVM_PATH_DOT "${LLVM_PATH_DOT}"
-
-/* Define to path to dotty program if found or 'echo dotty' otherwise */
-#cmakedefine LLVM_PATH_DOTTY "${LLVM_PATH_DOTTY}"
-
-/* Define to path to fdp program if found or 'echo fdp' otherwise */
-#cmakedefine LLVM_PATH_FDP "${LLVM_PATH_FDP}"
-
-/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
-#cmakedefine LLVM_PATH_GRAPHVIZ "${LLVM_PATH_GRAPHVIZ}"
-
-/* Define to path to gv program if found or 'echo gv' otherwise */
-#cmakedefine LLVM_PATH_GV "${LLVM_PATH_GV}"
-
-/* Define to path to neato program if found or 'echo neato' otherwise */
-#cmakedefine LLVM_PATH_NEATO "${LLVM_PATH_NEATO}"
-
-/* 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/Config/llvm-config.h.in b/include/llvm/Config/llvm-config.h.in
index a4fae55..5656240 100644
--- a/include/llvm/Config/llvm-config.h.in
+++ b/include/llvm/Config/llvm-config.h.in
@@ -1,4 +1,4 @@
-/*===-- llvm/config/llvm-config.h - llvm configure variable -------*- C -*-===*/
+/*===------- llvm/Config/llvm-config.h - llvm configuration -------*- C -*-===*/
/* */
/* The LLVM Compiler Infrastructure */
/* */
@@ -7,14 +7,12 @@
/* */
/*===----------------------------------------------------------------------===*/
-/* This file enumerates all of the llvm variables from configure so that
- they can be in exported headers and won't override package specific
- directives. This is a C file so we can include it in the llvm-c headers. */
+/* This file enumerates variables from the LLVM configuration so that they
+ can be in exported headers and won't override package specific directives.
+ This is a C header that can be included in the llvm-c headers. */
-/* To avoid multiple inclusions of these variables when we include the exported
- headers and config.h, conditionally include these. */
-/* TODO: This is a bit of a hack. */
-#ifndef CONFIG_H
+#ifndef LLVM_CONFIG_H
+#define LLVM_CONFIG_H
/* Installation directory for binary executables */
#undef LLVM_BINDIR
@@ -79,33 +77,6 @@
/* Define if this is Win32ish platform */
#undef LLVM_ON_WIN32
-/* Define to path to circo program if found or 'echo circo' otherwise */
-#undef LLVM_PATH_CIRCO
-
-/* Define to path to dot program if found or 'echo dot' otherwise */
-#undef LLVM_PATH_DOT
-
-/* Define to path to dotty program if found or 'echo dotty' otherwise */
-#undef LLVM_PATH_DOTTY
-
-/* Define to path to fdp program if found or 'echo fdp' otherwise */
-#undef LLVM_PATH_FDP
-
-/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
-#undef LLVM_PATH_GRAPHVIZ
-
-/* Define to path to gv program if found or 'echo gv' otherwise */
-#undef LLVM_PATH_GV
-
-/* Define to path to neato program if found or 'echo neato' otherwise */
-#undef LLVM_PATH_NEATO
-
-/* Define to path to twopi program if found or 'echo twopi' otherwise */
-#undef LLVM_PATH_TWOPI
-
-/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */
-#undef LLVM_PATH_XDOT_PY
-
/* Installation prefix directory */
#undef LLVM_PREFIX
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index 7518c1e..e5dab61 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -54,7 +54,7 @@ namespace object {
}
/// \brief Helper class for helping synchronize access to the global address map
-/// table.
+/// table. Access to this class should be serialized under a mutex.
class ExecutionEngineState {
public:
struct AddressMapConfig : public ValueMapConfig<const GlobalValue*> {
@@ -84,19 +84,19 @@ private:
public:
ExecutionEngineState(ExecutionEngine &EE);
- GlobalAddressMapTy &getGlobalAddressMap(const MutexGuard &) {
+ GlobalAddressMapTy &getGlobalAddressMap() {
return GlobalAddressMap;
}
std::map<void*, AssertingVH<const GlobalValue> > &
- getGlobalAddressReverseMap(const MutexGuard &) {
+ getGlobalAddressReverseMap() {
return GlobalAddressReverseMap;
}
/// \brief Erase an entry from the mapping table.
///
/// \returns The address that \p ToUnmap was happed to.
- void *RemoveMapping(const MutexGuard &, const GlobalValue *ToUnmap);
+ void *RemoveMapping(const GlobalValue *ToUnmap);
};
/// \brief Abstract interface for implementation execution of LLVM modules,
@@ -586,26 +586,7 @@ private:
bool VerifyModules;
/// InitEngine - Does the common initialization of default options.
- void InitEngine() {
- WhichEngine = EngineKind::Either;
- ErrorStr = nullptr;
- OptLevel = CodeGenOpt::Default;
- MCJMM = nullptr;
- JMM = nullptr;
- Options = TargetOptions();
- AllocateGVsWithCode = false;
- RelocModel = Reloc::Default;
- CMModel = CodeModel::JITDefault;
- UseMCJIT = false;
-
- // IR module verification is enabled by default in debug builds, and disabled
- // by default in release builds.
-#ifndef NDEBUG
- VerifyModules = true;
-#else
- VerifyModules = false;
-#endif
- }
+ void InitEngine();
public:
/// EngineBuilder - Constructor for EngineBuilder. If create() is called and
diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h
index 071a42b..6221d3b 100644
--- a/include/llvm/ExecutionEngine/ObjectBuffer.h
+++ b/include/llvm/ExecutionEngine/ObjectBuffer.h
@@ -39,7 +39,8 @@ public:
/// returns a pointer to an object that is owned by the caller. However,
/// the caller does not take ownership of the underlying memory.
MemoryBuffer *getMemBuffer() const {
- return MemoryBuffer::getMemBuffer(Buffer->getBuffer(), "", false);
+ return MemoryBuffer::getMemBuffer(Buffer->getBuffer(),
+ Buffer->getBufferIdentifier(), false);
}
const char *getBufferStart() const { return Buffer->getBufferStart(); }
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index 30c0d49..f123ffb 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -29,6 +29,8 @@ class RuntimeDyldImpl;
class ObjectImage;
class RuntimeDyld {
+ friend class RuntimeDyldChecker;
+
RuntimeDyld(const RuntimeDyld &) LLVM_DELETED_FUNCTION;
void operator=(const RuntimeDyld &) LLVM_DELETED_FUNCTION;
diff --git a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
new file mode 100644
index 0000000..38a4ea1
--- /dev/null
+++ b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
@@ -0,0 +1,98 @@
+//===---- RuntimeDyldChecker.h - RuntimeDyld tester framework -----*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_RUNTIMEDYLDCHECKER_H
+#define LLVM_RUNTIMEDYLDCHECKER_H
+
+#include "RuntimeDyld.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
+
+namespace llvm {
+
+class MCDisassembler;
+class MCInstPrinter;
+
+/// \brief RuntimeDyld invariant checker for verifying that RuntimeDyld has
+/// correctly applied relocations.
+///
+/// The RuntimeDyldChecker class evaluates expressions against an attached
+/// RuntimeDyld instance to verify that relocations have been applied
+/// correctly.
+///
+/// The expression language supports basic pointer arithmetic and bit-masking,
+/// and has limited disassembler integration for accessing instruction
+/// operands and the next PC (program counter) address for each instruction.
+///
+/// The language syntax is:
+///
+/// check = expr '=' expr
+///
+/// expr = binary_expr
+/// | sliceable_expr
+///
+/// sliceable_expr = '*{' number '}' load_addr_expr [slice]
+/// | '(' expr ')' [slice]
+/// | ident_expr [slice]
+/// | number [slice]
+///
+/// slice = '[' high-bit-index ':' low-bit-index ']'
+///
+/// load_addr_expr = symbol
+/// | '(' symbol '+' number ')'
+/// | '(' symbol '-' number ')'
+///
+/// ident_expr = 'decode_operand' '(' symbol ',' operand-index ')'
+/// | 'next_pc' '(' symbol ')'
+/// | symbol
+///
+/// binary_expr = expr '+' expr
+/// | expr '-' expr
+/// | expr '&' expr
+/// | expr '|' expr
+/// | expr '<<' expr
+/// | expr '>>' expr
+///
+class RuntimeDyldChecker {
+ friend class RuntimeDyldCheckerExprEval;
+public:
+ RuntimeDyldChecker(RuntimeDyld &RTDyld,
+ MCDisassembler *Disassembler,
+ MCInstPrinter *InstPrinter,
+ llvm::raw_ostream &ErrStream)
+ : RTDyld(*RTDyld.Dyld), Disassembler(Disassembler),
+ InstPrinter(InstPrinter), ErrStream(ErrStream) {}
+
+ /// \brief Check a single expression against the attached RuntimeDyld
+ /// instance.
+ bool check(StringRef CheckExpr) const;
+
+ /// \brief Scan the given memory buffer for lines beginning with the string
+ /// in RulePrefix. The remainder of the line is passed to the check
+ /// method to be evaluated as an expression.
+ bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const;
+
+private:
+
+ bool checkSymbolIsValidForLoad(StringRef Symbol) const;
+ uint64_t getSymbolAddress(StringRef Symbol) const;
+ uint64_t readMemoryAtSymbol(StringRef Symbol, int64_t Offset,
+ unsigned Size) const;
+ StringRef getSubsectionStartingAt(StringRef Name) const;
+
+ RuntimeDyldImpl &RTDyld;
+ MCDisassembler *Disassembler;
+ MCInstPrinter *InstPrinter;
+ llvm::raw_ostream &ErrStream;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_RUNTIMEDYLDCHECKER_H
diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h
index f24bb4d..1368563 100644
--- a/include/llvm/ExecutionEngine/SectionMemoryManager.h
+++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h
@@ -21,7 +21,6 @@
#include "llvm/Support/Memory.h"
namespace llvm {
-
/// This is a simple memory manager which implements the methods called by
/// the RuntimeDyld class to allocate memory for section-based loading of
/// objects, usually those generated by the MCJIT execution engine.
@@ -93,8 +92,8 @@ private:
uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size,
unsigned Alignment);
- error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup,
- unsigned Permissions);
+ std::error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup,
+ unsigned Permissions);
MemoryGroup CodeMem;
MemoryGroup RWDataMem;
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index 86f9cc8..e34dc83 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -75,6 +75,7 @@ public:
Cold, ///< Marks function as being in a cold path.
InlineHint, ///< Source said inlining was desirable
InReg, ///< Force argument to be passed in register
+ JumpTable, ///< Build jump-instruction tables and replace refs.
MinSize, ///< Function must be optimized for size first
Naked, ///< Naked function
Nest, ///< Nested function static chain
diff --git a/include/llvm/IR/AutoUpgrade.h b/include/llvm/IR/AutoUpgrade.h
index 076ed4a..a4b3c41 100644
--- a/include/llvm/IR/AutoUpgrade.h
+++ b/include/llvm/IR/AutoUpgrade.h
@@ -14,6 +14,8 @@
#ifndef LLVM_IR_AUTOUPGRADE_H
#define LLVM_IR_AUTOUPGRADE_H
+#include <string>
+
namespace llvm {
class CallInst;
class Constant;
@@ -61,6 +63,9 @@ namespace llvm {
/// Check the debug info version number, if it is out-dated, drop the debug
/// info. Return true if module is modified.
bool UpgradeDebugInfo(Module &M);
+
+ /// Upgrade a metadata string constant in place.
+ void UpgradeMDStringConstant(std::string &String);
} // End llvm namespace
#endif
diff --git a/include/llvm/IR/Comdat.h b/include/llvm/IR/Comdat.h
new file mode 100644
index 0000000..3e77a77
--- /dev/null
+++ b/include/llvm/IR/Comdat.h
@@ -0,0 +1,66 @@
+//===-- llvm/IR/Comdat.h - Comdat definitions -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// This file contains the declaration of the Comdat class, which represents a
+/// single COMDAT in LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_COMDAT_H
+#define LLVM_IR_COMDAT_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+class raw_ostream;
+template <typename ValueTy> class StringMapEntry;
+
+// This is a Name X SelectionKind pair. The reason for having this be an
+// independent object instead of just adding the name and the SelectionKind
+// to a GlobalObject is that it is invalid to have two Comdats with the same
+// name but different SelectionKind. This structure makes that unrepresentable.
+class Comdat {
+public:
+ enum SelectionKind {
+ Any, ///< The linker may choose any COMDAT.
+ ExactMatch, ///< The data referenced by the COMDAT must be the same.
+ Largest, ///< The linker will choose the largest COMDAT.
+ NoDuplicates, ///< No other Module may specify this COMDAT.
+ SameSize, ///< The data referenced by the COMDAT must be the same size.
+ };
+
+ Comdat(Comdat &&C);
+ SelectionKind getSelectionKind() const { return SK; }
+ void setSelectionKind(SelectionKind Val) { SK = Val; }
+ StringRef getName() const;
+ void print(raw_ostream &OS) const;
+ void dump() const;
+
+private:
+ friend class Module;
+ Comdat();
+ Comdat(SelectionKind SK, StringMapEntry<Comdat> *Name);
+ Comdat(const Comdat &) LLVM_DELETED_FUNCTION;
+
+ // Points to the map in Module.
+ StringMapEntry<Comdat> *Name;
+ SelectionKind SK;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const Comdat &C) {
+ C.print(OS);
+ return OS;
+}
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h
index f03e3dd..82ad9fc 100644
--- a/include/llvm/IR/Constant.h
+++ b/include/llvm/IR/Constant.h
@@ -64,6 +64,9 @@ public:
/// Return true if the value is negative zero or null value.
bool isZeroValue() const;
+ /// \brief Return true if the value is the smallest signed value.
+ bool isMinSignedValue() const;
+
/// canTrap - Return true if evaluation of this constant could trap. This is
/// true for things like constant expressions that could divide by zero.
bool canTrap() const;
@@ -71,6 +74,9 @@ public:
/// isThreadDependent - Return true if the value can vary between threads.
bool isThreadDependent() const;
+ /// Return true if the value is dependent on a dllimport variable.
+ bool isDLLImportDependent() const;
+
/// isConstantUsed - Return true if the constant has users other than constant
/// exprs and other dangling things.
bool isConstantUsed() const;
@@ -163,6 +169,14 @@ public:
/// 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;
+
+ Constant *stripPointerCasts() {
+ return cast<Constant>(Value::stripPointerCasts());
+ }
+
+ const Constant *stripPointerCasts() const {
+ return const_cast<Constant*>(this)->stripPointerCasts();
+ }
};
} // End llvm namespace
diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h
index 8b05bbb..2673504 100644
--- a/include/llvm/IR/DIBuilder.h
+++ b/include/llvm/IR/DIBuilder.h
@@ -108,12 +108,23 @@ namespace llvm {
/// Objective-C.
/// @param SplitName The name of the file that we'll split debug info out
/// into.
+ /// @param Kind The kind of debug information to generate.
+ /// @param EmitDebugInfo A boolean flag which indicates whether debug
+ /// information should be written to the final
+ /// output or not. When this is false, debug
+ /// information annotations will be present in
+ /// the IL but they are not written to the final
+ /// assembly or object file. This supports tracking
+ /// source location information in the back end
+ /// without actually changing the output (e.g.,
+ /// when using optimization remarks).
DICompileUnit createCompileUnit(unsigned Lang, StringRef File,
StringRef Dir, StringRef Producer,
bool isOptimized, StringRef Flags,
unsigned RV,
StringRef SplitName = StringRef(),
- DebugEmissionKind Kind = FullDebug);
+ DebugEmissionKind Kind = FullDebug,
+ bool EmitDebugInfo = true);
/// createFile - Create a file descriptor to hold debugging information
/// for a file.
diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h
index 3079dec..877029f 100644
--- a/include/llvm/IR/DataLayout.h
+++ b/include/llvm/IR/DataLayout.h
@@ -414,8 +414,8 @@ public:
return (LargestSize == 0) ? nullptr : Type::getIntNTy(C, LargestSize);
}
- /// getLargestLegalIntType - Return the size of largest legal integer type
- /// size, or 0 if none are set.
+ /// getLargestLegalIntTypeSize - Return the size of largest legal integer
+ /// type size, or 0 if none are set.
unsigned getLargestLegalIntTypeSize() const;
/// getIndexedOffset - return the offset from the beginning of the type for
diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h
index 65e0a06..088eb9f 100644
--- a/include/llvm/IR/DebugInfo.h
+++ b/include/llvm/IR/DebugInfo.h
@@ -690,12 +690,17 @@ public:
/// HasComplexAddr - Return true if the variable has a complex address.
bool hasComplexAddress() const { return getNumAddrElements() > 0; }
- unsigned getNumAddrElements() const;
-
- uint64_t getAddrElement(unsigned Idx) const {
- return getUInt64Field(Idx + 8);
+ /// \brief Return the size of this variable's complex address or
+ /// zero if there is none.
+ unsigned getNumAddrElements() const {
+ if (DbgNode->getNumOperands() < 9)
+ return 0;
+ return getDescriptorField(8)->getNumOperands();
}
+ /// \brief return the Idx'th complex address element.
+ uint64_t getAddrElement(unsigned Idx) const;
+
/// isBlockByrefVariable - Return true if the variable was declared as
/// a "__block" variable (Apple Blocks).
bool isBlockByrefVariable(const DITypeIdentifierMap &Map) const {
@@ -929,6 +934,9 @@ private:
/// Specify if TypeIdentifierMap is initialized.
bool TypeMapInitialized;
};
+
+DenseMap<const Function *, DISubprogram> makeSubprogramMap(const Module &M);
+
} // end namespace llvm
#endif
diff --git a/include/llvm/IR/DebugLoc.h b/include/llvm/IR/DebugLoc.h
index 6d769d4..3d969a8 100644
--- a/include/llvm/IR/DebugLoc.h
+++ b/include/llvm/IR/DebugLoc.h
@@ -95,7 +95,7 @@ namespace llvm {
// getFnDebugLoc - Walk up the scope chain of given debug loc and find line
// number info for the function.
- DebugLoc getFnDebugLoc(const LLVMContext &Ctx);
+ DebugLoc getFnDebugLoc(const LLVMContext &Ctx) const;
/// getAsMDNode - This method converts the compressed DebugLoc node into a
/// DILocation compatible MDNode.
diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h
index e78a42b..de38d07 100644
--- a/include/llvm/IR/DiagnosticInfo.h
+++ b/include/llvm/IR/DiagnosticInfo.h
@@ -138,7 +138,6 @@ public:
/// \see DiagnosticInfo::print.
void print(DiagnosticPrinter &DP) const override;
- /// Hand rolled RTTI.
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_InlineAsm;
}
@@ -166,7 +165,6 @@ public:
/// \see DiagnosticInfo::print.
void print(DiagnosticPrinter &DP) const override;
- /// Hand rolled RTTI.
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_StackSize;
}
@@ -195,7 +193,6 @@ public:
/// \see DiagnosticInfo::print.
void print(DiagnosticPrinter &DP) const override;
- /// Hand rolled RTTI.
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_DebugMetadataVersion;
}
@@ -221,7 +218,6 @@ public:
/// \see DiagnosticInfo::print.
void print(DiagnosticPrinter &DP) const override;
- /// Hand rolled RTTI.
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_SampleProfile;
}
@@ -261,7 +257,6 @@ public:
/// \see DiagnosticInfo::print.
void print(DiagnosticPrinter &DP) const override;
- /// Hand rolled RTTI.
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_OptimizationRemark;
}
@@ -323,7 +318,6 @@ public:
: DiagnosticInfoOptimizationRemarkBase(DK_OptimizationRemark, PassName,
Fn, DLoc, Msg) {}
- /// Hand rolled RTTI
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_OptimizationRemark;
}
@@ -350,7 +344,6 @@ public:
: DiagnosticInfoOptimizationRemarkBase(DK_OptimizationRemarkMissed,
PassName, Fn, DLoc, Msg) {}
- /// Hand rolled RTTI
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_OptimizationRemarkMissed;
}
@@ -378,7 +371,6 @@ public:
: DiagnosticInfoOptimizationRemarkBase(DK_OptimizationRemarkAnalysis,
PassName, Fn, DLoc, Msg) {}
- /// Hand rolled RTTI
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_OptimizationRemarkAnalysis;
}
diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h
index 3648202..e2d1ccc 100644
--- a/include/llvm/IR/Dominators.h
+++ b/include/llvm/IR/Dominators.h
@@ -97,10 +97,6 @@ public:
bool dominates(const BasicBlockEdge &BBE, const Use &U) const;
bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const;
- inline DomTreeNode *operator[](BasicBlock *BB) const {
- return getNode(BB);
- }
-
// Ensure base class overloads are visible.
using Base::isReachableFromEntry;
diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h
index dbe52bc..a1216a1 100644
--- a/include/llvm/IR/GVMaterializer.h
+++ b/include/llvm/IR/GVMaterializer.h
@@ -18,10 +18,9 @@
#ifndef LLVM_IR_GVMATERIALIZER_H
#define LLVM_IR_GVMATERIALIZER_H
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
-
class Function;
class GlobalValue;
class Module;
@@ -43,7 +42,7 @@ public:
/// Make sure the given GlobalValue is fully read.
///
- virtual error_code Materialize(GlobalValue *GV) = 0;
+ virtual std::error_code Materialize(GlobalValue *GV) = 0;
/// If the given GlobalValue is read in, and if the GVMaterializer supports
/// it, release the memory for the GV, and set it up to be materialized
@@ -54,7 +53,9 @@ public:
/// Make sure the entire Module has been completely read.
///
- virtual error_code MaterializeModule(Module *M) = 0;
+ virtual std::error_code MaterializeModule(Module *M) = 0;
+
+ virtual void releaseBuffer() = 0;
};
} // End llvm namespace
diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h
index d9f0b4a..075b570 100644
--- a/include/llvm/IR/GlobalAlias.h
+++ b/include/llvm/IR/GlobalAlias.h
@@ -34,7 +34,7 @@ class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
void setParent(Module *parent);
GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage,
- const Twine &Name, GlobalObject *Aliasee, Module *Parent);
+ const Twine &Name, Constant *Aliasee, Module *Parent);
public:
// allocate space for exactly one operand
@@ -46,7 +46,7 @@ public:
/// the end of the specified module's alias list.
static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
LinkageTypes Linkage, const Twine &Name,
- GlobalObject *Aliasee, Module *Parent);
+ Constant *Aliasee, Module *Parent);
// Without the Aliasee.
static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
@@ -56,14 +56,14 @@ public:
// The module is taken from the Aliasee.
static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
LinkageTypes Linkage, const Twine &Name,
- GlobalObject *Aliasee);
+ GlobalValue *Aliasee);
// Type, Parent and AddressSpace taken from the Aliasee.
static GlobalAlias *create(LinkageTypes Linkage, const Twine &Name,
- GlobalObject *Aliasee);
+ GlobalValue *Aliasee);
// Linkage, Type, Parent and AddressSpace taken from the Aliasee.
- static GlobalAlias *create(const Twine &Name, GlobalObject *Aliasee);
+ static GlobalAlias *create(const Twine &Name, GlobalValue *Aliasee);
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@@ -78,14 +78,28 @@ public:
///
void eraseFromParent() override;
- /// set/getAliasee - These methods retrive and set alias target.
- void setAliasee(GlobalObject *GO);
- const GlobalObject *getAliasee() const {
+ /// These methods retrive and set alias target.
+ void setAliasee(Constant *Aliasee);
+ const Constant *getAliasee() const {
return const_cast<GlobalAlias *>(this)->getAliasee();
}
+ Constant *getAliasee() {
+ return getOperand(0);
+ }
- GlobalObject *getAliasee() {
- return cast_or_null<GlobalObject>(getOperand(0));
+ const GlobalObject *getBaseObject() const {
+ return const_cast<GlobalAlias *>(this)->getBaseObject();
+ }
+ GlobalObject *getBaseObject() {
+ return dyn_cast<GlobalObject>(getAliasee()->stripInBoundsOffsets());
+ }
+
+ const GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) const {
+ return const_cast<GlobalAlias *>(this)->getBaseObject(DL, Offset);
+ }
+ GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) {
+ return dyn_cast<GlobalObject>(
+ getAliasee()->stripAndAccumulateInBoundsConstantOffsets(DL, Offset));
}
static bool isValidLinkage(LinkageTypes L) {
diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h
index 3bc8b85..2e042f4 100644
--- a/include/llvm/IR/GlobalObject.h
+++ b/include/llvm/IR/GlobalObject.h
@@ -20,7 +20,7 @@
#include "llvm/IR/GlobalValue.h"
namespace llvm {
-
+class Comdat;
class Module;
class GlobalObject : public GlobalValue {
@@ -29,21 +29,27 @@ class GlobalObject : public GlobalValue {
protected:
GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
LinkageTypes Linkage, const Twine &Name)
- : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name) {
+ : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name), ObjComdat(nullptr) {
setGlobalValueSubClassData(0);
}
std::string Section; // Section to emit this into, empty means default
+ Comdat *ObjComdat;
public:
unsigned getAlignment() const {
return (1u << getGlobalValueSubClassData()) >> 1;
}
void setAlignment(unsigned Align);
- bool hasSection() const { return !getSection().empty(); }
- const std::string &getSection() const { return Section; }
+ bool hasSection() const { return !StringRef(getSection()).empty(); }
+ const char *getSection() const { return Section.c_str(); }
void setSection(StringRef S);
+ bool hasComdat() const { return getComdat() != nullptr; }
+ const Comdat *getComdat() const { return ObjComdat; }
+ Comdat *getComdat() { return ObjComdat; }
+ void setComdat(Comdat *C) { ObjComdat = C; }
+
void copyAttributesFrom(const GlobalValue *Src) override;
// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index 10df372..68e410b 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -23,6 +23,7 @@
namespace llvm {
+class Comdat;
class PointerType;
class Module;
@@ -63,7 +64,8 @@ protected:
LinkageTypes Linkage, const Twine &Name)
: Constant(Ty, VTy, Ops, NumOps), Linkage(Linkage),
Visibility(DefaultVisibility), UnnamedAddr(0),
- DllStorageClass(DefaultStorageClass), Parent(nullptr) {
+ DllStorageClass(DefaultStorageClass),
+ ThreadLocal(NotThreadLocal), Parent(nullptr) {
setName(Name);
}
@@ -74,21 +76,32 @@ protected:
unsigned UnnamedAddr : 1; // This value's address is not significant
unsigned DllStorageClass : 2; // DLL storage class
+ unsigned ThreadLocal : 3; // Is this symbol "Thread Local", if so, what is
+ // the desired model?
+
private:
// Give subclasses access to what otherwise would be wasted padding.
- // (22 + 2 + 1 + 2 + 5) == 32.
- unsigned SubClassData : 22;
+ // (19 + 3 + 2 + 1 + 2 + 5) == 32.
+ unsigned SubClassData : 19;
protected:
unsigned getGlobalValueSubClassData() const {
return SubClassData;
}
void setGlobalValueSubClassData(unsigned V) {
- assert(V < (1 << 22) && "It will not fit");
+ assert(V < (1 << 19) && "It will not fit");
SubClassData = V;
}
Module *Parent; // The containing module.
public:
+ enum ThreadLocalMode {
+ NotThreadLocal = 0,
+ GeneralDynamicTLSModel,
+ LocalDynamicTLSModel,
+ InitialExecTLSModel,
+ LocalExecTLSModel
+ };
+
~GlobalValue() {
removeDeadConstantUsers(); // remove any dead constants using this.
}
@@ -98,6 +111,12 @@ public:
bool hasUnnamedAddr() const { return UnnamedAddr; }
void setUnnamedAddr(bool Val) { UnnamedAddr = Val; }
+ bool hasComdat() const { return getComdat() != nullptr; }
+ Comdat *getComdat();
+ const Comdat *getComdat() const {
+ return const_cast<GlobalValue *>(this)->getComdat();
+ }
+
VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); }
bool hasDefaultVisibility() const { return Visibility == DefaultVisibility; }
bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
@@ -110,6 +129,19 @@ public:
Visibility = V;
}
+ /// If the value is "Thread Local", its value isn't shared by the threads.
+ bool isThreadLocal() const { return getThreadLocalMode() != NotThreadLocal; }
+ void setThreadLocal(bool Val) {
+ setThreadLocalMode(Val ? GeneralDynamicTLSModel : NotThreadLocal);
+ }
+ void setThreadLocalMode(ThreadLocalMode Val) {
+ assert(Val == NotThreadLocal || getValueID() != Value::FunctionVal);
+ ThreadLocal = Val;
+ }
+ ThreadLocalMode getThreadLocalMode() const {
+ return static_cast<ThreadLocalMode>(ThreadLocal);
+ }
+
DLLStorageClassTypes getDLLStorageClass() const {
return DLLStorageClassTypes(DllStorageClass);
}
@@ -121,8 +153,14 @@ public:
}
void setDLLStorageClass(DLLStorageClassTypes C) { DllStorageClass = C; }
- bool hasSection() const { return !getSection().empty(); }
- const std::string &getSection() const;
+ bool hasSection() const { return !StringRef(getSection()).empty(); }
+ // It is unfortunate that we have to use "char *" in here since this is
+ // always non NULL, but:
+ // * The C API expects a null terminated string, so we cannot use StringRef.
+ // * The C API expects us to own it, so we cannot use a std:string.
+ // * For GlobalAliases we can fail to find the section and we have to
+ // return "", so we cannot use a "const std::string &".
+ const char *getSection() const;
/// Global values are always pointers.
inline PointerType *getType() const {
@@ -142,6 +180,9 @@ public:
static bool isAvailableExternallyLinkage(LinkageTypes Linkage) {
return Linkage == AvailableExternallyLinkage;
}
+ static bool isLinkOnceODRLinkage(LinkageTypes Linkage) {
+ return Linkage == LinkOnceODRLinkage;
+ }
static bool isLinkOnceLinkage(LinkageTypes Linkage) {
return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage;
}
diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h
index 8cd4332..4189ccb 100644
--- a/include/llvm/IR/GlobalVariable.h
+++ b/include/llvm/IR/GlobalVariable.h
@@ -41,9 +41,6 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
void setParent(Module *parent);
bool isConstantGlobal : 1; // Is this a global constant?
- unsigned threadLocalMode : 3; // Is this symbol "Thread Local",
- // if so, what is the desired
- // model?
bool isExternallyInitializedConstant : 1; // Is this a global whose value
// can change from its initial
// value before global
@@ -55,14 +52,6 @@ public:
return User::operator new(s, 1);
}
- enum ThreadLocalMode {
- NotThreadLocal = 0,
- GeneralDynamicTLSModel,
- LocalDynamicTLSModel,
- InitialExecTLSModel,
- LocalExecTLSModel
- };
-
/// GlobalVariable ctor - If a parent module is specified, the global is
/// automatically inserted into the end of the specified modules global list.
GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
@@ -155,16 +144,6 @@ public:
bool isConstant() const { return isConstantGlobal; }
void setConstant(bool Val) { isConstantGlobal = Val; }
- /// If the value is "Thread Local", its value isn't shared by the threads.
- bool isThreadLocal() const { return threadLocalMode != NotThreadLocal; }
- void setThreadLocal(bool Val) {
- threadLocalMode = Val ? GeneralDynamicTLSModel : NotThreadLocal;
- }
- void setThreadLocalMode(ThreadLocalMode Val) { threadLocalMode = Val; }
- ThreadLocalMode getThreadLocalMode() const {
- return static_cast<ThreadLocalMode>(threadLocalMode);
- }
-
bool isExternallyInitialized() const {
return isExternallyInitializedConstant;
}
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index 580d333..00d3684 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -327,6 +327,11 @@ public:
return Type::getIntNTy(Context, N);
}
+ /// \brief Fetch the type representing a 16-bit floating point value.
+ Type *getHalfTy() {
+ return Type::getHalfTy(Context);
+ }
+
/// \brief Fetch the type representing a 32-bit floating point value.
Type *getFloatTy() {
return Type::getFloatTy(Context);
@@ -1464,6 +1469,30 @@ public:
Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, NumElts));
return CreateShuffleVector(V, Undef, Zeros, Name + ".splat");
}
+
+ /// \brief Return a value that has been extracted from a larger integer type.
+ Value *CreateExtractInteger(const DataLayout &DL, Value *From,
+ IntegerType *ExtractedTy, uint64_t Offset,
+ const Twine &Name) {
+ IntegerType *IntTy = cast<IntegerType>(From->getType());
+ assert(DL.getTypeStoreSize(ExtractedTy) + Offset <=
+ DL.getTypeStoreSize(IntTy) &&
+ "Element extends past full value");
+ uint64_t ShAmt = 8 * Offset;
+ Value *V = From;
+ if (DL.isBigEndian())
+ ShAmt = 8 * (DL.getTypeStoreSize(IntTy) -
+ DL.getTypeStoreSize(ExtractedTy) - Offset);
+ if (ShAmt) {
+ V = CreateLShr(V, ShAmt, Name + ".shift");
+ }
+ assert(ExtractedTy->getBitWidth() <= IntTy->getBitWidth() &&
+ "Cannot extract to a larger integer!");
+ if (ExtractedTy != IntTy) {
+ V = CreateTrunc(V, ExtractedTy, Name + ".trunc");
+ }
+ return V;
+ }
};
// Create wrappers for C Binding types (see CBindingWrapping.h).
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index 7d338a6..a590f5a 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -500,6 +500,16 @@ public:
(unsigned)V);
}
+ /// Return true if this cmpxchg may spuriously fail.
+ bool isWeak() const {
+ return getSubclassDataFromInstruction() & 0x100;
+ }
+
+ void setWeak(bool IsWeak) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~0x100) |
+ (IsWeak << 8));
+ }
+
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2311,12 +2321,14 @@ public:
(V ? 1 : 0));
}
- /// addClause - Add a catch or filter clause to the landing pad.
- void addClause(Value *ClauseVal);
+ /// Add a catch or filter clause to the landing pad.
+ void addClause(Constant *ClauseVal);
- /// getClause - Get the value of the clause at index Idx. Use isCatch/isFilter
- /// to determine what type of clause this is.
- Value *getClause(unsigned Idx) const { return OperandList[Idx + 1]; }
+ /// Get the value of the clause at index Idx. Use isCatch/isFilter to
+ /// determine what type of clause this is.
+ Constant *getClause(unsigned Idx) const {
+ return cast<Constant>(OperandList[Idx + 1]);
+ }
/// isCatch - Return 'true' if the clause and index Idx is a catch clause.
bool isCatch(unsigned Idx) const {
@@ -2649,6 +2661,9 @@ public:
assert(RHS.SI == SI && "Incompatible operators.");
return RHS.Index != Index;
}
+ Self &operator*() {
+ return *this;
+ }
};
typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock>
@@ -2729,6 +2744,17 @@ public:
ConstCaseIt case_end() const {
return ConstCaseIt(this, getNumCases());
}
+
+ /// cases - iteration adapter for range-for loops.
+ iterator_range<CaseIt> cases() {
+ return iterator_range<CaseIt>(case_begin(), case_end());
+ }
+
+ /// cases - iteration adapter for range-for loops.
+ iterator_range<ConstCaseIt> cases() const {
+ return iterator_range<ConstCaseIt>(case_begin(), case_end());
+ }
+
/// Returns an iterator that points to the default case.
/// Note: this iterator allows to resolve successor only. Attempt
/// to resolve case value causes an assertion.
diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h
index 839bbbd..b0d746b 100644
--- a/include/llvm/IR/Intrinsics.h
+++ b/include/llvm/IR/Intrinsics.h
@@ -71,6 +71,9 @@ namespace Intrinsic {
/// Map a GCC builtin name to an intrinsic ID.
ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);
+
+ /// Map a MS builtin name to an intrinsic ID.
+ ID getIntrinsicForMSBuiltin(const char *Prefix, const char *BuiltinName);
/// IITDescriptor - This is a type descriptor which explains the type
/// requirements of an intrinsic. This is returned by
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index edd1621..ae2a90c 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -226,6 +226,10 @@ class GCCBuiltin<string name> {
string GCCBuiltinName = name;
}
+class MSBuiltin<string name> {
+ string MSBuiltinName = name;
+}
+
//===--------------- Variable Argument Handling Intrinsics ----------------===//
//
diff --git a/include/llvm/IR/IntrinsicsAArch64.td b/include/llvm/IR/IntrinsicsAArch64.td
index 23757aa..e3c0fb3 100644
--- a/include/llvm/IR/IntrinsicsAArch64.td
+++ b/include/llvm/IR/IntrinsicsAArch64.td
@@ -31,6 +31,13 @@ def int_aarch64_sdiv : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
LLVMMatchType<0>], [IntrNoMem]>;
def int_aarch64_udiv : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
LLVMMatchType<0>], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// RBIT
+
+def int_aarch64_rbit : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>],
+ [IntrNoMem]>;
+
}
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td
index d19d7b8..a02d707 100644
--- a/include/llvm/IR/IntrinsicsARM.td
+++ b/include/llvm/IR/IntrinsicsARM.td
@@ -54,8 +54,12 @@ def int_arm_ldaexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty]>;
//===----------------------------------------------------------------------===//
// Data barrier instructions
-def int_arm_dmb : GCCBuiltin<"__builtin_arm_dmb">, Intrinsic<[], [llvm_i32_ty]>;
-def int_arm_dsb : GCCBuiltin<"__builtin_arm_dsb">, Intrinsic<[], [llvm_i32_ty]>;
+def int_arm_dmb : GCCBuiltin<"__builtin_arm_dmb">, MSBuiltin<"__dmb">,
+ Intrinsic<[], [llvm_i32_ty]>;
+def int_arm_dsb : GCCBuiltin<"__builtin_arm_dsb">, MSBuiltin<"__dsb">,
+ Intrinsic<[], [llvm_i32_ty]>;
+def int_arm_isb : GCCBuiltin<"__builtin_arm_isb">, MSBuiltin<"__isb">,
+ Intrinsic<[], [llvm_i32_ty]>;
//===----------------------------------------------------------------------===//
// VFP
@@ -74,17 +78,21 @@ def int_arm_vcvtru : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty],
// Move to coprocessor
def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">,
+ MSBuiltin<"_MoveToCoprocessor">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">,
+ MSBuiltin<"_MoveToCoprocessor2">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
// Move from coprocessor
def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">,
+ MSBuiltin<"_MoveFromCoprocessor">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty], []>;
def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">,
+ MSBuiltin<"_MoveFromCoprocessor2">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty], []>;
@@ -126,6 +134,11 @@ def int_arm_crc32cw : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
def int_arm_hint : Intrinsic<[], [llvm_i32_ty]>;
//===----------------------------------------------------------------------===//
+// RBIT
+
+def int_arm_rbit : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
// UND (reserved undefined sequence)
def int_arm_undefined : Intrinsic<[], [llvm_i32_ty]>;
diff --git a/include/llvm/IR/IntrinsicsNVVM.td b/include/llvm/IR/IntrinsicsNVVM.td
index 26dc70a..6baf018 100644
--- a/include/llvm/IR/IntrinsicsNVVM.td
+++ b/include/llvm/IR/IntrinsicsNVVM.td
@@ -796,26 +796,25 @@ def llvm_anyi64ptr_ty : LLVMAnyPointerType<llvm_i64_ty>; // (space)i64*
// Generated within nvvm. Use for ldu on sm_20 or later
-// @TODO: Revisit this, Changed LLVMAnyPointerType to LLVMPointerType
def int_nvvm_ldu_global_i : Intrinsic<[llvm_anyint_ty],
- [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
"llvm.nvvm.ldu.global.i">;
def int_nvvm_ldu_global_f : Intrinsic<[llvm_anyfloat_ty],
- [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
"llvm.nvvm.ldu.global.f">;
def int_nvvm_ldu_global_p : Intrinsic<[llvm_anyptr_ty],
- [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
"llvm.nvvm.ldu.global.p">;
// Generated within nvvm. Use for ldg on sm_35 or later
def int_nvvm_ldg_global_i : Intrinsic<[llvm_anyint_ty],
- [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
"llvm.nvvm.ldg.global.i">;
def int_nvvm_ldg_global_f : Intrinsic<[llvm_anyfloat_ty],
- [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
"llvm.nvvm.ldg.global.f">;
def int_nvvm_ldg_global_p : Intrinsic<[llvm_anyptr_ty],
- [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
"llvm.nvvm.ldg.global.p">;
// Use for generic pointers
@@ -889,6 +888,157 @@ def int_nvvm_compiler_error :
def int_nvvm_compiler_warn :
Intrinsic<[], [llvm_anyptr_ty], [], "llvm.nvvm.compiler.warn">;
+def int_nvvm_reflect :
+ Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.reflect">;
+
+// isspacep.{const, global, local, shared}
+def int_nvvm_isspacep_const
+ : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty], [IntrNoMem],
+ "llvm.nvvm.isspacep.const">,
+ GCCBuiltin<"__nvvm_isspacep_const">;
+def int_nvvm_isspacep_global
+ : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty], [IntrNoMem],
+ "llvm.nvvm.isspacep.global">,
+ GCCBuiltin<"__nvvm_isspacep_global">;
+def int_nvvm_isspacep_local
+ : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty], [IntrNoMem],
+ "llvm.nvvm.isspacep.local">,
+ GCCBuiltin<"__nvvm_isspacep_local">;
+def int_nvvm_isspacep_shared
+ : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty], [IntrNoMem],
+ "llvm.nvvm.isspacep.shared">,
+ GCCBuiltin<"__nvvm_isspacep_shared">;
+
+// Environment register read
+def int_nvvm_read_ptx_sreg_envreg0
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg0">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg0">;
+def int_nvvm_read_ptx_sreg_envreg1
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg1">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg1">;
+def int_nvvm_read_ptx_sreg_envreg2
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg2">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg2">;
+def int_nvvm_read_ptx_sreg_envreg3
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg3">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg3">;
+def int_nvvm_read_ptx_sreg_envreg4
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg4">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg4">;
+def int_nvvm_read_ptx_sreg_envreg5
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg5">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg5">;
+def int_nvvm_read_ptx_sreg_envreg6
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg6">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg6">;
+def int_nvvm_read_ptx_sreg_envreg7
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg7">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg7">;
+def int_nvvm_read_ptx_sreg_envreg8
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg8">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg8">;
+def int_nvvm_read_ptx_sreg_envreg9
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg9">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg9">;
+def int_nvvm_read_ptx_sreg_envreg10
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg10">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg10">;
+def int_nvvm_read_ptx_sreg_envreg11
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg11">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg11">;
+def int_nvvm_read_ptx_sreg_envreg12
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg12">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg12">;
+def int_nvvm_read_ptx_sreg_envreg13
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg13">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg13">;
+def int_nvvm_read_ptx_sreg_envreg14
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg14">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg14">;
+def int_nvvm_read_ptx_sreg_envreg15
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg15">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg15">;
+def int_nvvm_read_ptx_sreg_envreg16
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg16">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg16">;
+def int_nvvm_read_ptx_sreg_envreg17
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg17">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg17">;
+def int_nvvm_read_ptx_sreg_envreg18
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg18">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg18">;
+def int_nvvm_read_ptx_sreg_envreg19
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg19">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg19">;
+def int_nvvm_read_ptx_sreg_envreg20
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg20">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg20">;
+def int_nvvm_read_ptx_sreg_envreg21
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg21">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg21">;
+def int_nvvm_read_ptx_sreg_envreg22
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg22">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg22">;
+def int_nvvm_read_ptx_sreg_envreg23
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg23">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg23">;
+def int_nvvm_read_ptx_sreg_envreg24
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg24">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg24">;
+def int_nvvm_read_ptx_sreg_envreg25
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg25">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg25">;
+def int_nvvm_read_ptx_sreg_envreg26
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg26">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg26">;
+def int_nvvm_read_ptx_sreg_envreg27
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg27">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg27">;
+def int_nvvm_read_ptx_sreg_envreg28
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg28">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg28">;
+def int_nvvm_read_ptx_sreg_envreg29
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg29">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg29">;
+def int_nvvm_read_ptx_sreg_envreg30
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg30">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg30">;
+def int_nvvm_read_ptx_sreg_envreg31
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+ "llvm.nvvm.read.ptx.sreg.envreg31">,
+ GCCBuiltin<"__nvvm_read_ptx_sreg_envreg31">;
+
// Texture Fetch
def int_nvvm_tex_1d_v4f32_i32
@@ -1800,6 +1950,25 @@ def int_nvvm_sust_p_3d_v4i32_trap
"llvm.nvvm.sust.p.3d.v4i32.trap">,
GCCBuiltin<"__nvvm_sust_p_3d_v4i32_trap">;
+def int_nvvm_rotate_b32
+ : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem], "llvm.nvvm.rotate.b32">,
+ GCCBuiltin<"__nvvm_rotate_b32">;
+
+def int_nvvm_rotate_b64
+ :Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty],
+ [IntrNoMem], "llvm.nvvm.rotate.b64">,
+ GCCBuiltin<"__nvvm_rotate_b64">;
+
+def int_nvvm_rotate_right_b64
+ : Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty],
+ [IntrNoMem], "llvm.nvvm.rotate.right.b64">,
+ GCCBuiltin<"__nvvm_rotate_right_b64">;
+
+def int_nvvm_swap_lo_hi_b64
+ : Intrinsic<[llvm_i64_ty], [llvm_i64_ty],
+ [IntrNoMem], "llvm.nvvm.swap.lo.hi.b64">,
+ GCCBuiltin<"__nvvm_swap_lo_hi_b64">;
// Old PTX back-end intrinsics retained here for backwards-compatibility
diff --git a/include/llvm/IR/IntrinsicsR600.td b/include/llvm/IR/IntrinsicsR600.td
index ecb5668..ba69eaa 100644
--- a/include/llvm/IR/IntrinsicsR600.td
+++ b/include/llvm/IR/IntrinsicsR600.td
@@ -33,4 +33,40 @@ defm int_r600_read_tgid : R600ReadPreloadRegisterIntrinsic_xyz <
"__builtin_r600_read_tgid">;
defm int_r600_read_tidig : R600ReadPreloadRegisterIntrinsic_xyz <
"__builtin_r600_read_tidig">;
+
} // End TargetPrefix = "r600"
+
+let TargetPrefix = "AMDGPU" in {
+def int_AMDGPU_div_scale : GCCBuiltin<"__builtin_amdgpu_div_scale">,
+ // 1st parameter: Numerator
+ // 2nd parameter: Denominator
+ // 3rd parameter: Constant to select select between first and
+ // second. (0 = first, 1 = second).
+ Intrinsic<[llvm_anyfloat_ty, llvm_i1_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty],
+ [IntrNoMem]>;
+
+def int_AMDGPU_div_fmas : GCCBuiltin<"__builtin_amdgpu_div_fmas">,
+ Intrinsic<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+def int_AMDGPU_div_fixup : GCCBuiltin<"__builtin_amdgpu_div_fixup">,
+ Intrinsic<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+def int_AMDGPU_trig_preop : GCCBuiltin<"__builtin_amdgpu_trig_preop">,
+ Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty],
+ [IntrNoMem]>;
+
+def int_AMDGPU_rcp : GCCBuiltin<"__builtin_amdgpu_rcp">,
+ Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+
+def int_AMDGPU_rsq : GCCBuiltin<"__builtin_amdgpu_rsq">,
+ Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+
+def int_AMDGPU_rsq_clamped : GCCBuiltin<"__builtin_amdgpu_rsq_clamped">,
+ Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+
+} // End TargetPrefix = "AMDGPU"
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 36d93fe..5de9508 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -26,6 +26,12 @@ let TargetPrefix = "x86" in {
Intrinsic<[llvm_i64_ty], [llvm_ptr_ty], [IntrReadWriteArgMem]>;
}
+// Read Performance-Monitoring Counter.
+let TargetPrefix = "x86" in {
+ def int_x86_rdpmc : GCCBuiltin<"__builtin_ia32_rdpmc">,
+ Intrinsic<[llvm_i64_ty], [llvm_i32_ty], []>;
+}
+
//===----------------------------------------------------------------------===//
// 3DNow!
@@ -667,6 +673,15 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_ssse3_pshuf_b_128 : GCCBuiltin<"__builtin_ia32_pshufb128">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_pshuf_d : GCCBuiltin<"__builtin_ia32_pshufd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse2_pshufl_w : GCCBuiltin<"__builtin_ia32_pshuflw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse2_pshufh_w : GCCBuiltin<"__builtin_ia32_pshufhw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i8_ty],
+ [IntrNoMem]>;
def int_x86_sse_pshuf_w : GCCBuiltin<"__builtin_ia32_pshufw">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_i8_ty],
[IntrNoMem]>;
@@ -1304,15 +1319,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Vector load with broadcast
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx_vbroadcast_ss :
- GCCBuiltin<"__builtin_ia32_vbroadcastss">,
- Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
- def int_x86_avx_vbroadcast_sd_256 :
- GCCBuiltin<"__builtin_ia32_vbroadcastsd256">,
- Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
- def int_x86_avx_vbroadcast_ss_256 :
- GCCBuiltin<"__builtin_ia32_vbroadcastss256">,
- Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
def int_x86_avx_vbroadcastf128_pd_256 :
GCCBuiltin<"__builtin_ia32_vbroadcastf128_pd256">,
Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
@@ -1948,6 +1954,8 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
llvm_i32_ty], [IntrNoMem, Commutative]>;
def int_x86_avx2_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa256">,
Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
+ def int_x86_avx512_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa512">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
}
//===----------------------------------------------------------------------===//
@@ -3141,6 +3149,16 @@ let TargetPrefix = "x86" in {
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
llvm_v8i64_ty, llvm_i8_ty],
[]>;
+ def int_x86_avx512_mask_lzcnt_d_512 :
+ GCCBuiltin<"__builtin_ia32_vplzcntd_512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty],
+ []>;
+ def int_x86_avx512_mask_lzcnt_q_512 :
+ GCCBuiltin<"__builtin_ia32_vplzcntq_512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty],
+ []>;
}
// Vector blend
diff --git a/include/llvm/IR/LegacyPassNameParser.h b/include/llvm/IR/LegacyPassNameParser.h
index b72fc4c..e2e4912 100644
--- a/include/llvm/IR/LegacyPassNameParser.h
+++ b/include/llvm/IR/LegacyPassNameParser.h
@@ -43,7 +43,7 @@ class PassNameParser : public PassRegistrationListener,
public cl::parser<const PassInfo*> {
cl::Option *Opt;
public:
- PassNameParser() : Opt(nullptr) {}
+ PassNameParser();
virtual ~PassNameParser();
void initialize(cl::Option &O) {
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index 0c309e8..26f62db 100644
--- a/include/llvm/IR/Module.h
+++ b/include/llvm/IR/Module.h
@@ -16,6 +16,7 @@
#define LLVM_IR_MODULE_H
#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/Comdat.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
@@ -23,13 +24,13 @@
#include "llvm/IR/Metadata.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
-
class FunctionType;
class GVMaterializer;
class LLVMContext;
+class RandomNumberGenerator;
class StructType;
template<typename T> struct DenseMapInfo;
template<typename KeyT, typename ValueT, typename KeyInfoT> class DenseMap;
@@ -123,6 +124,8 @@ public:
typedef iplist<GlobalAlias> AliasListType;
/// The type for the list of named metadata.
typedef ilist<NamedMDNode> NamedMDListType;
+ /// The type of the comdat "symbol" table.
+ typedef StringMap<Comdat> ComdatSymTabType;
/// The Global Variable iterator.
typedef GlobalListType::iterator global_iterator;
@@ -197,11 +200,14 @@ private:
NamedMDListType NamedMDList; ///< The named metadata in the module
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
ValueSymbolTable *ValSymTab; ///< Symbol table for values
+ ComdatSymTabType ComdatSymTab; ///< Symbol table for COMDATs
std::unique_ptr<GVMaterializer>
Materializer; ///< Used to materialize GlobalValues
std::string ModuleID; ///< Human readable identifier for the module
std::string TargetTriple; ///< Platform target triple Module compiled on
void *NamedMDSymTab; ///< NamedMDNode names.
+ // Allow lazy initialization in const method.
+ mutable RandomNumberGenerator *RNG; ///< The random number generator for this module.
// We need to keep the string because the C API expects us to own the string
// representation.
@@ -250,6 +256,11 @@ public:
/// @returns a string containing the module-scope inline assembly blocks.
const std::string &getModuleInlineAsm() const { return GlobalScopeAsm; }
+ /// Get the RandomNumberGenerator for this module. The RNG can be
+ /// seeded via -rng-seed=<uint64> and is salted with the ModuleID.
+ /// The returned RNG should not be shared across threads.
+ RandomNumberGenerator &getRNG() const;
+
/// @}
/// @name Module Level Mutators
/// @{
@@ -397,6 +408,14 @@ public:
void eraseNamedMetadata(NamedMDNode *NMD);
/// @}
+/// @name Comdat Accessors
+/// @{
+
+ /// Return the Comdat in the module with the specified name. It is created
+ /// if it didn't already exist.
+ Comdat *getOrInsertComdat(StringRef Name);
+
+/// @}
/// @name Module Flags Accessors
/// @{
@@ -454,12 +473,12 @@ public:
void Dematerialize(GlobalValue *GV);
/// Make sure all GlobalValues in this Module are fully read.
- error_code materializeAll();
+ std::error_code materializeAll();
/// Make sure all GlobalValues in this Module are fully read and clear the
/// Materializer. If the module is corrupt, this DOES NOT clear the old
/// Materializer.
- error_code materializeAllPermanently();
+ std::error_code materializeAllPermanently(bool ReleaseBuffer = false);
/// @}
/// @name Direct access to the globals list, functions list, and symbol table
@@ -497,6 +516,10 @@ public:
const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
/// Get the Module's symbol table of global variable and function identifiers.
ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; }
+ /// Get the Module's symbol table for COMDATs (constant).
+ const ComdatSymTabType &getComdatSymbolTable() const { return ComdatSymTab; }
+ /// Get the Module's symbol table for COMDATs.
+ ComdatSymTabType &getComdatSymbolTable() { return ComdatSymTab; }
/// @}
/// @name Global Variable Iteration
diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h
index bc7696b..848adae 100644
--- a/include/llvm/IR/User.h
+++ b/include/llvm/IR/User.h
@@ -39,6 +39,10 @@ class User : public Value {
friend struct HungoffOperandTraits;
virtual void anchor();
protected:
+ /// NumOperands - The number of values used by this User.
+ ///
+ unsigned NumOperands;
+
/// OperandList - This is a pointer to the array of Uses for this User.
/// For nodes of fixed arity (e.g. a binary operator) this array will live
/// prefixed to some derived class instance. For nodes of resizable variable
@@ -46,13 +50,9 @@ protected:
/// allocated and should be destroyed by the classes' virtual dtor.
Use *OperandList;
- /// NumOperands - The number of values used by this User.
- ///
- unsigned NumOperands;
-
void *operator new(size_t s, unsigned Us);
User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps)
- : Value(ty, vty), OperandList(OpList), NumOperands(NumOps) {}
+ : Value(ty, vty), NumOperands(NumOps), OperandList(OpList) {}
Use *allocHungoffUses(unsigned) const;
void dropHungoffUses() {
Use::zap(OperandList, OperandList + NumOperands, true);
diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
index 0158683..b5bbc96 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -67,6 +67,13 @@ typedef StringMapEntry<Value*> ValueName;
///
/// @brief LLVM Value Representation
class Value {
+ Type *VTy;
+ Use *UseList;
+
+ friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name.
+ friend class ValueHandleBase;
+ ValueName *Name;
+
const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast)
unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this?
protected:
@@ -77,6 +84,11 @@ protected:
unsigned char SubclassOptionalData : 7;
private:
+ /// SubclassData - This member is defined by this class, but is not used for
+ /// anything. Subclasses can use it to hold whatever state they find useful.
+ /// This field is initialized to zero by the ctor.
+ unsigned short SubclassData;
+
template <typename UseT> // UseT == 'Use' or 'const Use'
class use_iterator_impl
: public std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> {
@@ -167,18 +179,6 @@ private:
unsigned getOperandNo() const { return UI->getOperandNo(); }
};
- /// SubclassData - This member is defined by this class, but is not used for
- /// anything. Subclasses can use it to hold whatever state they find useful.
- /// This field is initialized to zero by the ctor.
- unsigned short SubclassData;
-
- Type *VTy;
- Use *UseList;
-
- friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name.
- friend class ValueHandleBase;
- ValueName *Name;
-
void operator=(const Value &) LLVM_DELETED_FUNCTION;
Value(const Value &) LLVM_DELETED_FUNCTION;
@@ -430,7 +430,7 @@ public:
/// isDereferenceablePointer - Test if this value is always a pointer to
/// allocated and suitably aligned memory for a simple load or store.
- bool isDereferenceablePointer() const;
+ bool isDereferenceablePointer(const DataLayout *DL = nullptr) const;
/// DoPHITranslation - If this value is a PHI node with CurBB as its parent,
/// return the value in the PHI node corresponding to PredBB. If not, return
diff --git a/include/llvm/IR/ValueMap.h b/include/llvm/IR/ValueMap.h
index 1503aed..43a79c7 100644
--- a/include/llvm/IR/ValueMap.h
+++ b/include/llvm/IR/ValueMap.h
@@ -45,8 +45,10 @@ class ValueMapConstIterator;
/// This class defines the default behavior for configurable aspects of
/// ValueMap<>. User Configs should inherit from this class to be as compatible
/// as possible with future versions of ValueMap.
-template<typename KeyT>
+template<typename KeyT, typename MutexT = sys::Mutex>
struct ValueMapConfig {
+ typedef MutexT mutex_type;
+
/// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's
/// false, the ValueMap will leave the original mapping in place.
enum { FollowRAUW = true };
@@ -67,7 +69,7 @@ struct ValueMapConfig {
/// and onDelete) and not inside other ValueMap methods. NULL means that no
/// mutex is necessary.
template<typename ExtraDataT>
- static sys::Mutex *getMutex(const ExtraDataT &/*Data*/) { return nullptr; }
+ static mutex_type *getMutex(const ExtraDataT &/*Data*/) { return nullptr; }
};
/// See the file comment.
@@ -85,6 +87,7 @@ public:
typedef KeyT key_type;
typedef ValueT mapped_type;
typedef std::pair<KeyT, ValueT> value_type;
+ typedef unsigned size_type;
explicit ValueMap(unsigned NumInitBuckets = 64)
: Map(NumInitBuckets), Data() {}
@@ -101,16 +104,16 @@ public:
inline const_iterator end() const { return const_iterator(Map.end()); }
bool empty() const { return Map.empty(); }
- unsigned size() const { return Map.size(); }
+ size_type size() const { return Map.size(); }
/// Grow the map so that it has at least Size buckets. Does not shrink
void resize(size_t Size) { Map.resize(Size); }
void clear() { Map.clear(); }
- /// count - Return true if the specified key is in the map.
- bool count(const KeyT &Val) const {
- return Map.find_as(Val) != Map.end();
+ /// Return 1 if the specified key is in the map, 0 otherwise.
+ size_type count(const KeyT &Val) const {
+ return Map.find_as(Val) == Map.end() ? 0 : 1;
}
iterator find(const KeyT &Val) {
@@ -212,7 +215,7 @@ public:
void deleted() override {
// Make a copy that won't get changed even when *this is destroyed.
ValueMapCallbackVH Copy(*this);
- sys::Mutex *M = Config::getMutex(Copy.Map->Data);
+ typename Config::mutex_type *M = Config::getMutex(Copy.Map->Data);
if (M)
M->acquire();
Config::onDelete(Copy.Map->Data, Copy.Unwrap()); // May destroy *this.
@@ -225,7 +228,7 @@ public:
"Invalid RAUW on key of ValueMap<>");
// Make a copy that won't get changed even when *this is destroyed.
ValueMapCallbackVH Copy(*this);
- sys::Mutex *M = Config::getMutex(Copy.Map->Data);
+ typename Config::mutex_type *M = Config::getMutex(Copy.Map->Data);
if (M)
M->acquire();
diff --git a/include/llvm/IRReader/IRReader.h b/include/llvm/IRReader/IRReader.h
index e2ae5f7..59ffc09 100644
--- a/include/llvm/IRReader/IRReader.h
+++ b/include/llvm/IRReader/IRReader.h
@@ -24,13 +24,6 @@ class MemoryBuffer;
class SMDiagnostic;
class LLVMContext;
-/// If the given MemoryBuffer holds a bitcode image, return a Module for it
-/// which does lazy deserialization of function bodies. Otherwise, attempt to
-/// parse it as LLVM Assembly and return a fully populated Module. This
-/// function *always* takes ownership of the given MemoryBuffer.
-Module *getLazyIRModule(MemoryBuffer *Buffer, SMDiagnostic &Err,
- LLVMContext &Context);
-
/// If the given file holds a bitcode image, return a Module
/// for it which does lazy deserialization of function bodies. Otherwise,
/// attempt to parse it as LLVM Assembly and return a fully populated
@@ -40,8 +33,7 @@ Module *getLazyIRFileModule(const std::string &Filename, SMDiagnostic &Err,
/// If the given MemoryBuffer holds a bitcode image, return a Module
/// for it. Otherwise, attempt to parse it as LLVM Assembly and return
-/// a Module for it. This function *always* takes ownership of the given
-/// MemoryBuffer.
+/// a Module for it. This function *never* takes ownership of Buffer.
Module *ParseIR(MemoryBuffer *Buffer, SMDiagnostic &Err, LLVMContext &Context);
/// If the given file holds a bitcode image, return a Module for it.
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 8e53615..0c840f3 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -146,6 +146,8 @@ void initializeInstCountPass(PassRegistry&);
void initializeInstNamerPass(PassRegistry&);
void initializeInternalizePassPass(PassRegistry&);
void initializeIntervalPartitionPass(PassRegistry&);
+void initializeJumpInstrTableInfoPass(PassRegistry&);
+void initializeJumpInstrTablesPass(PassRegistry&);
void initializeJumpThreadingPass(PassRegistry&);
void initializeLCSSAPass(PassRegistry&);
void initializeLICMPass(PassRegistry&);
@@ -272,6 +274,7 @@ void initializeSLPVectorizerPass(PassRegistry&);
void initializeBBVectorizePass(PassRegistry&);
void initializeMachineFunctionPrinterPassPass(PassRegistry&);
void initializeStackMapLivenessPass(PassRegistry&);
+void initializeLoadCombinePass(PassRegistry&);
}
#endif
diff --git a/include/llvm/LTO/LTOModule.h b/include/llvm/LTO/LTOModule.h
index f1b1480..c43846a 100644
--- a/include/llvm/LTO/LTOModule.h
+++ b/include/llvm/LTO/LTOModule.h
@@ -16,10 +16,10 @@
#include "llvm-c/lto.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/Object/IRObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include <string>
#include <vector>
@@ -46,9 +46,8 @@ private:
const GlobalValue *symbol;
};
- std::unique_ptr<Module> _module;
+ std::unique_ptr<object::IRObjectFile> IRFile;
std::unique_ptr<TargetMachine> _target;
- MCObjectFileInfo ObjFileInfo;
StringSet _linkeropt_strings;
std::vector<const char *> _deplibs;
std::vector<const char *> _linkeropts;
@@ -58,25 +57,22 @@ private:
StringSet _defines;
StringMap<NameAndAttributes> _undefines;
std::vector<const char*> _asm_undefines;
- MCContext _context;
- // Use mangler to add GlobalPrefix to names to match linker names.
- Mangler _mangler;
-
- LTOModule(Module *m, TargetMachine *t);
+ LTOModule(std::unique_ptr<object::IRObjectFile> Obj, TargetMachine *TM);
public:
/// Returns 'true' if the file or memory contents is LLVM bitcode.
static bool isBitcodeFile(const void *mem, size_t length);
static bool isBitcodeFile(const char *path);
- /// Returns 'true' if the file or memory contents is LLVM bitcode for the
- /// specified triple.
- static bool isBitcodeFileForTarget(const void *mem,
- size_t length,
- const char *triplePrefix);
- static bool isBitcodeFileForTarget(const char *path,
- const char *triplePrefix);
+ /// Returns 'true' if the memory buffer is LLVM bitcode for the specified
+ /// triple.
+ static bool isBitcodeForTarget(MemoryBuffer *memBuffer,
+ StringRef triplePrefix);
+
+ /// Create a MemoryBuffer from a memory range with an optional name.
+ static MemoryBuffer *makeBuffer(const void *mem, size_t length,
+ StringRef name = "");
/// Create an LTOModule. N.B. These methods take ownership of the buffer. The
/// caller must have initialized the Targets, the TargetMCs, the AsmPrinters,
@@ -86,25 +82,34 @@ public:
/// InitializeAllTargetMCs();
/// InitializeAllAsmPrinters();
/// InitializeAllAsmParsers();
- static LTOModule *makeLTOModule(const char *path, TargetOptions options,
- std::string &errMsg);
- static LTOModule *makeLTOModule(int fd, const char *path, size_t size,
- TargetOptions options, std::string &errMsg);
- static LTOModule *makeLTOModule(int fd, const char *path, size_t map_size,
- off_t offset, TargetOptions options,
- std::string &errMsg);
- static LTOModule *makeLTOModule(const void *mem, size_t length,
- TargetOptions options, std::string &errMsg,
- StringRef path = "");
+ static LTOModule *createFromFile(const char *path, TargetOptions options,
+ std::string &errMsg);
+ static LTOModule *createFromOpenFile(int fd, const char *path, size_t size,
+ TargetOptions options,
+ std::string &errMsg);
+ static LTOModule *createFromOpenFileSlice(int fd, const char *path,
+ size_t map_size, off_t offset,
+ TargetOptions options,
+ std::string &errMsg);
+ static LTOModule *createFromBuffer(const void *mem, size_t length,
+ TargetOptions options, std::string &errMsg,
+ StringRef path = "");
+
+ const Module &getModule() const {
+ return const_cast<LTOModule*>(this)->getModule();
+ }
+ Module &getModule() {
+ return IRFile->getModule();
+ }
/// Return the Module's target triple.
- const char *getTargetTriple() {
- return _module->getTargetTriple().c_str();
+ const std::string &getTargetTriple() {
+ return getModule().getTargetTriple();
}
/// Set the Module's target triple.
- void setTargetTriple(const char *triple) {
- _module->setTargetTriple(triple);
+ void setTargetTriple(StringRef Triple) {
+ getModule().setTargetTriple(Triple);
}
/// Get the number of symbols
@@ -150,9 +155,6 @@ public:
return nullptr;
}
- /// Return the Module.
- Module *getLLVVMModule() { return _module.get(); }
-
const std::vector<const char*> &getAsmUndefinedRefs() {
return _asm_undefines;
}
@@ -167,20 +169,20 @@ private:
bool parseSymbols(std::string &errMsg);
/// Add a symbol which isn't defined just yet to a list to be resolved later.
- void addPotentialUndefinedSymbol(const GlobalValue *dcl, bool isFunc);
+ void addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym,
+ bool isFunc);
/// Add a defined symbol to the list.
- void addDefinedSymbol(const GlobalValue *def, bool isFunction);
-
- /// Add a function symbol as defined to the list.
- void addDefinedFunctionSymbol(const Function *f);
+ void addDefinedSymbol(const char *Name, const GlobalValue *def,
+ bool isFunction);
/// Add a data symbol as defined to the list.
- void addDefinedDataSymbol(const GlobalValue *v);
+ void addDefinedDataSymbol(const object::BasicSymbolRef &Sym);
+ void addDefinedDataSymbol(const char*Name, const GlobalValue *v);
- /// Add global symbols from module-level ASM to the defined or undefined
- /// lists.
- bool addAsmGlobalSymbols(std::string &errMsg);
+ /// Add a function symbol as defined to the list.
+ void addDefinedFunctionSymbol(const object::BasicSymbolRef &Sym);
+ void addDefinedFunctionSymbol(const char *Name, const Function *F);
/// Add a global symbol from module-level ASM to the defined list.
void addAsmGlobalSymbol(const char *, lto_symbol_attributes scope);
@@ -200,17 +202,10 @@ private:
/// Get string that the data pointer points to.
bool objcClassNameFromExpression(const Constant *c, std::string &name);
- /// Returns 'true' if the memory buffer is for the specified target triple.
- static bool isTargetMatch(MemoryBuffer *memBuffer, const char *triplePrefix);
-
/// Create an LTOModule (private version). N.B. This method takes ownership of
/// the buffer.
- static LTOModule *makeLTOModule(MemoryBuffer *buffer, TargetOptions options,
- std::string &errMsg);
-
- /// Create a MemoryBuffer from a memory range with an optional name.
- static MemoryBuffer *makeBuffer(const void *mem, size_t length,
- StringRef name = "");
+ static LTOModule *makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer,
+ TargetOptions options, std::string &errMsg);
};
}
#endif // LTO_MODULE_H
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index 2616ebd..b2309ff 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -85,6 +85,8 @@ namespace {
(void) llvm::createIndVarSimplifyPass();
(void) llvm::createInstructionCombiningPass();
(void) llvm::createInternalizePass();
+ (void) llvm::createJumpInstrTableInfoPass();
+ (void) llvm::createJumpInstrTablesPass();
(void) llvm::createLCSSAPass();
(void) llvm::createLICMPass();
(void) llvm::createLazyValueInfoPass();
diff --git a/include/llvm/Linker/Linker.h b/include/llvm/Linker/Linker.h
index 42b2cb3..6254bbb 100644
--- a/include/llvm/Linker/Linker.h
+++ b/include/llvm/Linker/Linker.h
@@ -15,6 +15,8 @@
namespace llvm {
+class Comdat;
+class GlobalValue;
class Module;
class StringRef;
class StructType;
diff --git a/include/llvm/MC/ConstantPools.h b/include/llvm/MC/ConstantPools.h
new file mode 100644
index 0000000..2819b75
--- /dev/null
+++ b/include/llvm/MC/ConstantPools.h
@@ -0,0 +1,80 @@
+//===- ConstantPool.h - Keep track of assembler-generated ------*- 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 ConstantPool and AssemblerConstantPools classes.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_MC_CONSTANTPOOL_H
+#define LLVM_MC_CONSTANTPOOL_H
+
+#include "llvm/ADT/SmallVector.h"
+namespace llvm {
+class MCContext;
+class MCExpr;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+// A class to keep track of assembler-generated constant pools that are use to
+// implement the ldr-pseudo.
+class ConstantPool {
+ typedef SmallVector<std::pair<MCSymbol *, const MCExpr *>, 4> EntryVecTy;
+ EntryVecTy Entries;
+
+public:
+ // Initialize a new empty constant pool
+ ConstantPool() {}
+
+ // Add a new entry to the constant pool in the next slot.
+ // \param Value is the new entry to put in the constant pool.
+ //
+ // \returns a MCExpr that references the newly inserted value
+ const MCExpr *addEntry(const MCExpr *Value, MCContext &Context);
+
+ // Emit the contents of the constant pool using the provided streamer.
+ void emitEntries(MCStreamer &Streamer);
+
+ // Return true if the constant pool is empty
+ bool empty();
+};
+
+class AssemblerConstantPools {
+ // Map type used to keep track of per-Section constant pools used by the
+ // ldr-pseudo opcode. The map associates a section to its constant pool. The
+ // constant pool is a vector of (label, value) pairs. When the ldr
+ // pseudo is parsed we insert a new (label, value) pair into the constant pool
+ // for the current section and add MCSymbolRefExpr to the new label as
+ // an opcode to the ldr. After we have parsed all the user input we
+ // output the (label, value) pairs in each constant pool at the end of the
+ // section.
+ //
+ // We use the MapVector for the map type to ensure stable iteration of
+ // the sections at the end of the parse. We need to iterate over the
+ // sections in a stable order to ensure that we have print the
+ // constant pools in a deterministic order when printing an assembly
+ // file.
+ typedef MapVector<const MCSection *, ConstantPool> ConstantPoolMapTy;
+ ConstantPoolMapTy ConstantPools;
+
+public:
+ AssemblerConstantPools() {}
+ ~AssemblerConstantPools() {}
+
+ void emitAll(MCStreamer &Streamer);
+ void emitForCurrentSection(MCStreamer &Streamer);
+ const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr);
+
+private:
+ ConstantPool *getConstantPool(const MCSection *Section);
+ ConstantPool &getOrCreateConstantPool(const MCSection *Section);
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCAtom.h b/include/llvm/MC/MCAnalysis/MCAtom.h
index e9d0fba..33f3431 100644
--- a/include/llvm/MC/MCAtom.h
+++ b/include/llvm/MC/MCAnalysis/MCAtom.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCAtom.h ----------------------------------------*- C++ -*-===//
+//===-- MCAtom.h ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCATOM_H
-#define LLVM_MC_MCATOM_H
+#ifndef LLVM_MC_MCANALYSIS_MCATOM_H
+#define LLVM_MC_MCANALYSIS_MCATOM_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/MC/MCInst.h"
diff --git a/include/llvm/MC/MCFunction.h b/include/llvm/MC/MCAnalysis/MCFunction.h
index bfa470b..44fa450 100644
--- a/include/llvm/MC/MCFunction.h
+++ b/include/llvm/MC/MCAnalysis/MCFunction.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCFunction.h ------------------------------------*- C++ -*-===//
+//===-- MCFunction.h --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCFUNCTION_H
-#define LLVM_MC_MCFUNCTION_H
+#ifndef LLVM_MC_MCANALYSIS_MCFUNCTION_H
+#define LLVM_MC_MCANALYSIS_MCFUNCTION_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCInst.h"
diff --git a/include/llvm/MC/MCModule.h b/include/llvm/MC/MCAnalysis/MCModule.h
index aa389cb..cf7e2c0 100644
--- a/include/llvm/MC/MCModule.h
+++ b/include/llvm/MC/MCAnalysis/MCModule.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCModule.h - MCModule class ---------------------*- C++ -*-===//
+//===-- MCModule.h - MCModule class -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCMODULE_H
-#define LLVM_MC_MCMODULE_H
+#ifndef LLVM_MC_MCANALYSIS_MCMODULE_H
+#define LLVM_MC_MCANALYSIS_MCMODULE_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
diff --git a/include/llvm/MC/MCModuleYAML.h b/include/llvm/MC/MCAnalysis/MCModuleYAML.h
index c4ae829..4856277 100644
--- a/include/llvm/MC/MCModuleYAML.h
+++ b/include/llvm/MC/MCAnalysis/MCModuleYAML.h
@@ -13,11 +13,11 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCMODULEYAML_H
-#define LLVM_MC_MCMODULEYAML_H
+#ifndef LLVM_MC_MCANALYSIS_MCMODULEYAML_H
+#define LLVM_MC_MCANALYSIS_MCMODULEYAML_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/MC/MCModule.h"
+#include "llvm/MC/MCAnalysis/MCModule.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index f7d3be2..06e473d 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -23,546 +23,496 @@
#include <vector>
namespace llvm {
- class MCExpr;
- class MCSection;
- class MCStreamer;
- class MCSymbol;
- class MCContext;
-
- namespace ExceptionHandling {
- enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 };
+class MCExpr;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+class MCContext;
+
+namespace WinEH {
+enum class EncodingType {
+ ET_Invalid, /// Invalid
+ ET_Alpha, /// Windows Alpha
+ ET_Alpha64, /// Windows AXP64
+ ET_ARM, /// Windows NT (Windows on ARM)
+ ET_CE, /// Windows CE ARM, PowerPC, SH3, SH4
+ ET_Itanium, /// Windows x64, Windows Itanium (IA-64)
+ ET_MIPS = ET_Alpha,
+};
+}
+
+enum class ExceptionHandling {
+ None, /// No exception support
+ DwarfCFI, /// DWARF-like instruction based exceptions
+ SjLj, /// setjmp/longjmp based exceptions
+ ARM, /// ARM EHABI
+ WinEH, /// Windows Exception Handling
+};
+
+namespace LCOMM {
+enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
+}
+
+/// This class is intended to be used as a base class for asm
+/// properties and features specific to the target.
+class MCAsmInfo {
+protected:
+ //===------------------------------------------------------------------===//
+ // Properties to be set by the target writer, used to configure asm printer.
+ //
+
+ /// Pointer size in bytes. Default is 4.
+ unsigned PointerSize;
+
+ /// Size of the stack slot reserved for callee-saved registers, in bytes.
+ /// Default is same as pointer size.
+ unsigned CalleeSaveStackSlotSize;
+
+ /// True if target is little endian. Default is true.
+ bool IsLittleEndian;
+
+ /// True if target stack grow up. Default is false.
+ bool StackGrowsUp;
+
+ /// True if this target has the MachO .subsections_via_symbols directive.
+ /// Default is false.
+ bool HasSubsectionsViaSymbols;
+
+ /// True if this is a MachO target that supports the macho-specific .zerofill
+ /// directive for emitting BSS Symbols. Default is false.
+ bool HasMachoZeroFillDirective;
+
+ /// True if this is a MachO target that supports the macho-specific .tbss
+ /// directive for emitting thread local BSS Symbols. Default is false.
+ bool HasMachoTBSSDirective;
+
+ /// True if the compiler should emit a ".reference .constructors_used" or
+ /// ".reference .destructors_used" directive after the a static ctor/dtor
+ /// list. This directive is only emitted in Static relocation model. Default
+ /// is false.
+ bool HasStaticCtorDtorReferenceInStaticMode;
+
+ /// 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. Default to false.
+ bool LinkerRequiresNonEmptyDwarfLines;
+
+ /// This is the maximum possible length of an instruction, which is needed to
+ /// compute the size of an inline asm. Defaults to 4.
+ unsigned MaxInstLength;
+
+ /// Every possible instruction length is a multiple of this value. Factored
+ /// out in .debug_frame and .debug_line. Defaults to 1.
+ unsigned MinInstAlignment;
+
+ /// The '$' token, when not referencing an identifier or constant, refers to
+ /// the current PC. Defaults to false.
+ bool DollarIsPC;
+
+ /// This string, if specified, is used to separate instructions from each
+ /// other when on the same line. Defaults to ';'
+ const char *SeparatorString;
+
+ /// This indicates the comment character used by the assembler. Defaults to
+ /// "#"
+ const char *CommentString;
+
+ /// This is appended to emitted labels. Defaults to ":"
+ const char *LabelSuffix;
+
+ // Print the EH begin symbol with an assignment. Defaults to false.
+ bool UseAssignmentForEHBegin;
+
+ /// This prefix is used for globals like constant pool entries that are
+ /// completely private to the .s file and should not have names in the .o
+ /// file. Defaults to "L"
+ const char *PrivateGlobalPrefix;
+
+ /// This prefix is used for symbols that should be passed through the
+ /// assembler but be removed by the linker. This is 'l' on Darwin, currently
+ /// used for some ObjC metadata. The default of "" meast that for this system
+ /// a plain private symbol should be used. Defaults to "".
+ const char *LinkerPrivateGlobalPrefix;
+
+ /// If these are nonempty, they contain a directive to emit before and after
+ /// an inline assembly statement. Defaults to "#APP\n", "#NO_APP\n"
+ const char *InlineAsmStart;
+ const char *InlineAsmEnd;
+
+ /// These are assembly directives that tells the assembler to interpret the
+ /// following instructions differently. Defaults to ".code16", ".code32",
+ /// ".code64".
+ const char *Code16Directive;
+ const char *Code32Directive;
+ const char *Code64Directive;
+
+ /// Which dialect of an assembler variant to use. Defaults to 0
+ unsigned AssemblerDialect;
+
+ /// This is true if the assembler allows @ characters in symbol names.
+ /// Defaults to false.
+ bool AllowAtInName;
+
+ /// This is true if data region markers should be printed as
+ /// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels
+ /// instead.
+ bool UseDataRegionDirectives;
+
+ //===--- Data Emission Directives -------------------------------------===//
+
+ /// This should be set to the directive used to get some number of zero bytes
+ /// emitted to the current section. Common cases are "\t.zero\t" and
+ /// "\t.space\t". If this is set to null, the Data*bitsDirective's will be
+ /// used to emit zero bytes. Defaults to "\t.zero\t"
+ const char *ZeroDirective;
+
+ /// This directive allows emission of an ascii string with the standard C
+ /// escape characters embedded into it. Defaults to "\t.ascii\t"
+ const char *AsciiDirective;
+
+ /// If not null, this allows for special handling of zero terminated strings
+ /// on this target. This is commonly supported as ".asciz". If a target
+ /// doesn't support this, it can be set to null. Defaults to "\t.asciz\t"
+ const char *AscizDirective;
+
+ /// These directives are used to output some unit of integer data to the
+ /// current section. If a data directive is set to null, smaller data
+ /// directives will be used to emit the large sizes. Defaults to "\t.byte\t",
+ /// "\t.short\t", "\t.long\t", "\t.quad\t"
+ const char *Data8bitsDirective;
+ const char *Data16bitsDirective;
+ const char *Data32bitsDirective;
+ const char *Data64bitsDirective;
+
+ /// If non-null, a directive that is used to emit a word which should be
+ /// relocated as a 64-bit GP-relative offset, e.g. .gpdword on Mips. Defaults
+ /// to NULL.
+ const char *GPRel64Directive;
+
+ /// If non-null, a directive that is used to emit a word which should be
+ /// relocated as a 32-bit GP-relative offset, e.g. .gpword on Mips or .gprel32
+ /// on Alpha. Defaults to NULL.
+ const char *GPRel32Directive;
+
+ /// This is true if this target uses "Sun Style" syntax for section switching
+ /// ("#alloc,#write" etc) instead of the normal ELF syntax (,"a,w") in
+ /// .section directives. Defaults to false.
+ bool SunStyleELFSectionSwitchSyntax;
+
+ /// This is true if this target uses ELF '.section' directive before the
+ /// '.bss' one. It's used for PPC/Linux which doesn't support the '.bss'
+ /// directive only. Defaults to false.
+ bool UsesELFSectionDirectiveForBSS;
+
+ bool NeedsDwarfSectionOffsetDirective;
+
+ //===--- Alignment Information ----------------------------------------===//
+
+ /// If this is true (the default) then the asmprinter emits ".align N"
+ /// directives, where N is the number of bytes to align to. Otherwise, it
+ /// emits ".align log2(N)", e.g. 3 to align to an 8 byte boundary. Defaults
+ /// to true.
+ bool AlignmentIsInBytes;
+
+ /// If non-zero, this is used to fill the executable space created as the
+ /// result of a alignment directive. Defaults to 0
+ unsigned TextAlignFillValue;
+
+ //===--- Global Variable Emission Directives --------------------------===//
+
+ /// This is the directive used to declare a global entity. Defaults to NULL.
+ const char *GlobalDirective;
+
+ /// True if the assembler supports the .set directive. Defaults to true.
+ bool HasSetDirective;
+
+ /// False if the assembler requires that we use
+ /// \code
+ /// Lc = a - b
+ /// .long Lc
+ /// \endcode
+ //
+ /// instead of
+ //
+ /// \code
+ /// .long a - b
+ /// \endcode
+ ///
+ /// Defaults to true.
+ bool HasAggressiveSymbolFolding;
+
+ /// True is .comm's and .lcomms optional alignment is to be specified in bytes
+ /// instead of log2(n). Defaults to true.
+ bool COMMDirectiveAlignmentIsInBytes;
+
+ /// Describes if the .lcomm directive for the target supports an alignment
+ /// argument and how it is interpreted. Defaults to NoAlignment.
+ LCOMM::LCOMMType LCOMMDirectiveAlignmentType;
+
+ /// True if the target has .type and .size directives, this is true for most
+ /// ELF targets. Defaults to true.
+ bool HasDotTypeDotSizeDirective;
+
+ /// True if the target has a single parameter .file directive, this is true
+ /// for ELF targets. Defaults to true.
+ bool HasSingleParameterDotFile;
+
+ /// True if the target has a .ident directive, this is true for ELF targets.
+ /// Defaults to false.
+ bool HasIdentDirective;
+
+ /// True if this target supports the MachO .no_dead_strip directive. Defaults
+ /// to false.
+ bool HasNoDeadStrip;
+
+ /// This directive, if non-null, is used to declare a global as being a weak
+ /// undefined symbol. Defaults to NULL.
+ const char *WeakRefDirective;
+
+ /// True if we have a directive to declare a global as being a weak defined
+ /// symbol. Defaults to false.
+ bool HasWeakDefDirective;
+
+ /// True if we have a directive to declare a global as being a weak defined
+ /// symbol that can be hidden (unexported). Defaults to false.
+ bool HasWeakDefCanBeHiddenDirective;
+
+ /// True if we have a .linkonce directive. This is used on cygwin/mingw.
+ /// Defaults to false.
+ bool HasLinkOnceDirective;
+
+ /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
+ /// hidden visibility. Defaults to MCSA_Hidden.
+ MCSymbolAttr HiddenVisibilityAttr;
+
+ /// This attribute, if not MCSA_Invalid, is used to declare an undefined
+ /// symbol as having hidden visibility. Defaults to MCSA_Hidden.
+ MCSymbolAttr HiddenDeclarationVisibilityAttr;
+
+ /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
+ /// protected visibility. Defaults to MCSA_Protected
+ MCSymbolAttr ProtectedVisibilityAttr;
+
+ //===--- Dwarf Emission Directives -----------------------------------===//
+
+ /// True if target asm supports leb128 directives. Defaults to false.
+ bool HasLEB128;
+
+ /// True if target supports emission of debugging information. Defaults to
+ /// false.
+ bool SupportsDebugInformation;
+
+ /// Exception handling format for the target. Defaults to None.
+ ExceptionHandling ExceptionsType;
+
+ /// Windows exception handling data (.pdata) encoding. Defaults to Invalid.
+ WinEH::EncodingType WinEHEncodingType;
+
+ /// True if Dwarf2 output generally uses relocations for references to other
+ /// .debug_* sections.
+ bool DwarfUsesRelocationsAcrossSections;
+
+ /// True if DWARF FDE symbol reference relocations should be replaced by an
+ /// absolute difference.
+ bool DwarfFDESymbolsUseAbsDiff;
+
+ /// True if dwarf register numbers are printed instead of symbolic register
+ /// names in .cfi_* directives. Defaults to false.
+ bool DwarfRegNumForCFI;
+
+ /// True if target uses parens to indicate the symbol variant instead of @.
+ /// For example, foo(plt) instead of foo@plt. Defaults to false.
+ bool UseParensForSymbolVariant;
+
+ //===--- Prologue State ----------------------------------------------===//
+
+ std::vector<MCCFIInstruction> InitialFrameState;
+
+ //===--- Integrated Assembler State ----------------------------------===//
+
+ /// Should we use the integrated assembler?
+ /// The integrated assembler should be enabled by default (by the
+ /// constructors) when failing to parse a valid piece of assembly (inline
+ /// or otherwise) is considered a bug. It may then be overridden after
+ /// construction (see LLVMTargetMachine::initAsmInfo()).
+ bool UseIntegratedAssembler;
+
+ /// Compress DWARF debug sections. Defaults to false.
+ bool CompressDebugSections;
+
+public:
+ explicit MCAsmInfo();
+ virtual ~MCAsmInfo();
+
+ /// Get the pointer size in bytes.
+ unsigned getPointerSize() const { return PointerSize; }
+
+ /// Get the callee-saved register stack slot
+ /// size in bytes.
+ unsigned getCalleeSaveStackSlotSize() const {
+ return CalleeSaveStackSlotSize;
}
- namespace LCOMM {
- enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
+ /// True if the target is little endian.
+ bool isLittleEndian() const { return IsLittleEndian; }
+
+ /// True if target stack grow up.
+ bool isStackGrowthDirectionUp() const { return StackGrowsUp; }
+
+ bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
+
+ // Data directive accessors.
+
+ const char *getData8bitsDirective() const { return Data8bitsDirective; }
+ const char *getData16bitsDirective() const { return Data16bitsDirective; }
+ const char *getData32bitsDirective() const { return Data32bitsDirective; }
+ const char *getData64bitsDirective() const { return Data64bitsDirective; }
+ const char *getGPRel64Directive() const { return GPRel64Directive; }
+ const char *getGPRel32Directive() const { return GPRel32Directive; }
+
+ /// Targets can implement this method to specify a section to switch to if the
+ /// translation unit doesn't have any trampolines that require an executable
+ /// stack.
+ virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const {
+ return nullptr;
}
- /// MCAsmInfo - This class is intended to be used as a base class for asm
- /// properties and features specific to the target.
- class MCAsmInfo {
- protected:
- //===------------------------------------------------------------------===//
- // Properties to be set by the target writer, used to configure asm printer.
- //
-
- /// PointerSize - Pointer size in bytes.
- /// Default is 4.
- unsigned PointerSize;
-
- /// CalleeSaveStackSlotSize - Size of the stack slot reserved for
- /// callee-saved registers, in bytes.
- /// Default is same as pointer size.
- unsigned CalleeSaveStackSlotSize;
-
- /// IsLittleEndian - True if target is little endian.
- /// Default is true.
- bool IsLittleEndian;
-
- /// StackGrowsUp - True if target stack grow up.
- /// Default is false.
- bool StackGrowsUp;
-
- /// HasSubsectionsViaSymbols - True if this target has the MachO
- /// .subsections_via_symbols directive.
- bool HasSubsectionsViaSymbols; // Default is false.
-
- /// HasMachoZeroFillDirective - True if this is a MachO target that supports
- /// the macho-specific .zerofill directive for emitting BSS Symbols.
- bool HasMachoZeroFillDirective; // Default is false.
-
- /// HasMachoTBSSDirective - True if this is a MachO target that supports
- /// the macho-specific .tbss directive for emitting thread local BSS Symbols
- bool HasMachoTBSSDirective; // Default is false.
-
- /// HasStaticCtorDtorReferenceInStaticMode - True if the compiler should
- /// emit a ".reference .constructors_used" or ".reference .destructors_used"
- /// directive after the a static ctor/dtor list. This directive is only
- /// emitted in Static relocation model.
- bool HasStaticCtorDtorReferenceInStaticMode; // Default is false.
-
- /// LinkerRequiresNonEmptyDwarfLines - True if the linker has a bug and
- /// requires that the debug_line section be of a minimum size. In practice
- /// such a linker requires a non-empty line sequence if a file is present.
- bool LinkerRequiresNonEmptyDwarfLines; // Default to false.
-
- /// MaxInstLength - This is the maximum possible length of an instruction,
- /// which is needed to compute the size of an inline asm.
- unsigned MaxInstLength; // Defaults to 4.
-
- /// MinInstAlignment - Every possible instruction length is a multiple of
- /// this value. Factored out in .debug_frame and .debug_line.
- unsigned MinInstAlignment; // Defaults to 1.
-
- /// DollarIsPC - The '$' token, when not referencing an identifier or
- /// constant, refers to the current PC.
- bool DollarIsPC; // Defaults to false.
-
- /// SeparatorString - This string, if specified, is used to separate
- /// instructions from each other when on the same line.
- const char *SeparatorString; // Defaults to ';'
-
- /// CommentString - This indicates the comment character used by the
- /// assembler.
- const char *CommentString; // Defaults to "#"
-
- /// LabelSuffix - This is appended to emitted labels.
- const char *LabelSuffix; // Defaults to ":"
-
- /// LabelSuffix - This is appended to emitted labels.
- const char *DebugLabelSuffix; // Defaults to ":"
-
- /// This prefix is used for globals like constant pool entries that are
- /// completely private to the .s file and should not have names in the .o
- /// file.
- const char *PrivateGlobalPrefix; // Defaults to "L"
-
- /// This prefix is used for symbols that should be passed through the
- /// assembler but be removed by the linker. This is 'l' on Darwin,
- /// currently used for some ObjC metadata.
- /// The default of "" meast that for this system a plain private symbol
- /// should be used.
- const char *LinkerPrivateGlobalPrefix; // Defaults to "".
-
- /// InlineAsmStart/End - If these are nonempty, they contain a directive to
- /// emit before and after an inline assembly statement.
- const char *InlineAsmStart; // Defaults to "#APP\n"
- const char *InlineAsmEnd; // Defaults to "#NO_APP\n"
-
- /// Code16Directive, Code32Directive, Code64Directive - These are assembly
- /// directives that tells the assembler to interpret the following
- /// instructions differently.
- const char *Code16Directive; // Defaults to ".code16"
- const char *Code32Directive; // Defaults to ".code32"
- const char *Code64Directive; // Defaults to ".code64"
-
- /// AssemblerDialect - Which dialect of an assembler variant to use.
- unsigned AssemblerDialect; // Defaults to 0
-
- /// \brief This is true if the assembler allows @ characters in symbol
- /// names. Defaults to false.
- bool AllowAtInName;
-
- /// UseDataRegionDirectives - This is true if data region markers should
- /// be printed as ".data_region/.end_data_region" directives. If false,
- /// use "$d/$a" labels instead.
- bool UseDataRegionDirectives;
-
- //===--- Data Emission Directives -------------------------------------===//
-
- /// ZeroDirective - this should be set to the directive used to get some
- /// number of zero bytes emitted to the current section. Common cases are
- /// "\t.zero\t" and "\t.space\t". If this is set to null, the
- /// Data*bitsDirective's will be used to emit zero bytes.
- const char *ZeroDirective; // Defaults to "\t.zero\t"
-
- /// AsciiDirective - This directive allows emission of an ascii string with
- /// the standard C escape characters embedded into it.
- const char *AsciiDirective; // Defaults to "\t.ascii\t"
-
- /// AscizDirective - If not null, this allows for special handling of
- /// zero terminated strings on this target. This is commonly supported as
- /// ".asciz". If a target doesn't support this, it can be set to null.
- const char *AscizDirective; // Defaults to "\t.asciz\t"
-
- /// DataDirectives - These directives are used to output some unit of
- /// integer data to the current section. If a data directive is set to
- /// null, smaller data directives will be used to emit the large sizes.
- const char *Data8bitsDirective; // Defaults to "\t.byte\t"
- const char *Data16bitsDirective; // Defaults to "\t.short\t"
- const char *Data32bitsDirective; // Defaults to "\t.long\t"
- const char *Data64bitsDirective; // Defaults to "\t.quad\t"
-
- /// GPRel64Directive - if non-null, a directive that is used to emit a word
- /// which should be relocated as a 64-bit GP-relative offset, e.g. .gpdword
- /// on Mips.
- const char *GPRel64Directive; // Defaults to NULL.
-
- /// GPRel32Directive - if non-null, a directive that is used to emit a word
- /// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword
- /// on Mips or .gprel32 on Alpha.
- const char *GPRel32Directive; // Defaults to NULL.
-
- /// SunStyleELFSectionSwitchSyntax - This is true if this target uses "Sun
- /// Style" syntax for section switching ("#alloc,#write" etc) instead of the
- /// normal ELF syntax (,"a,w") in .section directives.
- bool SunStyleELFSectionSwitchSyntax; // Defaults to false.
-
- /// UsesELFSectionDirectiveForBSS - This is true if this target uses ELF
- /// '.section' directive before the '.bss' one. It's used for PPC/Linux
- /// which doesn't support the '.bss' directive only.
- bool UsesELFSectionDirectiveForBSS; // Defaults to false.
-
- bool NeedsDwarfSectionOffsetDirective;
-
- //===--- Alignment Information ----------------------------------------===//
-
- /// AlignmentIsInBytes - If this is true (the default) then the asmprinter
- /// emits ".align N" directives, where N is the number of bytes to align to.
- /// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte
- /// boundary.
- bool AlignmentIsInBytes; // Defaults to true
-
- /// TextAlignFillValue - If non-zero, this is used to fill the executable
- /// space created as the result of a alignment directive.
- unsigned TextAlignFillValue; // Defaults to 0
+ virtual const MCExpr *getExprForPersonalitySymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
+
+ virtual const MCExpr *getExprForFDESymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
+
+ bool usesSunStyleELFSectionSwitchSyntax() const {
+ return SunStyleELFSectionSwitchSyntax;
+ }
- //===--- Global Variable Emission Directives --------------------------===//
+ bool usesELFSectionDirectiveForBSS() const {
+ return UsesELFSectionDirectiveForBSS;
+ }
+
+ bool needsDwarfSectionOffsetDirective() const {
+ return NeedsDwarfSectionOffsetDirective;
+ }
+
+ // Accessors.
+
+ bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
+ bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
+ bool hasStaticCtorDtorReferenceInStaticMode() const {
+ return HasStaticCtorDtorReferenceInStaticMode;
+ }
+ bool getLinkerRequiresNonEmptyDwarfLines() const {
+ return LinkerRequiresNonEmptyDwarfLines;
+ }
+ unsigned getMaxInstLength() const { return MaxInstLength; }
+ unsigned getMinInstAlignment() const { return MinInstAlignment; }
+ bool getDollarIsPC() const { return DollarIsPC; }
+ const char *getSeparatorString() const { return SeparatorString; }
+
+ /// This indicates the column (zero-based) at which asm comments should be
+ /// printed.
+ unsigned getCommentColumn() const { return 40; }
+
+ const char *getCommentString() const { return CommentString; }
+ const char *getLabelSuffix() const { return LabelSuffix; }
+
+ bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; }
+ const char *getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; }
+ bool hasLinkerPrivateGlobalPrefix() const {
+ return LinkerPrivateGlobalPrefix[0] != '\0';
+ }
+ const char *getLinkerPrivateGlobalPrefix() const {
+ if (hasLinkerPrivateGlobalPrefix())
+ return LinkerPrivateGlobalPrefix;
+ return getPrivateGlobalPrefix();
+ }
+ const char *getInlineAsmStart() const { return InlineAsmStart; }
+ const char *getInlineAsmEnd() const { return InlineAsmEnd; }
+ const char *getCode16Directive() const { return Code16Directive; }
+ const char *getCode32Directive() const { return Code32Directive; }
+ const char *getCode64Directive() const { return Code64Directive; }
+ unsigned getAssemblerDialect() const { return AssemblerDialect; }
+ bool doesAllowAtInName() const { return AllowAtInName; }
+ bool doesSupportDataRegionDirectives() const {
+ return UseDataRegionDirectives;
+ }
+ const char *getZeroDirective() const { return ZeroDirective; }
+ const char *getAsciiDirective() const { return AsciiDirective; }
+ const char *getAscizDirective() const { return AscizDirective; }
+ bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; }
+ unsigned getTextAlignFillValue() const { return TextAlignFillValue; }
+ const char *getGlobalDirective() const { return GlobalDirective; }
+ bool hasSetDirective() const { return HasSetDirective; }
+ bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; }
+ bool getCOMMDirectiveAlignmentIsInBytes() const {
+ return COMMDirectiveAlignmentIsInBytes;
+ }
+ LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const {
+ return LCOMMDirectiveAlignmentType;
+ }
+ bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; }
+ bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
+ bool hasIdentDirective() const { return HasIdentDirective; }
+ bool hasNoDeadStrip() const { return HasNoDeadStrip; }
+ const char *getWeakRefDirective() const { return WeakRefDirective; }
+ bool hasWeakDefDirective() const { return HasWeakDefDirective; }
+ bool hasWeakDefCanBeHiddenDirective() const {
+ return HasWeakDefCanBeHiddenDirective;
+ }
+ bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
- /// GlobalDirective - This is the directive used to declare a global entity.
- ///
- const char *GlobalDirective; // Defaults to NULL.
-
- /// HasSetDirective - True if the assembler supports the .set directive.
- bool HasSetDirective; // Defaults to true.
-
- /// HasAggressiveSymbolFolding - False if the assembler requires that we use
- /// Lc = a - b
- /// .long Lc
- /// instead of
- /// .long a - b
- bool HasAggressiveSymbolFolding; // Defaults to true.
+ MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr; }
+ MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
+ return HiddenDeclarationVisibilityAttr;
+ }
+ MCSymbolAttr getProtectedVisibilityAttr() const {
+ return ProtectedVisibilityAttr;
+ }
+ bool hasLEB128() const { return HasLEB128; }
+ bool doesSupportDebugInformation() const { return SupportsDebugInformation; }
+ bool doesSupportExceptionHandling() const {
+ return ExceptionsType != ExceptionHandling::None;
+ }
+ ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; }
+ WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; }
+ bool isExceptionHandlingDwarf() const {
+ return (ExceptionsType == ExceptionHandling::DwarfCFI ||
+ ExceptionsType == ExceptionHandling::ARM ||
+ // Windows handler data still uses DWARF LSDA encoding.
+ ExceptionsType == ExceptionHandling::WinEH);
+ }
+ bool doesDwarfUseRelocationsAcrossSections() const {
+ return DwarfUsesRelocationsAcrossSections;
+ }
+ bool doDwarfFDESymbolsUseAbsDiff() const { return DwarfFDESymbolsUseAbsDiff; }
+ bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; }
+ bool useParensForSymbolVariant() const { return UseParensForSymbolVariant; }
- /// COMMDirectiveAlignmentIsInBytes - True is .comm's and .lcomms optional
- /// alignment is to be specified in bytes instead of log2(n).
- bool COMMDirectiveAlignmentIsInBytes; // Defaults to true;
+ void addInitialFrameState(const MCCFIInstruction &Inst) {
+ InitialFrameState.push_back(Inst);
+ }
- /// LCOMMDirectiveAlignment - Describes if the .lcomm directive for the
- /// target supports an alignment argument and how it is interpreted.
- LCOMM::LCOMMType LCOMMDirectiveAlignmentType; // Defaults to NoAlignment.
-
- /// HasDotTypeDotSizeDirective - True if the target has .type and .size
- /// directives, this is true for most ELF targets.
- bool HasDotTypeDotSizeDirective; // Defaults to true.
+ const std::vector<MCCFIInstruction> &getInitialFrameState() const {
+ return InitialFrameState;
+ }
- /// HasSingleParameterDotFile - True if the target has a single parameter
- /// .file directive, this is true for ELF targets.
- bool HasSingleParameterDotFile; // Defaults to true.
+ /// Return true if assembly (inline or otherwise) should be parsed.
+ bool useIntegratedAssembler() const { return UseIntegratedAssembler; }
- /// hasIdentDirective - True if the target has a .ident directive, this is
- /// true for ELF targets.
- bool HasIdentDirective; // Defaults to false.
+ /// Set whether assembly (inline or otherwise) should be parsed.
+ virtual void setUseIntegratedAssembler(bool Value) {
+ UseIntegratedAssembler = Value;
+ }
- /// HasNoDeadStrip - True if this target supports the MachO .no_dead_strip
- /// directive.
- bool HasNoDeadStrip; // Defaults to false.
+ bool compressDebugSections() const { return CompressDebugSections; }
- /// WeakRefDirective - This directive, if non-null, is used to declare a
- /// global as being a weak undefined symbol.
- const char *WeakRefDirective; // Defaults to NULL.
-
- /// True if we have a directive to declare a global as being a weak
- /// defined symbol.
- bool HasWeakDefDirective; // Defaults to false.
-
- /// True if we have a directive to declare a global as being a weak
- /// defined symbol that can be hidden (unexported).
- bool HasWeakDefCanBeHiddenDirective; // Defaults to false.
-
- /// True if we have a .linkonce directive. This is used on cygwin/mingw.
- bool HasLinkOnceDirective; // Defaults to false.
-
- /// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to
- /// declare a symbol as having hidden visibility.
- MCSymbolAttr HiddenVisibilityAttr; // Defaults to MCSA_Hidden.
-
- /// HiddenDeclarationVisibilityAttr - This attribute, if not MCSA_Invalid,
- /// is used to declare an undefined symbol as having hidden visibility.
- MCSymbolAttr HiddenDeclarationVisibilityAttr; // Defaults to MCSA_Hidden.
-
-
- /// ProtectedVisibilityAttr - This attribute, if not MCSA_Invalid, is used
- /// to declare a symbol as having protected visibility.
- MCSymbolAttr ProtectedVisibilityAttr; // Defaults to MCSA_Protected
-
- //===--- Dwarf Emission Directives -----------------------------------===//
-
- /// HasLEB128 - True if target asm supports leb128 directives.
- bool HasLEB128; // Defaults to false.
-
- /// SupportsDebugInformation - True if target supports emission of debugging
- /// information.
- bool SupportsDebugInformation; // Defaults to false.
-
- /// SupportsExceptionHandling - True if target supports exception handling.
- ExceptionHandling::ExceptionsType ExceptionsType; // Defaults to None
-
- /// DwarfUsesRelocationsAcrossSections - True if Dwarf2 output generally
- /// uses relocations for references to other .debug_* sections.
- bool DwarfUsesRelocationsAcrossSections;
-
- /// DwarfFDESymbolsUseAbsDiff - true if DWARF FDE symbol reference
- /// relocations should be replaced by an absolute difference.
- bool DwarfFDESymbolsUseAbsDiff;
-
- /// DwarfRegNumForCFI - True if dwarf register numbers are printed
- /// instead of symbolic register names in .cfi_* directives.
- bool DwarfRegNumForCFI; // Defaults to false;
-
- /// UseParensForSymbolVariant - True if target uses parens to indicate the
- /// symbol variant instead of @. For example, foo(plt) instead of foo@plt.
- bool UseParensForSymbolVariant; // Defaults to false;
-
- //===--- Prologue State ----------------------------------------------===//
-
- std::vector<MCCFIInstruction> InitialFrameState;
-
- //===--- Integrated Assembler State ----------------------------------===//
- /// Should we use the integrated assembler?
- /// The integrated assembler should be enabled by default (by the
- /// constructors) when failing to parse a valid piece of assembly (inline
- /// or otherwise) is considered a bug. It may then be overridden after
- /// construction (see LLVMTargetMachine::initAsmInfo()).
- bool UseIntegratedAssembler;
-
- /// Compress DWARF debug sections. Defaults to false.
- bool CompressDebugSections;
-
- public:
- explicit MCAsmInfo();
- virtual ~MCAsmInfo();
-
- /// getPointerSize - Get the pointer size in bytes.
- unsigned getPointerSize() const {
- return PointerSize;
- }
-
- /// getCalleeSaveStackSlotSize - Get the callee-saved register stack slot
- /// size in bytes.
- unsigned getCalleeSaveStackSlotSize() const {
- return CalleeSaveStackSlotSize;
- }
-
- /// isLittleEndian - True if the target is little endian.
- bool isLittleEndian() const {
- return IsLittleEndian;
- }
-
- /// isStackGrowthDirectionUp - True if target stack grow up.
- bool isStackGrowthDirectionUp() const {
- return StackGrowsUp;
- }
-
- bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
-
- // Data directive accessors.
- //
- const char *getData8bitsDirective() const {
- return Data8bitsDirective;
- }
- const char *getData16bitsDirective() const {
- return Data16bitsDirective;
- }
- const char *getData32bitsDirective() const {
- return Data32bitsDirective;
- }
- const char *getData64bitsDirective() const {
- return Data64bitsDirective;
- }
- const char *getGPRel64Directive() const { return GPRel64Directive; }
- const char *getGPRel32Directive() const { return GPRel32Directive; }
-
- /// getNonexecutableStackSection - Targets can implement this method to
- /// specify a section to switch to if the translation unit doesn't have any
- /// trampolines that require an executable stack.
- virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const{
- return nullptr;
- }
-
- virtual const MCExpr *
- getExprForPersonalitySymbol(const MCSymbol *Sym,
- unsigned Encoding,
- MCStreamer &Streamer) const;
-
- virtual const MCExpr *
- getExprForFDESymbol(const MCSymbol *Sym,
- unsigned Encoding,
- MCStreamer &Streamer) const;
-
- bool usesSunStyleELFSectionSwitchSyntax() const {
- return SunStyleELFSectionSwitchSyntax;
- }
-
- bool usesELFSectionDirectiveForBSS() const {
- return UsesELFSectionDirectiveForBSS;
- }
-
- bool needsDwarfSectionOffsetDirective() const {
- return NeedsDwarfSectionOffsetDirective;
- }
-
- // Accessors.
- //
- bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
- bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
- bool hasStaticCtorDtorReferenceInStaticMode() const {
- return HasStaticCtorDtorReferenceInStaticMode;
- }
- bool getLinkerRequiresNonEmptyDwarfLines() const {
- return LinkerRequiresNonEmptyDwarfLines;
- }
- unsigned getMaxInstLength() const {
- return MaxInstLength;
- }
- unsigned getMinInstAlignment() const {
- return MinInstAlignment;
- }
- bool getDollarIsPC() const {
- return DollarIsPC;
- }
- const char *getSeparatorString() const {
- return SeparatorString;
- }
-
- /// This indicates the column (zero-based) at which asm comments should be
- /// printed.
- unsigned getCommentColumn() const {
- return 40;
- }
-
- const char *getCommentString() const {
- return CommentString;
- }
- const char *getLabelSuffix() const {
- return LabelSuffix;
- }
-
- const char *getDebugLabelSuffix() const {
- return DebugLabelSuffix;
- }
- const char *getPrivateGlobalPrefix() const {
- return PrivateGlobalPrefix;
- }
- bool hasLinkerPrivateGlobalPrefix() const {
- return LinkerPrivateGlobalPrefix[0] != '\0';
- }
- const char *getLinkerPrivateGlobalPrefix() const {
- if (hasLinkerPrivateGlobalPrefix())
- return LinkerPrivateGlobalPrefix;
- return getPrivateGlobalPrefix();
- }
- const char *getInlineAsmStart() const {
- return InlineAsmStart;
- }
- const char *getInlineAsmEnd() const {
- return InlineAsmEnd;
- }
- const char *getCode16Directive() const {
- return Code16Directive;
- }
- const char *getCode32Directive() const {
- return Code32Directive;
- }
- const char *getCode64Directive() const {
- return Code64Directive;
- }
- unsigned getAssemblerDialect() const {
- return AssemblerDialect;
- }
- bool doesAllowAtInName() const {
- return AllowAtInName;
- }
- bool doesSupportDataRegionDirectives() const {
- return UseDataRegionDirectives;
- }
- const char *getZeroDirective() const {
- return ZeroDirective;
- }
- const char *getAsciiDirective() const {
- return AsciiDirective;
- }
- const char *getAscizDirective() const {
- return AscizDirective;
- }
- bool getAlignmentIsInBytes() const {
- return AlignmentIsInBytes;
- }
- unsigned getTextAlignFillValue() const {
- return TextAlignFillValue;
- }
- const char *getGlobalDirective() const {
- return GlobalDirective;
- }
- bool hasSetDirective() const { return HasSetDirective; }
- bool hasAggressiveSymbolFolding() const {
- return HasAggressiveSymbolFolding;
- }
- bool getCOMMDirectiveAlignmentIsInBytes() const {
- return COMMDirectiveAlignmentIsInBytes;
- }
- LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const {
- return LCOMMDirectiveAlignmentType;
- }
- bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
- bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
- bool hasIdentDirective() const { return HasIdentDirective; }
- bool hasNoDeadStrip() const { return HasNoDeadStrip; }
- const char *getWeakRefDirective() const { return WeakRefDirective; }
- bool hasWeakDefDirective() const { return HasWeakDefDirective; }
- bool hasWeakDefCanBeHiddenDirective() const {
- return HasWeakDefCanBeHiddenDirective;
- }
- bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
-
- MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;}
- MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
- return HiddenDeclarationVisibilityAttr;
- }
- MCSymbolAttr getProtectedVisibilityAttr() const {
- return ProtectedVisibilityAttr;
- }
- bool hasLEB128() const {
- return HasLEB128;
- }
- bool doesSupportDebugInformation() const {
- return SupportsDebugInformation;
- }
- bool doesSupportExceptionHandling() const {
- return ExceptionsType != ExceptionHandling::None;
- }
- ExceptionHandling::ExceptionsType getExceptionHandlingType() const {
- return ExceptionsType;
- }
- bool isExceptionHandlingDwarf() const {
- return
- (ExceptionsType == ExceptionHandling::DwarfCFI ||
- ExceptionsType == ExceptionHandling::ARM ||
- ExceptionsType == ExceptionHandling::Win64);
- }
- bool doesDwarfUseRelocationsAcrossSections() const {
- return DwarfUsesRelocationsAcrossSections;
- }
- bool doDwarfFDESymbolsUseAbsDiff() const {
- return DwarfFDESymbolsUseAbsDiff;
- }
- bool useDwarfRegNumForCFI() const {
- return DwarfRegNumForCFI;
- }
- bool useParensForSymbolVariant() const {
- return UseParensForSymbolVariant;
- }
-
- void addInitialFrameState(const MCCFIInstruction &Inst) {
- InitialFrameState.push_back(Inst);
- }
-
- const std::vector<MCCFIInstruction> &getInitialFrameState() const {
- return InitialFrameState;
- }
-
- /// Return true if assembly (inline or otherwise) should be parsed.
- bool useIntegratedAssembler() const { return UseIntegratedAssembler; }
-
- /// Set whether assembly (inline or otherwise) should be parsed.
- virtual void setUseIntegratedAssembler(bool Value) {
- UseIntegratedAssembler = Value;
- }
-
- bool compressDebugSections() const { return CompressDebugSections; }
-
- void setCompressDebugSections(bool CompressDebugSections) {
- this->CompressDebugSections = CompressDebugSections;
- }
- };
+ void setCompressDebugSections(bool CompressDebugSections) {
+ this->CompressDebugSections = CompressDebugSections;
+ }
+};
}
#endif
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index be13b36..1cb34c2 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -802,7 +802,7 @@ public:
/// @}
- void dump();
+ void dump() const;
};
// FIXME: This really doesn't belong here. See comments below.
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 7557e76..eb0340f 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -11,15 +11,18 @@
#define LLVM_MC_MCCONTEXT_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
+#include <tuple>
#include <vector> // FIXME: Shouldn't be needed.
namespace llvm {
@@ -129,11 +132,10 @@ namespace llvm {
/// assembly source files.
unsigned GenDwarfFileNumber;
- /// The default initial text section that we generate dwarf debugging line
- /// info for when generating dwarf assembly source files.
- const MCSection *GenDwarfSection;
- /// Symbols created for the start and end of this section.
- MCSymbol *GenDwarfSectionStartSym, *GenDwarfSectionEndSym;
+ /// Symbols created for the start and end of each section, used for
+ /// generating the .debug_ranges and .debug_aranges sections.
+ MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> >
+ SectionStartEndSyms;
/// The information gathered from labels that will have dwarf label
/// entries when generating dwarf assembly source files.
@@ -159,10 +161,11 @@ namespace llvm {
unsigned DwarfCompileUnitID;
typedef std::pair<std::string, std::string> SectionGroupPair;
+ typedef std::tuple<std::string, std::string, int> SectionGroupTriple;
StringMap<const MCSectionMachO*> MachOUniquingMap;
std::map<SectionGroupPair, const MCSectionELF *> ELFUniquingMap;
- std::map<SectionGroupPair, const MCSectionCOFF *> COFFUniquingMap;
+ std::map<SectionGroupTriple, const MCSectionCOFF *> COFFUniquingMap;
/// Do automatic reset in destructor
bool AutoReset;
@@ -273,9 +276,7 @@ namespace llvm {
const MCSectionCOFF *getCOFFSection(StringRef Section,
unsigned Characteristics,
SectionKind Kind,
- StringRef COMDATSymName,
- int Selection,
- const MCSectionCOFF *Assoc = nullptr);
+ StringRef COMDATSymName, int Selection);
const MCSectionCOFF *getCOFFSection(StringRef Section,
unsigned Characteristics,
@@ -376,16 +377,18 @@ namespace llvm {
void setGenDwarfFileNumber(unsigned FileNumber) {
GenDwarfFileNumber = FileNumber;
}
- const MCSection *getGenDwarfSection() { return GenDwarfSection; }
- void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; }
- MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; }
- void setGenDwarfSectionStartSym(MCSymbol *Sym) {
- GenDwarfSectionStartSym = Sym;
+ MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> > &
+ getGenDwarfSectionSyms() {
+ return SectionStartEndSyms;
}
- MCSymbol *getGenDwarfSectionEndSym() { return GenDwarfSectionEndSym; }
- void setGenDwarfSectionEndSym(MCSymbol *Sym) {
- GenDwarfSectionEndSym = Sym;
+ std::pair<MapVector<const MCSection *,
+ std::pair<MCSymbol *, MCSymbol *> >::iterator,
+ bool>
+ addGenDwarfSection(const MCSection *Sec) {
+ return SectionStartEndSyms.insert(
+ std::make_pair(Sec, std::make_pair(nullptr, nullptr)));
}
+ void finalizeDwarfSections(MCStreamer &MCOS);
const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const {
return MCGenDwarfLabelEntries;
}
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index 6df8a19..6cd9a9a 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -465,14 +465,13 @@ public:
struct MCDwarfFrameInfo {
MCDwarfFrameInfo()
- : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr),
- Function(nullptr), Instructions(), PersonalityEncoding(), LsdaEncoding(0),
- CompactUnwindEncoding(0), IsSignalFrame(false), IsSimple(false) {}
+ : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr),
+ Instructions(), PersonalityEncoding(), LsdaEncoding(0),
+ CompactUnwindEncoding(0), IsSignalFrame(false), IsSimple(false) {}
MCSymbol *Begin;
MCSymbol *End;
const MCSymbol *Personality;
const MCSymbol *Lsda;
- const MCSymbol *Function;
std::vector<MCCFIInstruction> Instructions;
unsigned PersonalityEncoding;
unsigned LsdaEncoding;
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
index be39128..66729fe 100644
--- a/include/llvm/MC/MCELFStreamer.h
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -48,7 +48,6 @@ public:
void ChangeSection(const MCSection *Section,
const MCExpr *Subsection) override;
void EmitLabel(MCSymbol *Symbol) override;
- void EmitDebugLabel(MCSymbol *Symbol) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitThumbFunc(MCSymbol *Func) override;
void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h
index 2f1f561..297c442 100644
--- a/include/llvm/MC/MCELFSymbolFlags.h
+++ b/include/llvm/MC/MCELFSymbolFlags.h
@@ -41,6 +41,7 @@ namespace llvm {
ELF_STT_File = (ELF::STT_FILE << ELF_STT_Shift),
ELF_STT_Common = (ELF::STT_COMMON << ELF_STT_Shift),
ELF_STT_Tls = (ELF::STT_TLS << ELF_STT_Shift),
+ ELF_STT_GnuIFunc = (ELF::STT_GNU_IFUNC << ELF_STT_Shift),
ELF_STT_Loproc = (ELF::STT_LOPROC << ELF_STT_Shift),
ELF_STT_Hiproc = (ELF::STT_HIPROC << ELF_STT_Shift),
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index ca5cecb..e96ecb4 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -21,6 +21,7 @@ class MCAssembler;
class MCContext;
class MCSection;
class MCSectionData;
+class MCStreamer;
class MCSymbol;
class MCValue;
class raw_ostream;
@@ -524,7 +525,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;
+ virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
virtual const MCSection *FindAssociatedSection() const = 0;
virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h
index 3b0d933..50fd527 100644
--- a/include/llvm/MC/MCLinkerOptimizationHint.h
+++ b/include/llvm/MC/MCLinkerOptimizationHint.h
@@ -132,8 +132,19 @@ public:
/// the given @p Layout.
uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
const MCAsmLayout &Layout) const {
- std::string Buffer;
- raw_string_ostream OutStream(Buffer);
+ class raw_counting_ostream : public raw_ostream {
+ uint64_t Count;
+
+ void write_impl(const char *, size_t size) override { Count += size; }
+
+ uint64_t current_pos() const override { return Count; }
+
+ public:
+ raw_counting_ostream() : Count(0) {}
+ ~raw_counting_ostream() { flush(); }
+ };
+
+ raw_counting_ostream OutStream;
Emit_impl(OutStream, ObjWriter, Layout);
return OutStream.tell();
}
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index e7d5bbd..12a7f0e 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -111,6 +111,8 @@ class MachObjectWriter : public MCObjectWriter {
/// @}
+ MachSymbolData *findSymbolData(const MCSymbol &Sym);
+
public:
MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
bool _IsLittleEndian)
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index 1a56040..4d1715e 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -14,13 +14,13 @@
#ifndef LLVM_MC_MCBJECTFILEINFO_H
#define LLVM_MC_MCBJECTFILEINFO_H
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/CodeGen.h"
namespace llvm {
class MCContext;
class MCSection;
class StringRef;
- class Triple;
class MCObjectFileInfo {
protected:
@@ -33,12 +33,6 @@ protected:
/// weak_definition of constant 0 for an omitted EH frame.
bool SupportsWeakOmittedEHFrame;
- /// IsFunctionEHFrameSymbolPrivate - This flag is set to true if the
- /// "EH_frame" symbol for EH information should be an assembler temporary (aka
- /// private linkage, aka an L or .L label) or false if it should be a normal
- /// non-.globl label. This defaults to true.
- bool IsFunctionEHFrameSymbolPrivate;
-
/// SupportsCompactUnwindWithoutEHFrame - True if the target object file
/// supports emitting a compact unwind section without an associated EH frame
/// section.
@@ -201,9 +195,6 @@ public:
void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
MCContext &ctx);
- bool isFunctionEHFrameSymbolPrivate() const {
- return IsFunctionEHFrameSymbolPrivate;
- }
bool getSupportsWeakOmittedEHFrame() const {
return SupportsWeakOmittedEHFrame;
}
@@ -380,6 +371,7 @@ private:
Reloc::Model RelocM;
CodeModel::Model CMModel;
MCContext *Ctx;
+ Triple TT;
void InitMachOMCObjectFileInfo(Triple T);
void InitELFMCObjectFileInfo(Triple T);
@@ -388,6 +380,9 @@ private:
/// InitEHFrameSection - Initialize EHFrameSection on demand.
///
void InitEHFrameSection();
+
+public:
+ const Triple &getTargetTriple() const { return TT; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index e41a8ba..8d37c85 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -78,16 +78,15 @@ protected:
/// fragment is not a data fragment.
MCDataFragment *getOrCreateDataFragment() const;
- const MCExpr *AddValueSymbols(const MCExpr *Value);
-
public:
+ void visitUsedSymbol(const MCSymbol &Sym) override;
+
MCAssembler &getAssembler() { return *Assembler; }
/// @name MCStreamer Interface
/// @{
void EmitLabel(MCSymbol *Symbol) override;
- void EmitDebugLabel(MCSymbol *Symbol) override;
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc = SMLoc()) override;
@@ -126,6 +125,10 @@ public:
void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
void EmitZeros(uint64_t NumBytes) override;
void FinishImpl() override;
+
+ virtual bool mayHaveInstructions() const {
+ return getCurrentSectionData()->hasInstructions();
+ }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h
index 59b5c09..0b550ba 100644
--- a/include/llvm/MC/MCParser/AsmLexer.h
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -28,7 +28,7 @@ class AsmLexer : public MCAsmLexer {
const MCAsmInfo &MAI;
const char *CurPtr;
- const MemoryBuffer *CurBuf;
+ StringRef CurBuf;
bool isAtStartOfLine;
void operator=(const AsmLexer&) LLVM_DELETED_FUNCTION;
@@ -42,7 +42,7 @@ public:
AsmLexer(const MCAsmInfo &MAI);
~AsmLexer();
- void setBuffer(const MemoryBuffer *buf, const char *ptr = nullptr);
+ void setBuffer(StringRef Buf, const char *ptr = nullptr);
StringRef LexUntilEndOfStatement() override;
StringRef LexUntilEndOfLine();
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index f751786..9836795 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -30,23 +30,24 @@ class SMRange;
class SourceMgr;
class Twine;
+class InlineAsmIdentifierInfo {
+public:
+ void *OpDecl;
+ bool IsVarDecl;
+ unsigned Length, Size, Type;
+
+ void clear() {
+ OpDecl = nullptr;
+ IsVarDecl = false;
+ Length = 1;
+ Size = 0;
+ Type = 0;
+ }
+};
+
/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser.
class MCAsmParserSemaCallback {
public:
- typedef struct {
- void *OpDecl;
- bool IsVarDecl;
- unsigned Length, Size, Type;
-
- void clear() {
- OpDecl = nullptr;
- IsVarDecl = false;
- Length = 1;
- Size = 0;
- Type = 0;
- }
- } InlineAsmIdentifierInfo;
-
virtual ~MCAsmParserSemaCallback();
virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf,
InlineAsmIdentifierInfo &Info,
@@ -56,9 +57,6 @@ public:
unsigned &Offset) = 0;
};
-typedef MCAsmParserSemaCallback::InlineAsmIdentifierInfo
- InlineAsmIdentifierInfo;
-
/// MCAsmParser - Generic assembler parser interface, for use by target specific
/// assembly parsers.
class MCAsmParser {
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index a428f9e..d205e2a 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -42,24 +42,15 @@ class MCSymbol;
/// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
mutable int Selection;
- /// Assoc - This is name of the associated section, if it is a COMDAT
- /// section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0 with an
- /// associative Selection (IMAGE_COMDAT_SELECT_ASSOCIATIVE).
- mutable const MCSectionCOFF *Assoc;
-
private:
friend class MCContext;
MCSectionCOFF(StringRef Section, unsigned Characteristics,
- const MCSymbol *COMDATSymbol, int Selection,
- const MCSectionCOFF *Assoc, SectionKind K)
+ const MCSymbol *COMDATSymbol, int Selection, SectionKind K)
: MCSection(SV_COFF, K), SectionName(Section),
Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
- Selection(Selection), Assoc(Assoc) {
+ Selection(Selection) {
assert ((Characteristics & 0x00F00000) == 0 &&
"alignment must not be set upon section creation");
- assert ((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ==
- (Assoc != nullptr) &&
- "associative COMDAT section must have an associated section");
}
~MCSectionCOFF();
@@ -76,11 +67,10 @@ class MCSymbol;
return SectionName.str() + "_end";
}
unsigned getCharacteristics() const { return Characteristics; }
+ const MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; }
int getSelection() const { return Selection; }
- const MCSectionCOFF *getAssocSection() const { return Assoc; }
- void setSelection(int Selection,
- const MCSectionCOFF *Assoc = nullptr) const;
+ void setSelection(int Selection) const;
void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
const MCExpr *Subsection) const override;
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 2a8367a..216de75 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -86,6 +86,27 @@ public:
virtual void finish();
};
+class AArch64TargetStreamer : public MCTargetStreamer {
+public:
+ AArch64TargetStreamer(MCStreamer &S);
+ ~AArch64TargetStreamer();
+
+
+ void finish() override;
+
+ /// Callback used to implement the ldr= pseudo.
+ /// Add a new entry to the constant pool for the current section and return an
+ /// MCExpr that can be used to refer to the constant pool location.
+ const MCExpr *addConstantPoolEntry(const MCExpr *);
+
+ /// Callback used to implemnt the .ltorg directive.
+ /// Emit contents of constant pool for the current section.
+ void emitCurrentConstantPool();
+
+private:
+ std::unique_ptr<AssemblerConstantPools> ConstantPools;
+};
+
// FIXME: declared here because it is used from
// lib/CodeGen/AsmPrinter/ARMException.cpp.
class ARMTargetStreamer : public MCTargetStreamer {
@@ -164,8 +185,6 @@ class MCStreamer {
void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame);
void EnsureValidW64UnwindInfo();
- MCSymbol *LastSymbol;
-
// SymbolOrdering - Tracks an index to represent the order
// a symbol was emitted in. Zero means we did not emit that symbol.
DenseMap<const MCSymbol *, unsigned> SymbolOrdering;
@@ -182,9 +201,7 @@ protected:
const MCExpr *ForceExpAbs(const MCExpr *Expr);
- void RecordProcStart(MCDwarfFrameInfo &Frame);
virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
- void RecordProcEnd(MCDwarfFrameInfo &Frame);
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame);
MCWin64EHUnwindInfo *getCurrentW64UnwindInfo() {
@@ -197,6 +214,9 @@ protected:
public:
virtual ~MCStreamer();
+ void visitUsedExpr(const MCExpr &Expr);
+ virtual void visitUsedSymbol(const MCSymbol &Sym);
+
void setTargetStreamer(MCTargetStreamer *TS) {
TargetStreamer.reset(TS);
}
@@ -223,6 +243,10 @@ public:
return *W64UnwindInfos[i];
}
+ ArrayRef<MCWin64EHUnwindInfo *> getW64UnwindInfos() const {
+ return W64UnwindInfos;
+ }
+
void generateCompactUnwindEncodings(MCAsmBackend *MAB);
/// @name Assembly File Formatting.
@@ -294,7 +318,7 @@ public:
///
/// This is called by PopSection and SwitchSection, if the current
/// section changes.
- virtual void ChangeSection(const MCSection *, const MCExpr *) = 0;
+ virtual void ChangeSection(const MCSection *, const MCExpr *);
/// pushSection - Save the current and previous section on the
/// section stack.
@@ -374,12 +398,10 @@ public:
// add the section we're emitting it to later.
virtual void EmitLabel(MCSymbol *Symbol);
- virtual void EmitDebugLabel(MCSymbol *Symbol);
-
virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol);
/// EmitAssemblerFlag - Note in the output the specified @p Flag.
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0;
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
/// EmitLinkerOptions - Emit the given list @p Options of strings as linker
/// options into the output.
@@ -394,7 +416,7 @@ public:
/// EmitThumbFunc - Note in the output that the specified @p Func is
/// a Thumb mode function (ARM target only).
- virtual void EmitThumbFunc(MCSymbol *Func) = 0;
+ virtual void EmitThumbFunc(MCSymbol *Func);
/// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
///
@@ -416,7 +438,7 @@ public:
///
/// @param Alias - The alias that is being created.
/// @param Symbol - The symbol being aliased.
- virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) = 0;
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
/// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol.
virtual bool EmitSymbolAttribute(MCSymbol *Symbol,
@@ -426,25 +448,25 @@ public:
///
/// @param Symbol - The symbol to have its n_desc field set.
/// @param DescValue - The value to set into the n_desc field.
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0;
+ virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
/// BeginCOFFSymbolDef - Start emitting COFF symbol definition
///
/// @param Symbol - The symbol to have its External & Type fields set.
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) = 0;
+ virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
/// EmitCOFFSymbolStorageClass - Emit the storage class of the symbol.
///
/// @param StorageClass - The storage class the symbol should have.
- virtual void EmitCOFFSymbolStorageClass(int StorageClass) = 0;
+ virtual void EmitCOFFSymbolStorageClass(int StorageClass);
/// EmitCOFFSymbolType - Emit the type of the symbol.
///
/// @param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h)
- virtual void EmitCOFFSymbolType(int Type) = 0;
+ virtual void EmitCOFFSymbolType(int Type);
/// EndCOFFSymbolDef - Marks the end of the symbol definition.
- virtual void EndCOFFSymbolDef() = 0;
+ virtual void EndCOFFSymbolDef();
/// EmitCOFFSectionIndex - Emits a COFF section index.
///
@@ -461,7 +483,7 @@ public:
/// This corresponds to an assembler statement such as:
/// .size symbol, expression
///
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0;
+ virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
/// \brief Emit a Linker Optimization Hint (LOH) directive.
/// \param Args - Arguments of the LOH.
@@ -482,7 +504,7 @@ public:
/// @param Size - The size of the common symbol.
/// @param ByteAlignment - The alignment of the common symbol in bytes.
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment) = 0;
+ unsigned ByteAlignment);
/// EmitZerofill - Emit the zerofill section and an optional symbol.
///
@@ -503,7 +525,7 @@ public:
/// @param ByteAlignment - The alignment of the thread local common symbol
/// if non-zero. This must be a power of 2 on some targets.
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment = 0) = 0;
+ uint64_t Size, unsigned ByteAlignment = 0);
/// @}
/// @name Generating Data
@@ -513,7 +535,7 @@ public:
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
- virtual void EmitBytes(StringRef Data) = 0;
+ virtual void EmitBytes(StringRef Data);
/// EmitValue - Emit the expression @p Value into the output as a native
/// integer of the given @p Size bytes.
@@ -526,7 +548,7 @@ public:
/// match a native machine width.
/// @param Loc - The location of the expression for error reporting.
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
- const SMLoc &Loc = SMLoc()) = 0;
+ const SMLoc &Loc = SMLoc());
void EmitValue(const MCExpr *Value, unsigned Size,
const SMLoc &Loc = SMLoc());
@@ -541,9 +563,9 @@ public:
/// .long foo
void EmitAbsValue(const MCExpr *Value, unsigned Size);
- virtual void EmitULEB128Value(const MCExpr *Value) = 0;
+ virtual void EmitULEB128Value(const MCExpr *Value);
- virtual void EmitSLEB128Value(const MCExpr *Value) = 0;
+ virtual void EmitSLEB128Value(const MCExpr *Value);
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
@@ -598,7 +620,7 @@ public:
/// emitted.
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
- unsigned MaxBytesToEmit = 0) = 0;
+ unsigned MaxBytesToEmit = 0);
/// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment
/// is reached.
@@ -612,7 +634,7 @@ public:
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit = 0) = 0;
+ unsigned MaxBytesToEmit = 0);
/// EmitValueToOffset - Emit some number of copies of @p Value until the
/// byte offset @p Offset is reached.
@@ -624,13 +646,13 @@ public:
/// @param Value - The value to use when filling bytes.
/// @return false on success, true if the offset was invalid.
virtual bool EmitValueToOffset(const MCExpr *Offset,
- unsigned char Value = 0) = 0;
+ unsigned char Value = 0);
/// @}
/// EmitFileDirective - Switch to a new logical file. This is used to
/// implement the '.file "foo.c"' assembler directive.
- virtual void EmitFileDirective(StringRef Filename) = 0;
+ virtual void EmitFileDirective(StringRef Filename);
/// Emit the "identifiers" directive. This implements the
/// '.ident "version foo"' assembler directive.
@@ -677,38 +699,38 @@ public:
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
virtual void EmitCFIWindowSave();
- virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
- virtual void EmitWin64EHEndProc();
- virtual void EmitWin64EHStartChained();
- virtual void EmitWin64EHEndChained();
- virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
- bool Except);
- virtual void EmitWin64EHHandlerData();
- virtual void EmitWin64EHPushReg(unsigned Register);
- virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
- virtual void EmitWin64EHAllocStack(unsigned Size);
- virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
- virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
- virtual void EmitWin64EHPushFrame(bool Code);
- virtual void EmitWin64EHEndProlog();
+ virtual void EmitWinCFIStartProc(const MCSymbol *Symbol);
+ virtual void EmitWinCFIEndProc();
+ virtual void EmitWinCFIStartChained();
+ virtual void EmitWinCFIEndChained();
+ virtual void EmitWinCFIPushReg(unsigned Register);
+ virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset);
+ virtual void EmitWinCFIAllocStack(unsigned Size);
+ virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset);
+ virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset);
+ virtual void EmitWinCFIPushFrame(bool Code);
+ virtual void EmitWinCFIEndProlog();
+
+ virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except);
+ virtual void EmitWinEHHandlerData();
/// EmitInstruction - Emit the given @p Instruction into the current
/// section.
- virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) = 0;
+ virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI);
/// \brief Set the bundle alignment mode from now on in the section.
/// The argument is the power of 2 to which the alignment is set. The
/// value 0 means turn the bundle alignment off.
- virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0;
+ virtual void EmitBundleAlignMode(unsigned AlignPow2);
/// \brief The following instructions are a bundle-locked group.
///
/// \param AlignToEnd - If true, the bundle-locked group will be aligned to
/// the end of a bundle.
- virtual void EmitBundleLock(bool AlignToEnd) = 0;
+ virtual void EmitBundleLock(bool AlignToEnd);
/// \brief Ends a bundle-locked group.
- virtual void EmitBundleUnlock() = 0;
+ virtual void EmitBundleUnlock();
/// EmitRawText - If this file is backed by a assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
@@ -719,9 +741,11 @@ public:
virtual void Flush() {}
/// FinishImpl - Streamer specific finalization.
- virtual void FinishImpl() = 0;
+ virtual void FinishImpl();
/// Finish - Finish emission of machine code.
void Finish();
+
+ virtual bool mayHaveInstructions() const { return true; }
};
/// createNullStreamer - Create a dummy machine code streamer, which does
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 18ef6c2..384cc1b 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -14,6 +14,8 @@
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCTargetOptions.h"
+#include <memory>
+
namespace llvm {
class AsmToken;
class MCInst;
@@ -23,6 +25,8 @@ class SMLoc;
class StringRef;
template <typename T> class SmallVectorImpl;
+typedef SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> OperandVector;
+
enum AsmRewriteKind {
AOK_Delete = 0, // Rewrite should be ignored.
AOK_Align, // Rewrite align as .align.
@@ -131,8 +135,7 @@ public:
/// ownership of them to the caller.
/// \return True on failure.
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
- SMLoc NameLoc,
- SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
+ SMLoc NameLoc, OperandVector &Operands) = 0;
/// ParseDirective - Parse a target specific assembler directive
///
@@ -156,17 +159,16 @@ public:
///
/// On failure, the target parser is responsible for emitting a diagnostic
/// explaining the match failure.
- virtual bool
- MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
- SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- MCStreamer &Out, unsigned &ErrorInfo,
- bool MatchingInlineAsm) = 0;
+ virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
+ OperandVector &Operands, MCStreamer &Out,
+ unsigned &ErrorInfo,
+ bool MatchingInlineAsm) = 0;
/// Allow a target to add special case operand matching for things that
/// tblgen doesn't/can't handle effectively. For example, literal
/// immediates on ARM. TableGen expects a token operand, but the parser
/// will recognize them as immediates.
- virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
+ virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
unsigned Kind) {
return Match_InvalidOperand;
}
@@ -178,7 +180,7 @@ public:
}
virtual void convertToMapAndConstraints(unsigned Kind,
- const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
+ const OperandVector &Operands) = 0;
virtual const MCExpr *applyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind,
diff --git a/include/llvm/MC/MCTargetOptions.h b/include/llvm/MC/MCTargetOptions.h
index 80cc8be..eb4348e 100644
--- a/include/llvm/MC/MCTargetOptions.h
+++ b/include/llvm/MC/MCTargetOptions.h
@@ -29,6 +29,7 @@ public:
bool ShowMCEncoding : 1;
bool ShowMCInst : 1;
bool AsmVerbose : 1;
+ int DwarfVersion;
MCTargetOptions();
};
@@ -41,7 +42,8 @@ inline bool operator==(const MCTargetOptions &LHS, const MCTargetOptions &RHS) {
ARE_EQUAL(MCUseDwarfDirectory) &&
ARE_EQUAL(ShowMCEncoding) &&
ARE_EQUAL(ShowMCInst) &&
- ARE_EQUAL(AsmVerbose));
+ ARE_EQUAL(AsmVerbose) &&
+ ARE_EQUAL(DwarfVersion));
#undef ARE_EQUAL
}
diff --git a/include/llvm/MC/MCTargetOptionsCommandFlags.h b/include/llvm/MC/MCTargetOptionsCommandFlags.h
index 17a117a..6d4eb0e 100644
--- a/include/llvm/MC/MCTargetOptionsCommandFlags.h
+++ b/include/llvm/MC/MCTargetOptionsCommandFlags.h
@@ -33,11 +33,20 @@ cl::opt<bool> RelaxAll("mc-relax-all",
cl::desc("When used with filetype=obj, "
"relax all fixups in the emitted object file"));
+cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
+ cl::init(0));
+
+cl::opt<bool> ShowMCInst("asm-show-inst",
+ cl::desc("Emit internal instruction representation to "
+ "assembly file"));
+
static inline MCTargetOptions InitMCTargetOptionsFromFlags() {
MCTargetOptions Options;
Options.SanitizeAddress =
(AsmInstrumentation == MCTargetOptions::AsmInstrumentationAddress);
Options.MCRelaxAll = RelaxAll;
+ Options.DwarfVersion = DwarfVersion;
+ Options.ShowMCInst = ShowMCInst;
return Options;
}
diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h
index 34e39bb..7d2d0e4 100644
--- a/include/llvm/MC/MCWinCOFFStreamer.h
+++ b/include/llvm/MC/MCWinCOFFStreamer.h
@@ -35,7 +35,6 @@ public:
void InitSections() override;
void EmitLabel(MCSymbol *Symbol) override;
- void EmitDebugLabel(MCSymbol *Symbol) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitThumbFunc(MCSymbol *Func) override;
bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
@@ -57,7 +56,7 @@ public:
unsigned ByteAlignment) override;
void EmitFileDirective(StringRef Filename) override;
void EmitIdent(StringRef IdentString) override;
- void EmitWin64EHHandlerData() override;
+ void EmitWinEHHandlerData() override;
void FinishImpl() override;
/// \}
diff --git a/include/llvm/Object/StringTableBuilder.h b/include/llvm/MC/StringTableBuilder.h
index c61e216..065e9e0 100644
--- a/include/llvm/Object/StringTableBuilder.h
+++ b/include/llvm/MC/StringTableBuilder.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_OBJECT_STRINGTABLE_BUILDER_H
-#define LLVM_OBJECT_STRINGTABLE_BUILDER_H
+#ifndef LLVM_MC_STRINGTABLE_BUILDER_H
+#define LLVM_MC_STRINGTABLE_BUILDER_H
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
diff --git a/include/llvm/Object/YAML.h b/include/llvm/MC/YAML.h
index 1792e8b..383cdc6 100644
--- a/include/llvm/Object/YAML.h
+++ b/include/llvm/MC/YAML.h
@@ -1,26 +1,10 @@
-//===- YAML.h - YAMLIO utilities for object files ---------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares utility classes for handling the YAML representation of
-// object files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_YAML_H
-#define LLVM_OBJECT_YAML_H
+#ifndef LLVM_MC_YAML_H
+#define LLVM_MC_YAML_H
#include "llvm/Support/YAMLTraits.h"
namespace llvm {
-namespace object {
namespace yaml {
-
/// \brief Specialized YAMLIO scalar type for representing a binary blob.
///
/// A typical use case would be to represent the content of a section in a
@@ -100,18 +84,11 @@ inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) {
return LHS.DataIsHexString == RHS.DataIsHexString && LHS.Data == RHS.Data;
}
-}
-}
-
-namespace yaml {
-template <> struct ScalarTraits<object::yaml::BinaryRef> {
- static void output(const object::yaml::BinaryRef &, void *,
- llvm::raw_ostream &);
- static StringRef input(StringRef, void *, object::yaml::BinaryRef &);
+template <> struct ScalarTraits<BinaryRef> {
+ static void output(const BinaryRef &, void *, llvm::raw_ostream &);
+ static StringRef input(StringRef, void *, BinaryRef &);
static bool mustQuote(StringRef S) { return needsQuotes(S); }
};
}
-
}
-
#endif
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h
index 652b659..af6c995 100644
--- a/include/llvm/Object/Archive.h
+++ b/include/llvm/Object/Archive.h
@@ -72,7 +72,7 @@ public:
Child getNext() const;
- error_code getName(StringRef &Result) const;
+ ErrorOr<StringRef> getName() const;
StringRef getRawName() const { return getHeader()->getName(); }
sys::TimeValue getLastModified() const {
return getHeader()->getLastModified();
@@ -89,11 +89,11 @@ public:
return StringRef(Data.data() + StartOfFile, getSize());
}
- error_code getMemoryBuffer(std::unique_ptr<MemoryBuffer> &Result,
- bool FullPath = false) const;
+ ErrorOr<std::unique_ptr<MemoryBuffer>>
+ getMemoryBuffer(bool FullPath = false) const;
- error_code getAsBinary(std::unique_ptr<Binary> &Result,
- LLVMContext *Context = nullptr) const;
+ ErrorOr<std::unique_ptr<Binary>>
+ getAsBinary(LLVMContext *Context = nullptr) const;
};
class child_iterator {
@@ -137,8 +137,8 @@ public:
: Parent(p)
, SymbolIndex(symi)
, StringIndex(stri) {}
- error_code getName(StringRef &Result) const;
- error_code getMember(child_iterator &Result) const;
+ StringRef getName() const;
+ ErrorOr<child_iterator> getMember() const;
Symbol getNext() const;
};
@@ -164,8 +164,8 @@ public:
}
};
- Archive(MemoryBuffer *source, error_code &ec);
- static ErrorOr<Archive *> create(MemoryBuffer *Source);
+ Archive(std::unique_ptr<MemoryBuffer> Source, std::error_code &EC);
+ static ErrorOr<Archive *> create(std::unique_ptr<MemoryBuffer> Source);
enum Kind {
K_GNU,
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
index 8ac84e7..9be2fbe 100644
--- a/include/llvm/Object/Binary.h
+++ b/include/llvm/Object/Binary.h
@@ -32,12 +32,11 @@ private:
Binary(const Binary &other) LLVM_DELETED_FUNCTION;
unsigned int TypeID;
- bool BufferOwned;
protected:
- MemoryBuffer *Data;
+ std::unique_ptr<MemoryBuffer> Data;
- Binary(unsigned int Type, MemoryBuffer *Source, bool BufferOwned = true);
+ Binary(unsigned int Type, std::unique_ptr<MemoryBuffer> Source);
enum {
ID_Archive,
@@ -79,6 +78,7 @@ public:
virtual ~Binary();
StringRef getData() const;
+ MemoryBuffer *releaseBuffer() { return Data.release(); }
StringRef getFileName() const;
// Cast methods.
@@ -128,7 +128,7 @@ public:
/// @param Source The data to create the Binary from. Ownership is transferred
/// to the Binary if successful. If an error is returned,
/// Source is destroyed by createBinary before returning.
-ErrorOr<Binary *> createBinary(MemoryBuffer *Source,
+ErrorOr<Binary *> createBinary(std::unique_ptr<MemoryBuffer> &Source,
LLVMContext *Context = nullptr);
ErrorOr<Binary *> createBinary(StringRef Path);
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
index bd9c677..e2da070 100644
--- a/include/llvm/Object/COFF.h
+++ b/include/llvm/Object/COFF.h
@@ -353,65 +353,74 @@ private:
uint32_t NumberOfImportDirectory;
const export_directory_table_entry *ExportDirectory;
- error_code getString(uint32_t offset, StringRef &Res) const;
+ std::error_code getString(uint32_t offset, StringRef &Res) const;
const coff_symbol *toSymb(DataRefImpl Symb) const;
const coff_section *toSec(DataRefImpl Sec) const;
const coff_relocation *toRel(DataRefImpl Rel) const;
- error_code initSymbolTablePtr();
- error_code initImportTablePtr();
- error_code initExportTablePtr();
+ std::error_code initSymbolTablePtr();
+ std::error_code initImportTablePtr();
+ std::error_code initExportTablePtr();
protected:
void moveSymbolNext(DataRefImpl &Symb) const override;
- error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const override;
- error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override;
- error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ std::error_code getSymbolName(DataRefImpl Symb,
+ StringRef &Res) const override;
+ std::error_code getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Res) const override;
+ std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
- error_code getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Res) const override;
- error_code getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const override;
+ std::error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const override;
+ std::error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const override;
void moveSectionNext(DataRefImpl &Sec) const override;
- error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override;
- error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const override;
- error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
- error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override;
- error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const override;
- error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Res) const override;
- error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const override;
+ std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAddress(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+ std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
void moveRelocationNext(DataRefImpl &Rel) const override;
- error_code getRelocationAddress(DataRefImpl Rel,
- uint64_t &Res) const override;
- error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override;
+ std::error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const override;
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
- error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override;
- error_code
+ std::error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code
getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const override;
- error_code
+ std::error_code
getRelocationValueString(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const override;
- error_code getLibraryNext(DataRefImpl LibData,
- LibraryRef &Result) const override;
- error_code getLibraryPath(DataRefImpl LibData,
- StringRef &Result) const override;
+ std::error_code getLibraryNext(DataRefImpl LibData,
+ LibraryRef &Result) const override;
+ std::error_code getLibraryPath(DataRefImpl LibData,
+ StringRef &Result) const override;
public:
- COFFObjectFile(MemoryBuffer *Object, error_code &EC, bool BufferOwned = true);
+ COFFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC);
basic_symbol_iterator symbol_begin_impl() const override;
basic_symbol_iterator symbol_end_impl() const override;
library_iterator needed_library_begin() const override;
@@ -433,30 +442,33 @@ public:
export_directory_iterator export_directory_begin() const;
export_directory_iterator export_directory_end() const;
- error_code getHeader(const coff_file_header *&Res) const;
- error_code getCOFFHeader(const coff_file_header *&Res) const;
- error_code getPE32Header(const pe32_header *&Res) const;
- error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
- error_code getDataDirectory(uint32_t index, const data_directory *&Res) const;
- error_code getSection(int32_t index, const coff_section *&Res) const;
- error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
+ std::error_code getHeader(const coff_file_header *&Res) const;
+ std::error_code getCOFFHeader(const coff_file_header *&Res) const;
+ std::error_code getPE32Header(const pe32_header *&Res) const;
+ std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
+ std::error_code getDataDirectory(uint32_t index,
+ const data_directory *&Res) const;
+ std::error_code getSection(int32_t index, const coff_section *&Res) const;
+ std::error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
template <typename T>
- error_code getAuxSymbol(uint32_t index, const T *&Res) const {
+ std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
const coff_symbol *s;
- error_code ec = getSymbol(index, s);
+ std::error_code ec = getSymbol(index, s);
Res = reinterpret_cast<const T *>(s);
return ec;
}
- error_code getSymbolName(const coff_symbol *symbol, StringRef &Res) const;
+ std::error_code getSymbolName(const coff_symbol *symbol,
+ StringRef &Res) const;
ArrayRef<uint8_t> getSymbolAuxData(const coff_symbol *symbol) const;
- error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
- error_code getSectionContents(const coff_section *Sec,
- ArrayRef<uint8_t> &Res) const;
+ std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
+ std::error_code getSectionContents(const coff_section *Sec,
+ ArrayRef<uint8_t> &Res) const;
- error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
- error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
- error_code getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const;
+ std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
+ std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
+ std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
+ StringRef &Name) const;
static inline bool classof(const Binary *v) { return v->isCOFF(); }
};
@@ -471,12 +483,12 @@ public:
bool operator==(const ImportDirectoryEntryRef &Other) const;
void moveNext();
- error_code getName(StringRef &Result) const;
+ std::error_code getName(StringRef &Result) const;
- error_code
+ std::error_code
getImportTableEntry(const import_directory_table_entry *&Result) const;
- error_code
+ std::error_code
getImportLookupEntry(const import_lookup_table_entry32 *&Result) const;
private:
@@ -496,11 +508,11 @@ public:
bool operator==(const ExportDirectoryEntryRef &Other) const;
void moveNext();
- error_code getDllName(StringRef &Result) const;
- error_code getOrdinalBase(uint32_t &Result) const;
- error_code getOrdinal(uint32_t &Result) const;
- error_code getExportRVA(uint32_t &Result) const;
- error_code getSymbolName(StringRef &Result) const;
+ std::error_code getDllName(StringRef &Result) const;
+ std::error_code getOrdinalBase(uint32_t &Result) const;
+ std::error_code getOrdinal(uint32_t &Result) const;
+ std::error_code getExportRVA(uint32_t &Result) const;
+ std::error_code getSymbolName(StringRef &Result) const;
private:
const export_directory_table_entry *ExportTable;
diff --git a/include/llvm/Object/COFFYAML.h b/include/llvm/Object/COFFYAML.h
index 3f48e07..4aba08f 100644
--- a/include/llvm/Object/COFFYAML.h
+++ b/include/llvm/Object/COFFYAML.h
@@ -15,7 +15,7 @@
#define LLVM_OBJECT_COFFYAML_H
#include "llvm/ADT/Optional.h"
-#include "llvm/Object/YAML.h"
+#include "llvm/MC/YAML.h"
#include "llvm/Support/COFF.h"
namespace llvm {
@@ -49,7 +49,7 @@ namespace COFFYAML {
struct Section {
COFF::section Header;
unsigned Alignment;
- object::yaml::BinaryRef SectionData;
+ yaml::BinaryRef SectionData;
std::vector<Relocation> Relocations;
StringRef Name;
Section();
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index ee97d4e..fbc48e6 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -40,11 +40,12 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
// Subclasses of ELFFile may need this for template instantiation
inline std::pair<unsigned char, unsigned char>
-getElfArchType(MemoryBuffer *Object) {
- if (Object->getBufferSize() < ELF::EI_NIDENT)
- return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
- return std::make_pair((uint8_t) Object->getBufferStart()[ELF::EI_CLASS],
- (uint8_t) Object->getBufferStart()[ELF::EI_DATA]);
+getElfArchType(StringRef Object) {
+ if (Object.size() < ELF::EI_NIDENT)
+ return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
+ (uint8_t)ELF::ELFDATANONE);
+ return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
+ (uint8_t)Object[ELF::EI_DATA]);
}
template <class ELFT>
@@ -133,6 +134,7 @@ public:
typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux;
typedef Elf_Versym_Impl<ELFT> Elf_Versym;
typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_Iter;
+ typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range;
typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter;
typedef ELFEntityIterator<const Elf_Shdr> Elf_Shdr_Iter;
@@ -229,10 +231,10 @@ private:
typedef SmallVector<const Elf_Shdr *, 2> Sections_t;
typedef DenseMap<unsigned, unsigned> IndexMap_t;
- MemoryBuffer *Buf;
+ StringRef Buf;
const uint8_t *base() const {
- return reinterpret_cast<const uint8_t *>(Buf->getBufferStart());
+ return reinterpret_cast<const uint8_t *>(Buf.data());
}
const Elf_Ehdr *Header;
@@ -316,7 +318,7 @@ public:
std::pair<const Elf_Shdr *, const Elf_Sym *>
getRelocationSymbol(const Elf_Shdr *RelSec, const RelT *Rel) const;
- ELFFile(MemoryBuffer *Object, error_code &ec);
+ ELFFile(StringRef Object, std::error_code &ec);
bool isMipsELF64() const {
return Header->e_machine == ELF::EM_MIPS &&
@@ -342,6 +344,9 @@ public:
/// \param NULLEnd use one past the first DT_NULL entry as the end instead of
/// the section size.
Elf_Dyn_Iter end_dynamic_table(bool NULLEnd = false) const;
+ Elf_Dyn_Range dynamic_table(bool NULLEnd = false) const {
+ return make_range(begin_dynamic_table(), end_dynamic_table(NULLEnd));
+ }
Elf_Sym_Iter begin_dynamic_symbols() const {
if (DynSymRegion.Addr)
@@ -532,7 +537,7 @@ ELFFile<ELFT>::getSymbol(uint32_t Index) const {
template <class ELFT>
ErrorOr<ArrayRef<uint8_t> >
ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
- if (Sec->sh_offset + Sec->sh_size > Buf->getBufferSize())
+ if (Sec->sh_offset + Sec->sh_size > Buf.size())
return object_error::parse_failed;
const uint8_t *Start = base() + Sec->sh_offset;
return ArrayRef<uint8_t>(Start, Sec->sh_size);
@@ -598,7 +603,7 @@ void ELFFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const {
template <class ELFT>
uint64_t ELFFile<ELFT>::getNumSections() const {
assert(Header && "Header not initialized!");
- if (Header->e_shnum == ELF::SHN_UNDEF) {
+ if (Header->e_shnum == ELF::SHN_UNDEF && Header->e_shoff > 0) {
assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
return SectionHeaderTable->sh_size;
}
@@ -617,18 +622,13 @@ typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const {
}
template <class ELFT>
-ELFFile<ELFT>::ELFFile(MemoryBuffer *Object, error_code &ec)
- : Buf(Object),
- SectionHeaderTable(nullptr),
- dot_shstrtab_sec(nullptr),
- dot_strtab_sec(nullptr),
- dot_symtab_sec(nullptr),
- SymbolTableSectionHeaderIndex(nullptr),
- dot_gnu_version_sec(nullptr),
- dot_gnu_version_r_sec(nullptr),
- dot_gnu_version_d_sec(nullptr),
+ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec)
+ : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr),
+ dot_strtab_sec(nullptr), dot_symtab_sec(nullptr),
+ SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr),
+ dot_gnu_version_r_sec(nullptr), dot_gnu_version_d_sec(nullptr),
dt_soname(nullptr) {
- const uint64_t FileSize = Buf->getBufferSize();
+ const uint64_t FileSize = Buf.size();
if (sizeof(Elf_Ehdr) > FileSize)
// FIXME: Proper error handling.
@@ -744,7 +744,7 @@ ELFFile<ELFT>::ELFFile(MemoryBuffer *Object, error_code &ec)
}
}
- ec = error_code::success();
+ ec = std::error_code();
}
// Get the symbol table index in the symtab section given a symbol
@@ -823,17 +823,13 @@ ELFFile<ELFT>::end_dynamic_table(bool NULLEnd) const {
template <class ELFT>
StringRef ELFFile<ELFT>::getLoadName() const {
if (!dt_soname) {
+ dt_soname = "";
// Find the DT_SONAME entry
- Elf_Dyn_Iter it = begin_dynamic_table();
- Elf_Dyn_Iter ie = end_dynamic_table();
- while (it != ie && it->getTag() != ELF::DT_SONAME)
- ++it;
-
- if (it != ie) {
- dt_soname = getDynamicString(it->getVal());
- } else {
- dt_soname = "";
- }
+ for (const auto &Entry : dynamic_table())
+ if (Entry.getTag() == ELF::DT_SONAME) {
+ dt_soname = getDynamicString(Entry.getVal());
+ break;
+ }
}
return dt_soname;
}
diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h
index 302caba..cfb6b08 100644
--- a/include/llvm/Object/ELFObjectFile.h
+++ b/include/llvm/Object/ELFObjectFile.h
@@ -57,50 +57,63 @@ protected:
ELFFile<ELFT> EF;
void moveSymbolNext(DataRefImpl &Symb) const override;
- error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const override;
- error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override;
- error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const override;
- error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ std::error_code getSymbolName(DataRefImpl Symb,
+ StringRef &Res) const override;
+ std::error_code getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Res) const override;
+ std::error_code getSymbolAlignment(DataRefImpl Symb,
+ uint32_t &Res) const override;
+ std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
- error_code getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Res) const override;
- error_code getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const override;
+ std::error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const override;
+ std::error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const override;
- error_code getLibraryNext(DataRefImpl Data,
- LibraryRef &Result) const override;
- error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const override;
+ std::error_code getLibraryNext(DataRefImpl Data,
+ LibraryRef &Result) const override;
+ std::error_code getLibraryPath(DataRefImpl Data,
+ StringRef &Res) const override;
void moveSectionNext(DataRefImpl &Sec) const override;
- error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override;
- error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const override;
- error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
- error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override;
- error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const override;
- error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Res) const override;
- error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const override;
- error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const override;
+ std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAddress(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+ std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
section_iterator getRelocatedSection(DataRefImpl Sec) const override;
void moveRelocationNext(DataRefImpl &Rel) const override;
- error_code getRelocationAddress(DataRefImpl Rel,
- uint64_t &Res) const override;
- error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override;
+ std::error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const override;
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
- error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override;
- error_code getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
- error_code getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
+ std::error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code
+ getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ std::error_code
+ getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
uint64_t getROffset(DataRefImpl Rel) const;
StringRef getRelocationTypeName(uint32_t Type) const;
@@ -164,7 +177,7 @@ protected:
bool isDyldELFObject;
public:
- ELFObjectFile(MemoryBuffer *Object, error_code &EC, bool BufferOwned = true);
+ ELFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC);
const Elf_Sym *getSymbol(DataRefImpl Symb) const;
@@ -180,10 +193,9 @@ public:
library_iterator needed_library_begin() const override;
library_iterator needed_library_end() const override;
- error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const;
- error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
- bool &IsDefault) const;
-
+ std::error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const;
+ std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
+ bool &IsDefault) const;
uint8_t getBytesInAddress() const override;
StringRef getFileFormatName() const override;
@@ -212,8 +224,8 @@ void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
- StringRef &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
+ StringRef &Result) const {
ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb));
if (!Name)
return Name.getError();
@@ -222,9 +234,9 @@ error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
- StringRef &Version,
- bool &IsDefault) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
+ StringRef &Version,
+ bool &IsDefault) const {
DataRefImpl Symb = SymRef.getRawDataRefImpl();
const Elf_Sym *symb = getSymbol(Symb);
ErrorOr<StringRef> Ver =
@@ -236,8 +248,8 @@ error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
- uint64_t &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Result) const {
const Elf_Sym *ESym = getSymbol(Symb);
switch (EF.getSymbolTableIndex(ESym)) {
case ELF::SHN_COMMON:
@@ -265,8 +277,8 @@ error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
- uint32_t &Res) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
+ uint32_t &Res) const {
Elf_Sym_Iter Sym = toELFSymIter(Symb);
if (Sym->st_shndx == ELF::SHN_COMMON)
Res = Sym->st_value;
@@ -276,15 +288,16 @@ error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
- uint64_t &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
+ uint64_t &Result) const {
Result = toELFSymIter(Symb)->st_size;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Result) const {
+std::error_code
+ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Result) const {
const Elf_Sym *ESym = getSymbol(Symb);
switch (ESym->getType()) {
@@ -343,8 +356,9 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const {
+std::error_code
+ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const {
const Elf_Sym *ESym = getSymbol(Symb);
const Elf_Shdr *ESec = EF.getSection(ESym);
if (!ESec)
@@ -363,8 +377,8 @@ void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
- StringRef &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
+ StringRef &Result) const {
ErrorOr<StringRef> Name = EF.getSectionName(&*toELFShdrIter(Sec));
if (!Name)
return Name.getError();
@@ -373,44 +387,46 @@ error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec,
- uint64_t &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec,
+ uint64_t &Result) const {
Result = toELFShdrIter(Sec)->sh_addr;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec,
- uint64_t &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec,
+ uint64_t &Result) const {
Result = toELFShdrIter(Sec)->sh_size;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
- StringRef &Result) const {
+std::error_code
+ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
+ StringRef &Result) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec,
- uint64_t &Result) const {
+std::error_code
+ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Result) const {
Result = toELFShdrIter(Sec)->sh_addralign;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec,
+ bool &Result) const {
Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
+ bool &Result) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
EShdr->sh_type == ELF::SHT_PROGBITS;
@@ -418,8 +434,8 @@ error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
+ bool &Result) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
EShdr->sh_type == ELF::SHT_NOBITS;
@@ -427,7 +443,7 @@ error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
}
template <class ELFT>
-error_code
+std::error_code
ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec,
bool &Result) const {
Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC;
@@ -435,31 +451,31 @@ ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec,
+ bool &Result) const {
Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec,
+ bool &Result) const {
Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Result) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
Result = !(EShdr->sh_flags & (ELF::SHF_WRITE | ELF::SHF_EXECINSTR));
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
- DataRefImpl Symb,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
+ DataRefImpl Symb,
+ bool &Result) const {
Elf_Sym_Iter ESym = toELFSymIter(Symb);
uintX_t Index = ESym->st_shndx;
@@ -553,8 +569,9 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
- uint64_t &Result) const {
+std::error_code
+ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Result) const {
uint64_t ROffset = getROffset(Rel);
const Elf_Ehdr *Header = EF.getHeader();
@@ -570,8 +587,9 @@ error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
- uint64_t &Result) const {
+std::error_code
+ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Result) const {
assert(EF.getHeader()->e_type == ELF::ET_REL &&
"Only relocatable object files have relocation offsets");
Result = getROffset(Rel);
@@ -592,8 +610,8 @@ uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
- uint64_t &Result) const {
+std::error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
+ uint64_t &Result) const {
const Elf_Shdr *sec = getRelSection(Rel);
switch (sec->sh_type) {
default:
@@ -616,7 +634,7 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationTypeName(
+std::error_code ELFObjectFile<ELFT>::getRelocationTypeName(
DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
const Elf_Shdr *sec = getRelSection(Rel);
uint32_t type;
@@ -638,8 +656,9 @@ error_code ELFObjectFile<ELFT>::getRelocationTypeName(
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel,
- int64_t &Result) const {
+std::error_code
+ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel,
+ int64_t &Result) const {
const Elf_Shdr *sec = getRelSection(Rel);
switch (sec->sh_type) {
default:
@@ -656,7 +675,7 @@ error_code ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationValueString(
+std::error_code ELFObjectFile<ELFT>::getRelocationValueString(
DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
const Elf_Shdr *sec = getRelSection(Rel);
uint8_t type;
@@ -754,13 +773,13 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
}
template <class ELFT>
-ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec,
- bool BufferOwned)
+ELFObjectFile<ELFT>::ELFObjectFile(std::unique_ptr<MemoryBuffer> Object,
+ std::error_code &EC)
: ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) ==
support::little,
ELFT::Is64Bits),
- Object, BufferOwned),
- EF(Object, ec) {}
+ std::move(Object)),
+ EF(Data->getBuffer(), EC) {}
template <class ELFT>
basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {
@@ -817,8 +836,8 @@ library_iterator ELFObjectFile<ELFT>::needed_library_begin() const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
- LibraryRef &Result) const {
+std::error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
+ LibraryRef &Result) const {
Elf_Dyn_Iter DI = toELFDynIter(Data);
Elf_Dyn_Iter DE = EF.end_dynamic_table();
@@ -832,8 +851,8 @@ error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data,
- StringRef &Res) const {
+std::error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data,
+ StringRef &Res) const {
Res = EF.getDynamicString(toELFDynIter(Data)->getVal());
return object_error::success;
}
@@ -898,6 +917,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
template <class ELFT>
unsigned ELFObjectFile<ELFT>::getArch() const {
+ bool IsLittleEndian = ELFT::TargetEndianness == support::little;
switch (EF.getHeader()->e_machine) {
case ELF::EM_386:
return Triple::x86;
@@ -910,11 +930,16 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
case ELF::EM_HEXAGON:
return Triple::hexagon;
case ELF::EM_MIPS:
- return (ELFT::TargetEndianness == support::little) ? Triple::mipsel
- : Triple::mips;
+ switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+ case ELF::ELFCLASS32:
+ return IsLittleEndian ? Triple::mipsel : Triple::mips;
+ case ELF::ELFCLASS64:
+ return IsLittleEndian ? Triple::mips64el : Triple::mips64;
+ default:
+ report_fatal_error("Invalid ELFCLASS!");
+ }
case ELF::EM_PPC64:
- return (ELFT::TargetEndianness == support::little) ? Triple::ppc64le
- : Triple::ppc64;
+ return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
case ELF::EM_S390:
return Triple::systemz;
@@ -931,8 +956,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
/// FIXME: Maybe we should have a base ElfObjectFile that is not a template
/// and make these member functions?
-inline error_code getELFRelocationAddend(const RelocationRef R,
- int64_t &Addend) {
+inline std::error_code getELFRelocationAddend(const RelocationRef R,
+ int64_t &Addend) {
const ObjectFile *Obj = R.getObjectFile();
DataRefImpl DRI = R.getRawDataRefImpl();
// Little-endian 32-bit
@@ -975,9 +1000,10 @@ getELFDynamicSymbolIterators(SymbolicFile *Obj) {
/// This is a generic interface for retrieving GNU symbol version
/// information from an ELFObjectFile.
-inline error_code GetELFSymbolVersion(const ObjectFile *Obj,
- const SymbolRef &Sym, StringRef &Version,
- bool &IsDefault) {
+inline std::error_code GetELFSymbolVersion(const ObjectFile *Obj,
+ const SymbolRef &Sym,
+ StringRef &Version,
+ bool &IsDefault) {
// Little-endian 32-bit
if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h
index 524e55b..fc8cc95 100644
--- a/include/llvm/Object/ELFYAML.h
+++ b/include/llvm/Object/ELFYAML.h
@@ -16,7 +16,7 @@
#ifndef LLVM_OBJECT_ELFYAML_H
#define LLVM_OBJECT_ELFYAML_H
-#include "llvm/Object/YAML.h"
+#include "llvm/MC/YAML.h"
#include "llvm/Support/ELF.h"
namespace llvm {
@@ -44,6 +44,7 @@ LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_REL)
// Just use 64, since it can hold 32-bit values too.
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV)
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
// since 64-bit can hold 32-bit values too.
@@ -62,6 +63,7 @@ struct Symbol {
StringRef Section;
llvm::yaml::Hex64 Value;
llvm::yaml::Hex64 Size;
+ ELF_STV Visibility;
};
struct LocalGlobalWeakSymbols {
std::vector<Symbol> Local;
@@ -76,13 +78,12 @@ struct Section {
ELF_SHF Flags;
llvm::yaml::Hex64 Address;
StringRef Link;
- StringRef Info;
llvm::yaml::Hex64 AddressAlign;
Section(SectionKind Kind) : Kind(Kind) {}
virtual ~Section();
};
struct RawContentSection : Section {
- object::yaml::BinaryRef Content;
+ yaml::BinaryRef Content;
llvm::yaml::Hex64 Size;
RawContentSection() : Section(SectionKind::RawContent) {}
static bool classof(const Section *S) {
@@ -96,6 +97,7 @@ struct Relocation {
StringRef Symbol;
};
struct RelocationSection : Section {
+ StringRef Info;
std::vector<Relocation> Relocations;
RelocationSection() : Section(SectionKind::Relocation) {}
static bool classof(const Section *S) {
@@ -168,6 +170,11 @@ struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
};
template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_STV> {
+ static void enumeration(IO &IO, ELFYAML::ELF_STV &Value);
+};
+
+template <>
struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
};
diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h
index 779c747..701da12 100644
--- a/include/llvm/Object/Error.h
+++ b/include/llvm/Object/Error.h
@@ -14,38 +14,32 @@
#ifndef LLVM_OBJECT_ERROR_H
#define LLVM_OBJECT_ERROR_H
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
namespace object {
-const error_category &object_category();
+const std::error_category &object_category();
-struct object_error {
- enum Impl {
- success = 0,
- arch_not_found,
- invalid_file_type,
- parse_failed,
- unexpected_eof
- };
- Impl V;
-
- object_error(Impl V) : V(V) {}
- operator Impl() const { return V; }
+enum class object_error {
+ success = 0,
+ arch_not_found,
+ invalid_file_type,
+ parse_failed,
+ unexpected_eof
};
-inline error_code make_error_code(object_error e) {
- return error_code(static_cast<int>(e), object_category());
+inline std::error_code make_error_code(object_error e) {
+ return std::error_code(static_cast<int>(e), object_category());
}
} // end namespace object.
-template <> struct is_error_code_enum<object::object_error> : std::true_type {};
+} // end namespace llvm.
+namespace std {
template <>
-struct is_error_code_enum<object::object_error::Impl> : std::true_type {};
-
-} // end namespace llvm.
+struct is_error_code_enum<llvm::object::object_error> : std::true_type {};
+}
#endif
diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h
index 78f5b2b..b33cc26 100644
--- a/include/llvm/Object/IRObjectFile.h
+++ b/include/llvm/Object/IRObjectFile.h
@@ -25,20 +25,33 @@ namespace object {
class IRObjectFile : public SymbolicFile {
std::unique_ptr<Module> M;
std::unique_ptr<Mangler> Mang;
+ std::vector<std::pair<std::string, uint32_t>> AsmSymbols;
public:
- IRObjectFile(MemoryBuffer *Object, error_code &EC, LLVMContext &Context,
- bool BufferOwned);
+ IRObjectFile(std::unique_ptr<MemoryBuffer> Object, std::unique_ptr<Module> M);
+ ~IRObjectFile();
void moveSymbolNext(DataRefImpl &Symb) const override;
- error_code printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override;
+ std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
- const GlobalValue &getSymbolGV(DataRefImpl Symb) const;
+ const GlobalValue *getSymbolGV(DataRefImpl Symb) const;
basic_symbol_iterator symbol_begin_impl() const override;
basic_symbol_iterator symbol_end_impl() const override;
+ const Module &getModule() const {
+ return const_cast<IRObjectFile*>(this)->getModule();
+ }
+ Module &getModule() {
+ return *M;
+ }
+
static inline bool classof(const Binary *v) {
return v->isIR();
}
+
+ static ErrorOr<IRObjectFile *>
+ createIRObjectFile(std::unique_ptr<MemoryBuffer> Object,
+ LLVMContext &Context);
};
}
}
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index 710ad7e..e93ebb8 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -40,9 +40,9 @@ public:
void moveNext();
- error_code getOffset(uint32_t &Result) const;
- error_code getLength(uint16_t &Result) const;
- error_code getKind(uint16_t &Result) const;
+ std::error_code getOffset(uint32_t &Result) const;
+ std::error_code getLength(uint16_t &Result) const;
+ std::error_code getKind(uint16_t &Result) const;
DataRefImpl getRawDataRefImpl() const;
const ObjectFile *getObjectFile() const;
@@ -56,54 +56,75 @@ public:
MachO::load_command C; // The command itself.
};
- MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
- error_code &EC, bool BufferOwned = true);
+ MachOObjectFile(std::unique_ptr<MemoryBuffer> Object, bool IsLittleEndian,
+ bool Is64Bits, std::error_code &EC);
void moveSymbolNext(DataRefImpl &Symb) const override;
- error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const override;
- error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override;
- error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const override;
- error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
- error_code getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Res) const override;
+ std::error_code getSymbolName(DataRefImpl Symb,
+ StringRef &Res) const override;
+
+ // MachO specific.
+ std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
+
+ std::error_code getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Res) const override;
+ std::error_code getSymbolAlignment(DataRefImpl Symb,
+ uint32_t &Res) const override;
+ std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ std::error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
- error_code getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const override;
+ std::error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const override;
void moveSectionNext(DataRefImpl &Sec) const override;
- error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override;
- error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const override;
- error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
- error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override;
- error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const override;
- error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Res) const override;
- error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
- error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const override;
- error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const override;
+ std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAddress(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+ std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
void moveRelocationNext(DataRefImpl &Rel) const override;
- error_code getRelocationAddress(DataRefImpl Rel,
- uint64_t &Res) const override;
- error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override;
+ std::error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const override;
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
- error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override;
- error_code getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
- error_code getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
- error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const override;
+ std::error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code
+ getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ std::error_code
+ getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ std::error_code getRelocationHidden(DataRefImpl Rel,
+ bool &Result) const override;
+
+ std::error_code getLibraryNext(DataRefImpl LibData,
+ LibraryRef &Res) const override;
+ std::error_code getLibraryPath(DataRefImpl LibData,
+ StringRef &Res) const override;
- error_code getLibraryNext(DataRefImpl LibData,
- LibraryRef &Res) const override;
- error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const override;
+ // MachO specific.
+ std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &Res);
// TODO: Would be useful to have an iterator based version
// of the load command interface too.
@@ -180,6 +201,8 @@ public:
getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const;
MachO::version_min_command
getVersionMinLoadCommand(const LoadCommandInfo &L) const;
+ MachO::dylib_command
+ getDylibIDLoadCommand(const LoadCommandInfo &L) const;
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
@@ -198,15 +221,27 @@ public:
bool is64Bit() const;
void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
+ static StringRef guessLibraryShortName(StringRef Name, bool &isFramework,
+ StringRef &Suffix);
+
static Triple::ArchType getArch(uint32_t CPUType);
+ static Triple getArch(uint32_t CPUType, uint32_t CPUSubType);
+ static Triple getArch(StringRef ArchFlag);
+ static Triple getHostArch();
static bool classof(const Binary *v) {
return v->isMachO();
}
+ const char *getSectionPointer(DataRefImpl Rel) const;
+
private:
- typedef SmallVector<const char*, 1> SectionList;
+ typedef SmallVector<const char *, 1> SectionList;
SectionList Sections;
+ typedef SmallVector<const char *, 1> LibraryList;
+ LibraryList Libraries;
+ typedef SmallVector<StringRef, 1> LibraryShortName;
+ LibraryShortName LibrariesShortNames;
const char *SymtabLoadCmd;
const char *DysymtabLoadCmd;
const char *DataInCodeLoadCmd;
@@ -234,7 +269,7 @@ inline void DiceRef::moveNext() {
// the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for
// the methods that get the values of the fields of the reference.
-inline error_code DiceRef::getOffset(uint32_t &Result) const {
+inline std::error_code DiceRef::getOffset(uint32_t &Result) const {
const MachOObjectFile *MachOOF =
static_cast<const MachOObjectFile *>(OwningObject);
MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
@@ -242,7 +277,7 @@ inline error_code DiceRef::getOffset(uint32_t &Result) const {
return object_error::success;
}
-inline error_code DiceRef::getLength(uint16_t &Result) const {
+inline std::error_code DiceRef::getLength(uint16_t &Result) const {
const MachOObjectFile *MachOOF =
static_cast<const MachOObjectFile *>(OwningObject);
MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
@@ -250,7 +285,7 @@ inline error_code DiceRef::getLength(uint16_t &Result) const {
return object_error::success;
}
-inline error_code DiceRef::getKind(uint16_t &Result) const {
+inline std::error_code DiceRef::getKind(uint16_t &Result) const {
const MachOObjectFile *MachOOF =
static_cast<const MachOObjectFile *>(OwningObject);
MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h
index d27c824..e6677f5 100644
--- a/include/llvm/Object/MachOUniversal.h
+++ b/include/llvm/Object/MachOUniversal.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/Triple.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/Archive.h"
+#include "llvm/Object/MachO.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MachO.h"
@@ -52,10 +53,14 @@ public:
ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
uint32_t getCPUType() const { return Header.cputype; }
+ std::string getArchTypeName() const {
+ Triple T = MachOObjectFile::getArch(Header.cputype, Header.cpusubtype);
+ return T.getArchName();
+ }
- error_code getAsObjectFile(std::unique_ptr<ObjectFile> &Result) const;
+ ErrorOr<std::unique_ptr<ObjectFile>> getAsObjectFile() const;
- error_code getAsArchive(std::unique_ptr<Archive> &Result) const;
+ std::error_code getAsArchive(std::unique_ptr<Archive> &Result) const;
};
class object_iterator {
@@ -79,8 +84,10 @@ public:
}
};
- MachOUniversalBinary(MemoryBuffer *Source, error_code &ec);
- static ErrorOr<MachOUniversalBinary*> create(MemoryBuffer *Source);
+ MachOUniversalBinary(std::unique_ptr<MemoryBuffer> Source,
+ std::error_code &ec);
+ static ErrorOr<MachOUniversalBinary *>
+ create(std::unique_ptr<MemoryBuffer> Source);
object_iterator begin_objects() const {
return ObjectForArch(this, 0);
@@ -96,8 +103,8 @@ public:
return V->isMachOUniversalBinary();
}
- error_code getObjectForArch(Triple::ArchType Arch,
- std::unique_ptr<ObjectFile> &Result) const;
+ ErrorOr<std::unique_ptr<ObjectFile>>
+ getObjectForArch(Triple::ArchType Arch) const;
};
}
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index 10209b9..646abf8 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -46,26 +46,26 @@ public:
void moveNext();
- error_code getAddress(uint64_t &Result) const;
- error_code getOffset(uint64_t &Result) const;
+ std::error_code getAddress(uint64_t &Result) const;
+ std::error_code getOffset(uint64_t &Result) const;
symbol_iterator getSymbol() const;
- error_code getType(uint64_t &Result) const;
+ std::error_code getType(uint64_t &Result) const;
/// @brief Indicates whether this relocation should hidden when listing
/// relocations, usually because it is the trailing part of a multipart
/// relocation that will be printed as part of the leading relocation.
- error_code getHidden(bool &Result) const;
+ std::error_code getHidden(bool &Result) const;
/// @brief Get a string that represents the type of this relocation.
///
/// This is for display purposes only.
- error_code getTypeName(SmallVectorImpl<char> &Result) const;
+ std::error_code getTypeName(SmallVectorImpl<char> &Result) const;
/// @brief Get a string that represents the calculation of the value of this
/// relocation.
///
/// This is for display purposes only.
- error_code getValueString(SmallVectorImpl<char> &Result) const;
+ std::error_code getValueString(SmallVectorImpl<char> &Result) const;
DataRefImpl getRawDataRefImpl() const;
const ObjectFile *getObjectFile() const;
@@ -92,24 +92,24 @@ public:
void moveNext();
- error_code getName(StringRef &Result) const;
- error_code getAddress(uint64_t &Result) const;
- error_code getSize(uint64_t &Result) const;
- error_code getContents(StringRef &Result) const;
+ std::error_code getName(StringRef &Result) const;
+ std::error_code getAddress(uint64_t &Result) const;
+ std::error_code getSize(uint64_t &Result) const;
+ std::error_code getContents(StringRef &Result) const;
/// @brief Get the alignment of this section as the actual value (not log 2).
- error_code getAlignment(uint64_t &Result) const;
+ std::error_code getAlignment(uint64_t &Result) const;
// FIXME: Move to the normalization layer when it's created.
- error_code isText(bool &Result) const;
- error_code isData(bool &Result) const;
- error_code isBSS(bool &Result) const;
- error_code isRequiredForExecution(bool &Result) const;
- error_code isVirtual(bool &Result) const;
- error_code isZeroInit(bool &Result) const;
- error_code isReadOnlyData(bool &Result) const;
+ std::error_code isText(bool &Result) const;
+ std::error_code isData(bool &Result) const;
+ std::error_code isBSS(bool &Result) const;
+ std::error_code isRequiredForExecution(bool &Result) const;
+ std::error_code isVirtual(bool &Result) const;
+ std::error_code isZeroInit(bool &Result) const;
+ std::error_code isReadOnlyData(bool &Result) const;
- error_code containsSymbol(SymbolRef S, bool &Result) const;
+ std::error_code containsSymbol(SymbolRef S, bool &Result) const;
relocation_iterator relocation_begin() const;
relocation_iterator relocation_end() const;
@@ -141,18 +141,18 @@ public:
SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
- error_code getName(StringRef &Result) const;
+ std::error_code getName(StringRef &Result) const;
/// Returns the symbol virtual address (i.e. address at which it will be
/// mapped).
- error_code getAddress(uint64_t &Result) const;
+ std::error_code getAddress(uint64_t &Result) const;
/// @brief Get the alignment of this symbol as the actual value (not log 2).
- error_code getAlignment(uint32_t &Result) const;
- error_code getSize(uint64_t &Result) const;
- error_code getType(SymbolRef::Type &Result) const;
+ std::error_code getAlignment(uint32_t &Result) const;
+ std::error_code getSize(uint64_t &Result) const;
+ std::error_code getType(SymbolRef::Type &Result) const;
/// @brief Get section this symbol is defined in reference to. Result is
/// end_sections() if it is undefined or is an absolute symbol.
- error_code getSection(section_iterator &Result) const;
+ std::error_code getSection(section_iterator &Result) const;
const ObjectFile *getObject() const;
};
@@ -190,10 +190,10 @@ public:
bool operator==(const LibraryRef &Other) const;
bool operator<(const LibraryRef &Other) const;
- error_code getNext(LibraryRef &Result) const;
+ std::error_code getNext(LibraryRef &Result) const;
// Get the path to this library, as stored in the object file.
- error_code getPath(StringRef &Result) const;
+ std::error_code getPath(StringRef &Result) const;
DataRefImpl getRawDataRefImpl() const;
};
@@ -208,7 +208,7 @@ class ObjectFile : public SymbolicFile {
ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
protected:
- ObjectFile(unsigned int Type, MemoryBuffer *Source, bool BufferOwned = true);
+ ObjectFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source);
const uint8_t *base() const {
return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
@@ -223,35 +223,49 @@ protected:
// Implementations assume that the DataRefImpl is valid and has not been
// modified externally. It's UB otherwise.
friend class SymbolRef;
- virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
- error_code printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override;
- virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0;
- virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
- virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
- virtual error_code getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Res) const = 0;
- virtual error_code getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const = 0;
+ virtual std::error_code getSymbolName(DataRefImpl Symb,
+ StringRef &Res) const = 0;
+ std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const override;
+ virtual std::error_code getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Res) const = 0;
+ virtual std::error_code getSymbolAlignment(DataRefImpl Symb,
+ uint32_t &Res) const;
+ virtual std::error_code getSymbolSize(DataRefImpl Symb,
+ uint64_t &Res) const = 0;
+ virtual std::error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const = 0;
+ virtual std::error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const = 0;
// Same as above for SectionRef.
friend class SectionRef;
virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
- virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0;
- virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0;
- virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0;
- virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0;
- virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res)const=0;
- virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
- virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0;
- virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0;
- virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Res) const = 0;
+ virtual std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const = 0;
+ virtual std::error_code getSectionAddress(DataRefImpl Sec,
+ uint64_t &Res) const = 0;
+ virtual std::error_code getSectionSize(DataRefImpl Sec,
+ uint64_t &Res) const = 0;
+ virtual std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const = 0;
+ virtual std::error_code getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Res) const = 0;
+ virtual std::error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
+ virtual std::error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0;
+ virtual std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0;
+ virtual std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const = 0;
// A section is 'virtual' if its contents aren't present in the object image.
- virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const = 0;
- virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const = 0;
- virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const =0;
- virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const = 0;
+ virtual std::error_code isSectionVirtual(DataRefImpl Sec,
+ bool &Res) const = 0;
+ virtual std::error_code isSectionZeroInit(DataRefImpl Sec,
+ bool &Res) const = 0;
+ virtual std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Res) const = 0;
+ virtual std::error_code sectionContainsSymbol(DataRefImpl Sec,
+ DataRefImpl Symb,
+ bool &Result) const = 0;
virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
@@ -259,26 +273,31 @@ protected:
// Same as above for RelocationRef.
friend class RelocationRef;
virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
- virtual error_code getRelocationAddress(DataRefImpl Rel,
- uint64_t &Res) const =0;
- virtual error_code getRelocationOffset(DataRefImpl Rel,
- uint64_t &Res) const =0;
+ virtual std::error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const = 0;
+ virtual std::error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const = 0;
virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
- virtual error_code getRelocationType(DataRefImpl Rel,
- uint64_t &Res) const = 0;
- virtual error_code getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const = 0;
- virtual error_code getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const = 0;
- virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const {
+ virtual std::error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const = 0;
+ virtual std::error_code
+ getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const = 0;
+ virtual std::error_code
+ getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const = 0;
+ virtual std::error_code getRelocationHidden(DataRefImpl Rel,
+ bool &Result) const {
Result = false;
return object_error::success;
}
// Same for LibraryRef
friend class LibraryRef;
- virtual error_code getLibraryNext(DataRefImpl Lib, LibraryRef &Res) const = 0;
- virtual error_code getLibraryPath(DataRefImpl Lib, StringRef &Res) const = 0;
+ virtual std::error_code getLibraryNext(DataRefImpl Lib,
+ LibraryRef &Res) const = 0;
+ virtual std::error_code getLibraryPath(DataRefImpl Lib,
+ StringRef &Res) const = 0;
public:
typedef iterator_range<symbol_iterator> symbol_iterator_range;
@@ -314,11 +333,12 @@ public:
/// return true.
/// @brief Create ObjectFile from path.
static ErrorOr<ObjectFile *> createObjectFile(StringRef ObjectPath);
- static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object,
- bool BufferOwned,
- sys::fs::file_magic Type);
- static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object) {
- return createObjectFile(Object, true, sys::fs::file_magic::unknown);
+ static ErrorOr<ObjectFile *>
+ createObjectFile(std::unique_ptr<MemoryBuffer> &Object,
+ sys::fs::file_magic Type);
+ static ErrorOr<ObjectFile *>
+ createObjectFile(std::unique_ptr<MemoryBuffer> &Object) {
+ return createObjectFile(Object, sys::fs::file_magic::unknown);
}
@@ -327,39 +347,39 @@ public:
}
public:
- static ErrorOr<ObjectFile *> createCOFFObjectFile(MemoryBuffer *Object,
- bool BufferOwned = true);
- static ErrorOr<ObjectFile *> createELFObjectFile(MemoryBuffer *Object,
- bool BufferOwned = true);
- static ErrorOr<ObjectFile *> createMachOObjectFile(MemoryBuffer *Object,
- bool BufferOwned = true);
+ static ErrorOr<ObjectFile *>
+ createCOFFObjectFile(std::unique_ptr<MemoryBuffer> Object);
+ static ErrorOr<ObjectFile *>
+ createELFObjectFile(std::unique_ptr<MemoryBuffer> &Object);
+ static ErrorOr<ObjectFile *>
+ createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Object);
};
// Inline function definitions.
inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
: BasicSymbolRef(SymbolP, Owner) {}
-inline error_code SymbolRef::getName(StringRef &Result) const {
+inline std::error_code SymbolRef::getName(StringRef &Result) const {
return getObject()->getSymbolName(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getAddress(uint64_t &Result) const {
+inline std::error_code SymbolRef::getAddress(uint64_t &Result) const {
return getObject()->getSymbolAddress(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getAlignment(uint32_t &Result) const {
+inline std::error_code SymbolRef::getAlignment(uint32_t &Result) const {
return getObject()->getSymbolAlignment(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getSize(uint64_t &Result) const {
+inline std::error_code SymbolRef::getSize(uint64_t &Result) const {
return getObject()->getSymbolSize(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getSection(section_iterator &Result) const {
+inline std::error_code SymbolRef::getSection(section_iterator &Result) const {
return getObject()->getSymbolSection(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getType(SymbolRef::Type &Result) const {
+inline std::error_code SymbolRef::getType(SymbolRef::Type &Result) const {
return getObject()->getSymbolType(getRawDataRefImpl(), Result);
}
@@ -391,55 +411,56 @@ inline void SectionRef::moveNext() {
return OwningObject->moveSectionNext(SectionPimpl);
}
-inline error_code SectionRef::getName(StringRef &Result) const {
+inline std::error_code SectionRef::getName(StringRef &Result) const {
return OwningObject->getSectionName(SectionPimpl, Result);
}
-inline error_code SectionRef::getAddress(uint64_t &Result) const {
+inline std::error_code SectionRef::getAddress(uint64_t &Result) const {
return OwningObject->getSectionAddress(SectionPimpl, Result);
}
-inline error_code SectionRef::getSize(uint64_t &Result) const {
+inline std::error_code SectionRef::getSize(uint64_t &Result) const {
return OwningObject->getSectionSize(SectionPimpl, Result);
}
-inline error_code SectionRef::getContents(StringRef &Result) const {
+inline std::error_code SectionRef::getContents(StringRef &Result) const {
return OwningObject->getSectionContents(SectionPimpl, Result);
}
-inline error_code SectionRef::getAlignment(uint64_t &Result) const {
+inline std::error_code SectionRef::getAlignment(uint64_t &Result) const {
return OwningObject->getSectionAlignment(SectionPimpl, Result);
}
-inline error_code SectionRef::isText(bool &Result) const {
+inline std::error_code SectionRef::isText(bool &Result) const {
return OwningObject->isSectionText(SectionPimpl, Result);
}
-inline error_code SectionRef::isData(bool &Result) const {
+inline std::error_code SectionRef::isData(bool &Result) const {
return OwningObject->isSectionData(SectionPimpl, Result);
}
-inline error_code SectionRef::isBSS(bool &Result) const {
+inline std::error_code SectionRef::isBSS(bool &Result) const {
return OwningObject->isSectionBSS(SectionPimpl, Result);
}
-inline error_code SectionRef::isRequiredForExecution(bool &Result) const {
+inline std::error_code SectionRef::isRequiredForExecution(bool &Result) const {
return OwningObject->isSectionRequiredForExecution(SectionPimpl, Result);
}
-inline error_code SectionRef::isVirtual(bool &Result) const {
+inline std::error_code SectionRef::isVirtual(bool &Result) const {
return OwningObject->isSectionVirtual(SectionPimpl, Result);
}
-inline error_code SectionRef::isZeroInit(bool &Result) const {
+inline std::error_code SectionRef::isZeroInit(bool &Result) const {
return OwningObject->isSectionZeroInit(SectionPimpl, Result);
}
-inline error_code SectionRef::isReadOnlyData(bool &Result) const {
+inline std::error_code SectionRef::isReadOnlyData(bool &Result) const {
return OwningObject->isSectionReadOnlyData(SectionPimpl, Result);
}
-inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const {
+inline std::error_code SectionRef::containsSymbol(SymbolRef S,
+ bool &Result) const {
return OwningObject->sectionContainsSymbol(SectionPimpl,
S.getRawDataRefImpl(), Result);
}
@@ -474,11 +495,11 @@ inline void RelocationRef::moveNext() {
return OwningObject->moveRelocationNext(RelocationPimpl);
}
-inline error_code RelocationRef::getAddress(uint64_t &Result) const {
+inline std::error_code RelocationRef::getAddress(uint64_t &Result) const {
return OwningObject->getRelocationAddress(RelocationPimpl, Result);
}
-inline error_code RelocationRef::getOffset(uint64_t &Result) const {
+inline std::error_code RelocationRef::getOffset(uint64_t &Result) const {
return OwningObject->getRelocationOffset(RelocationPimpl, Result);
}
@@ -486,21 +507,21 @@ inline symbol_iterator RelocationRef::getSymbol() const {
return OwningObject->getRelocationSymbol(RelocationPimpl);
}
-inline error_code RelocationRef::getType(uint64_t &Result) const {
+inline std::error_code RelocationRef::getType(uint64_t &Result) const {
return OwningObject->getRelocationType(RelocationPimpl, Result);
}
-inline error_code RelocationRef::getTypeName(SmallVectorImpl<char> &Result)
- const {
+inline std::error_code
+RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
}
-inline error_code RelocationRef::getValueString(SmallVectorImpl<char> &Result)
- const {
+inline std::error_code
+RelocationRef::getValueString(SmallVectorImpl<char> &Result) const {
return OwningObject->getRelocationValueString(RelocationPimpl, Result);
}
-inline error_code RelocationRef::getHidden(bool &Result) const {
+inline std::error_code RelocationRef::getHidden(bool &Result) const {
return OwningObject->getRelocationHidden(RelocationPimpl, Result);
}
@@ -525,11 +546,11 @@ inline bool LibraryRef::operator<(const LibraryRef &Other) const {
return LibraryPimpl < Other.LibraryPimpl;
}
-inline error_code LibraryRef::getNext(LibraryRef &Result) const {
+inline std::error_code LibraryRef::getNext(LibraryRef &Result) const {
return OwningObject->getLibraryNext(LibraryPimpl, Result);
}
-inline error_code LibraryRef::getPath(StringRef &Result) const {
+inline std::error_code LibraryRef::getPath(StringRef &Result) const {
return OwningObject->getLibraryPath(LibraryPimpl, Result);
}
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index a3aaf17..5ca2450 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -253,12 +253,14 @@ private:
/// PPC64 ELF
RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getAddend64BE(R);
+ int64_t Addend;
+ getELFRelocationAddend(R, Addend);
uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
return RelocToApply(Res, 4);
}
RelocToApply visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) {
- int64_t Addend = getAddend64BE(R);
+ int64_t Addend;
+ getELFRelocationAddend(R, Addend);
return RelocToApply(Value + Addend, 8);
}
diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h
index 28400e1..77eef4a 100644
--- a/include/llvm/Object/SymbolicFile.h
+++ b/include/llvm/Object/SymbolicFile.h
@@ -86,7 +86,8 @@ public:
SF_Weak = 1U << 2, // Weak symbol
SF_Absolute = 1U << 3, // Absolute symbol
SF_Common = 1U << 4, // Symbol has common linkage
- SF_FormatSpecific = 1U << 5 // Specific to the object file format
+ SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
+ SF_FormatSpecific = 1U << 6 // Specific to the object file format
// (e.g. section symbols)
};
@@ -98,7 +99,7 @@ public:
void moveNext();
- error_code printName(raw_ostream &OS) const;
+ std::error_code printName(raw_ostream &OS) const;
/// Get symbol flags (bitwise OR of SymbolRef::Flags)
uint32_t getFlags() const;
@@ -114,13 +115,13 @@ const uint64_t UnknownAddressOrSize = ~0ULL;
class SymbolicFile : public Binary {
public:
virtual ~SymbolicFile();
- SymbolicFile(unsigned int Type, MemoryBuffer *Source, bool BufferOwned);
+ SymbolicFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source);
// virtual interface.
virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
- virtual error_code printSymbolName(raw_ostream &OS,
- DataRefImpl Symb) const = 0;
+ virtual std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const = 0;
virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
@@ -135,20 +136,19 @@ public:
basic_symbol_iterator symbol_end() const {
return symbol_end_impl();
}
+ typedef iterator_range<basic_symbol_iterator> basic_symbol_iterator_range;
+ basic_symbol_iterator_range symbols() const {
+ return basic_symbol_iterator_range(symbol_begin(), symbol_end());
+ }
// construction aux.
- static ErrorOr<SymbolicFile *> createIRObjectFile(MemoryBuffer *Object,
- LLVMContext &Context,
- bool BufferOwned = true);
-
- static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object,
- bool BufferOwned,
- sys::fs::file_magic Type,
- LLVMContext *Context);
-
- static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object) {
- return createSymbolicFile(Object, true, sys::fs::file_magic::unknown,
- nullptr);
+ static ErrorOr<SymbolicFile *>
+ createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object,
+ sys::fs::file_magic Type, LLVMContext *Context);
+
+ static ErrorOr<SymbolicFile *>
+ createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object) {
+ return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
}
static ErrorOr<SymbolicFile *> createSymbolicFile(StringRef ObjectPath);
@@ -173,7 +173,7 @@ inline void BasicSymbolRef::moveNext() {
return OwningObject->moveSymbolNext(SymbolPimpl);
}
-inline error_code BasicSymbolRef::printName(raw_ostream &OS) const {
+inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
return OwningObject->printSymbolName(OS, SymbolPimpl);
}
diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h
index ab40a1a..d46b0e8 100644
--- a/include/llvm/Option/ArgList.h
+++ b/include/llvm/Option/ArgList.h
@@ -150,6 +150,12 @@ public:
return arg_iterator(Args.end(), *this);
}
+ iterator_range<arg_iterator> filtered(OptSpecifier Id0 = 0U,
+ OptSpecifier Id1 = 0U,
+ OptSpecifier Id2 = 0U) const {
+ return make_range(filtered_begin(Id0, Id1, Id2), filtered_end());
+ }
+
/// @}
/// @name Arg Removal
/// @{
@@ -328,6 +334,7 @@ public:
unsigned MakeIndex(StringRef String0) const;
unsigned MakeIndex(StringRef String0, StringRef String1) const;
+ using ArgList::MakeArgString;
const char *MakeArgString(StringRef Str) const override;
/// @}
@@ -365,6 +372,7 @@ public:
/// (to be freed).
void AddSynthesizedArg(Arg *A);
+ using ArgList::MakeArgString;
const char *MakeArgString(StringRef Str) const override;
/// AddFlagArg - Construct a new FlagArg for the given option \p Id and
diff --git a/include/llvm/PassInfo.h b/include/llvm/PassInfo.h
new file mode 100644
index 0000000..d53daf1
--- /dev/null
+++ b/include/llvm/PassInfo.h
@@ -0,0 +1,147 @@
+//===- llvm/PassInfo.h - Pass Info class ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines and implements the PassInfo class.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_PASSINFO_H
+#define LLVM_PASSINFO_H
+
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+
+class Pass;
+class TargetMachine;
+
+//===---------------------------------------------------------------------------
+/// PassInfo class - An instance of this class exists for every pass known by
+/// the system, and can be obtained from a live Pass by calling its
+/// getPassInfo() method. These objects are set up by the RegisterPass<>
+/// template.
+///
+class PassInfo {
+public:
+ typedef Pass* (*NormalCtor_t)();
+ typedef Pass *(*TargetMachineCtor_t)(TargetMachine *);
+
+private:
+ const char *const PassName; // Nice name for Pass
+ const char *const PassArgument; // Command Line argument to run this pass
+ const void *PassID;
+ const bool IsCFGOnlyPass; // Pass only looks at the CFG.
+ const bool IsAnalysis; // True if an analysis pass.
+ const bool IsAnalysisGroup; // True if an analysis group.
+ std::vector<const PassInfo*> ItfImpl;// Interfaces implemented by this pass
+
+ NormalCtor_t NormalCtor;
+ TargetMachineCtor_t TargetMachineCtor;
+
+public:
+ /// PassInfo ctor - Do not call this directly, this should only be invoked
+ /// through RegisterPass.
+ PassInfo(const char *name, const char *arg, const void *pi,
+ NormalCtor_t normal, bool isCFGOnly, bool is_analysis,
+ TargetMachineCtor_t machine = nullptr)
+ : PassName(name), PassArgument(arg), PassID(pi),
+ IsCFGOnlyPass(isCFGOnly),
+ IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal),
+ TargetMachineCtor(machine) {}
+ /// PassInfo ctor - Do not call this directly, this should only be invoked
+ /// through RegisterPass. This version is for use by analysis groups; it
+ /// does not auto-register the pass.
+ PassInfo(const char *name, const void *pi)
+ : PassName(name), PassArgument(""), PassID(pi),
+ IsCFGOnlyPass(false),
+ IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(nullptr),
+ TargetMachineCtor(nullptr) {}
+
+ /// getPassName - Return the friendly name for the pass, never returns null
+ ///
+ const char *getPassName() const { return PassName; }
+
+ /// getPassArgument - Return the command line option that may be passed to
+ /// 'opt' that will cause this pass to be run. This will return null if there
+ /// is no argument.
+ ///
+ const char *getPassArgument() const { return PassArgument; }
+
+ /// getTypeInfo - Return the id object for the pass...
+ /// TODO : Rename
+ const void *getTypeInfo() const { return PassID; }
+
+ /// Return true if this PassID implements the specified ID pointer.
+ bool isPassID(const void *IDPtr) const {
+ return PassID == IDPtr;
+ }
+
+ /// isAnalysisGroup - Return true if this is an analysis group, not a normal
+ /// pass.
+ ///
+ bool isAnalysisGroup() const { return IsAnalysisGroup; }
+ bool isAnalysis() const { return IsAnalysis; }
+
+ /// isCFGOnlyPass - return true if this pass only looks at the CFG for the
+ /// function.
+ bool isCFGOnlyPass() const { return IsCFGOnlyPass; }
+
+ /// getNormalCtor - Return a pointer to a function, that when called, creates
+ /// an instance of the pass and returns it. This pointer may be null if there
+ /// is no default constructor for the pass.
+ ///
+ NormalCtor_t getNormalCtor() const {
+ return NormalCtor;
+ }
+ void setNormalCtor(NormalCtor_t Ctor) {
+ NormalCtor = Ctor;
+ }
+
+ /// getTargetMachineCtor - Return a pointer to a function, that when called
+ /// with a TargetMachine, creates an instance of the pass and returns it.
+ /// This pointer may be null if there is no constructor with a TargetMachine
+ /// for the pass.
+ ///
+ TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; }
+ void setTargetMachineCtor(TargetMachineCtor_t Ctor) {
+ TargetMachineCtor = Ctor;
+ }
+
+ /// createPass() - Use this method to create an instance of this pass.
+ Pass *createPass() const {
+ assert((!isAnalysisGroup() || NormalCtor) &&
+ "No default implementation found for analysis group!");
+ assert(NormalCtor &&
+ "Cannot call createPass on PassInfo without default ctor!");
+ return NormalCtor();
+ }
+
+ /// addInterfaceImplemented - This method is called when this pass is
+ /// registered as a member of an analysis group with the RegisterAnalysisGroup
+ /// template.
+ ///
+ void addInterfaceImplemented(const PassInfo *ItfPI) {
+ ItfImpl.push_back(ItfPI);
+ }
+
+ /// getInterfacesImplemented - Return a list of all of the analysis group
+ /// interfaces implemented by this pass.
+ ///
+ const std::vector<const PassInfo*> &getInterfacesImplemented() const {
+ return ItfImpl;
+ }
+
+private:
+ void operator=(const PassInfo &) LLVM_DELETED_FUNCTION;
+ PassInfo(const PassInfo &) LLVM_DELETED_FUNCTION;
+};
+
+}
+
+#endif
diff --git a/include/llvm/PassRegistry.h b/include/llvm/PassRegistry.h
index 7f2a014..1558c51 100644
--- a/include/llvm/PassRegistry.h
+++ b/include/llvm/PassRegistry.h
@@ -18,8 +18,14 @@
#define LLVM_PASSREGISTRY_H
#include "llvm-c/Core.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/PassInfo.h"
#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/RWMutex.h"
+#include <vector>
namespace llvm {
@@ -33,11 +39,26 @@ struct PassRegistrationListener;
/// threads simultaneously, you will need to use a separate PassRegistry on
/// each thread.
class PassRegistry {
- mutable void *pImpl;
- void *getImpl() const;
+ mutable sys::SmartRWMutex<true> Lock;
+
+ /// PassInfoMap - Keep track of the PassInfo object for each registered pass.
+ typedef DenseMap<const void*, const PassInfo*> MapType;
+ MapType PassInfoMap;
+
+ typedef StringMap<const PassInfo*> StringMapType;
+ StringMapType PassInfoStringMap;
+
+ /// AnalysisGroupInfo - Keep track of information for each analysis group.
+ struct AnalysisGroupInfo {
+ SmallPtrSet<const PassInfo *, 8> Implementations;
+ };
+ DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap;
+
+ std::vector<std::unique_ptr<const PassInfo>> ToFree;
+ std::vector<PassRegistrationListener*> Listeners;
public:
- PassRegistry() : pImpl(nullptr) { }
+ PassRegistry() { }
~PassRegistry();
/// getPassRegistry - Access the global registry object, which is
diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h
index 8efb45f..449bc92 100644
--- a/include/llvm/PassSupport.h
+++ b/include/llvm/PassSupport.h
@@ -23,6 +23,7 @@
#include "Pass.h"
#include "llvm/InitializePasses.h"
+#include "llvm/PassInfo.h"
#include "llvm/PassRegistry.h"
#include "llvm/Support/Atomic.h"
#include "llvm/Support/Valgrind.h"
@@ -31,120 +32,6 @@
namespace llvm {
class TargetMachine;
-//===---------------------------------------------------------------------------
-/// PassInfo class - An instance of this class exists for every pass known by
-/// the system, and can be obtained from a live Pass by calling its
-/// getPassInfo() method. These objects are set up by the RegisterPass<>
-/// template, defined below.
-///
-class PassInfo {
-public:
- typedef Pass* (*NormalCtor_t)();
- typedef Pass *(*TargetMachineCtor_t)(TargetMachine *);
-
-private:
- const char *const PassName; // Nice name for Pass
- const char *const PassArgument; // Command Line argument to run this pass
- const void *PassID;
- const bool IsCFGOnlyPass; // Pass only looks at the CFG.
- const bool IsAnalysis; // True if an analysis pass.
- const bool IsAnalysisGroup; // True if an analysis group.
- std::vector<const PassInfo*> ItfImpl;// Interfaces implemented by this pass
-
- NormalCtor_t NormalCtor;
- TargetMachineCtor_t TargetMachineCtor;
-
-public:
- /// PassInfo ctor - Do not call this directly, this should only be invoked
- /// through RegisterPass.
- PassInfo(const char *name, const char *arg, const void *pi,
- NormalCtor_t normal, bool isCFGOnly, bool is_analysis,
- TargetMachineCtor_t machine = nullptr)
- : PassName(name), PassArgument(arg), PassID(pi),
- IsCFGOnlyPass(isCFGOnly),
- IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal),
- TargetMachineCtor(machine) {}
- /// PassInfo ctor - Do not call this directly, this should only be invoked
- /// through RegisterPass. This version is for use by analysis groups; it
- /// does not auto-register the pass.
- PassInfo(const char *name, const void *pi)
- : PassName(name), PassArgument(""), PassID(pi),
- IsCFGOnlyPass(false),
- IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(nullptr),
- TargetMachineCtor(nullptr) {}
-
- /// getPassName - Return the friendly name for the pass, never returns null
- ///
- const char *getPassName() const { return PassName; }
-
- /// getPassArgument - Return the command line option that may be passed to
- /// 'opt' that will cause this pass to be run. This will return null if there
- /// is no argument.
- ///
- const char *getPassArgument() const { return PassArgument; }
-
- /// getTypeInfo - Return the id object for the pass...
- /// TODO : Rename
- const void *getTypeInfo() const { return PassID; }
-
- /// Return true if this PassID implements the specified ID pointer.
- bool isPassID(const void *IDPtr) const {
- return PassID == IDPtr;
- }
-
- /// isAnalysisGroup - Return true if this is an analysis group, not a normal
- /// pass.
- ///
- bool isAnalysisGroup() const { return IsAnalysisGroup; }
- bool isAnalysis() const { return IsAnalysis; }
-
- /// isCFGOnlyPass - return true if this pass only looks at the CFG for the
- /// function.
- bool isCFGOnlyPass() const { return IsCFGOnlyPass; }
-
- /// getNormalCtor - Return a pointer to a function, that when called, creates
- /// an instance of the pass and returns it. This pointer may be null if there
- /// is no default constructor for the pass.
- ///
- NormalCtor_t getNormalCtor() const {
- return NormalCtor;
- }
- void setNormalCtor(NormalCtor_t Ctor) {
- NormalCtor = Ctor;
- }
-
- /// getTargetMachineCtor - Return a pointer to a function, that when called
- /// with a TargetMachine, creates an instance of the pass and returns it.
- /// This pointer may be null if there is no constructor with a TargetMachine
- /// for the pass.
- ///
- TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; }
- void setTargetMachineCtor(TargetMachineCtor_t Ctor) {
- TargetMachineCtor = Ctor;
- }
-
- /// createPass() - Use this method to create an instance of this pass.
- Pass *createPass() const;
-
- /// addInterfaceImplemented - This method is called when this pass is
- /// registered as a member of an analysis group with the RegisterAnalysisGroup
- /// template.
- ///
- void addInterfaceImplemented(const PassInfo *ItfPI) {
- ItfImpl.push_back(ItfPI);
- }
-
- /// getInterfacesImplemented - Return a list of all of the analysis group
- /// interfaces implemented by this pass.
- ///
- const std::vector<const PassInfo*> &getInterfacesImplemented() const {
- return ItfImpl;
- }
-
-private:
- void operator=(const PassInfo &) LLVM_DELETED_FUNCTION;
- PassInfo(const PassInfo &) LLVM_DELETED_FUNCTION;
-};
#define CALL_ONCE_INITIALIZATION(function) \
static volatile sys::cas_flag initialized = 0; \
@@ -325,19 +212,12 @@ struct RegisterAnalysisGroup : public RegisterAGBase {
/// clients that are interested in which passes get registered and unregistered
/// at runtime (which can be because of the RegisterPass constructors being run
/// as the program starts up, or may be because a shared object just got
-/// loaded). Deriving from the PassRegistrationListener class automatically
-/// registers your object to receive callbacks indicating when passes are loaded
-/// and removed.
+/// loaded).
///
struct PassRegistrationListener {
- /// PassRegistrationListener ctor - Add the current object to the list of
- /// PassRegistrationListeners...
- PassRegistrationListener();
-
- /// dtor - Remove object from list of listeners...
- ///
- virtual ~PassRegistrationListener();
+ PassRegistrationListener() {}
+ virtual ~PassRegistrationListener() {}
/// Callback functions - These functions are invoked whenever a pass is loaded
/// or removed from the current executable.
diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h
index 8457678..eafb768 100644
--- a/include/llvm/ProfileData/InstrProf.h
+++ b/include/llvm/ProfileData/InstrProf.h
@@ -16,14 +16,12 @@
#ifndef LLVM_PROFILEDATA_INSTRPROF_H_
#define LLVM_PROFILEDATA_INSTRPROF_H_
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
+const std::error_category &instrprof_category();
-const error_category &instrprof_category();
-
-struct instrprof_error {
- enum ErrorType {
+enum class instrprof_error {
success = 0,
eof,
bad_magic,
@@ -37,21 +35,17 @@ struct instrprof_error {
hash_mismatch,
count_mismatch,
counter_overflow
- };
- ErrorType V;
-
- instrprof_error(ErrorType V) : V(V) {}
- operator ErrorType() const { return V; }
};
-inline error_code make_error_code(instrprof_error E) {
- return error_code(static_cast<int>(E), instrprof_category());
+inline std::error_code make_error_code(instrprof_error E) {
+ return std::error_code(static_cast<int>(E), instrprof_category());
}
-template <> struct is_error_code_enum<instrprof_error> : std::true_type {};
-template <> struct is_error_code_enum<instrprof_error::ErrorType>
- : std::true_type {};
-
} // end namespace llvm
+namespace std {
+template <>
+struct is_error_code_enum<llvm::instrprof_error> : std::true_type {};
+}
+
#endif // LLVM_PROFILEDATA_INSTRPROF_H_
diff --git a/include/llvm/ProfileData/InstrProfReader.h b/include/llvm/ProfileData/InstrProfReader.h
index 3e18c76..7a5a71d 100644
--- a/include/llvm/ProfileData/InstrProfReader.h
+++ b/include/llvm/ProfileData/InstrProfReader.h
@@ -60,28 +60,29 @@ public:
/// Base class and interface for reading profiling data of any known instrprof
/// format. Provides an iterator over InstrProfRecords.
class InstrProfReader {
- error_code LastError;
+ std::error_code LastError;
+
public:
InstrProfReader() : LastError(instrprof_error::success) {}
virtual ~InstrProfReader() {}
/// Read the header. Required before reading first record.
- virtual error_code readHeader() = 0;
+ virtual std::error_code readHeader() = 0;
/// Read a single record.
- virtual error_code readNextRecord(InstrProfRecord &Record) = 0;
+ virtual std::error_code readNextRecord(InstrProfRecord &Record) = 0;
/// Iterator over profile data.
InstrProfIterator begin() { return InstrProfIterator(this); }
InstrProfIterator end() { return InstrProfIterator(); }
protected:
- /// Set the current error_code and return same.
- error_code error(error_code EC) {
+ /// Set the current std::error_code and return same.
+ std::error_code error(std::error_code EC) {
LastError = EC;
return EC;
}
/// Clear the current error code and return a successful one.
- error_code success() { return error(instrprof_error::success); }
+ std::error_code success() { return error(instrprof_error::success); }
public:
/// Return true if the reader has finished reading the profile data.
@@ -89,12 +90,12 @@ public:
/// Return true if the reader encountered an error reading profiling data.
bool hasError() { return LastError && !isEOF(); }
/// Get the current error code.
- error_code getError() { return LastError; }
+ std::error_code getError() { return LastError; }
/// Factory method to create an appropriately typed reader for the given
/// instrprof file.
- static error_code create(std::string Path,
- std::unique_ptr<InstrProfReader> &Result);
+ static std::error_code create(std::string Path,
+ std::unique_ptr<InstrProfReader> &Result);
};
/// Reader for the simple text based instrprof format.
@@ -122,9 +123,9 @@ public:
: DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, '#') {}
/// Read the header.
- error_code readHeader() override { return success(); }
+ std::error_code readHeader() override { return success(); }
/// Read a single record.
- error_code readNextRecord(InstrProfRecord &Record) override;
+ std::error_code readNextRecord(InstrProfRecord &Record) override;
};
/// Reader for the raw instrprof binary format from runtime.
@@ -167,23 +168,23 @@ private:
const char *NamesStart;
const char *ProfileEnd;
- RawInstrProfReader(const TextInstrProfReader &) LLVM_DELETED_FUNCTION;
- RawInstrProfReader &operator=(const TextInstrProfReader &)
+ RawInstrProfReader(const RawInstrProfReader &) LLVM_DELETED_FUNCTION;
+ RawInstrProfReader &operator=(const RawInstrProfReader &)
LLVM_DELETED_FUNCTION;
public:
RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)
: DataBuffer(std::move(DataBuffer)) { }
static bool hasFormat(const MemoryBuffer &DataBuffer);
- error_code readHeader() override;
- error_code readNextRecord(InstrProfRecord &Record) override;
+ std::error_code readHeader() override;
+ std::error_code readNextRecord(InstrProfRecord &Record) override;
private:
- error_code readNextHeader(const char *CurrentPos);
- error_code readHeader(const RawHeader &Header);
+ std::error_code readNextHeader(const char *CurrentPos);
+ std::error_code readHeader(const RawHeader &Header);
template <class IntT>
IntT swap(IntT Int) const {
- return ShouldSwapBytes ? sys::SwapByteOrder(Int) : Int;
+ return ShouldSwapBytes ? sys::getSwappedBytes(Int) : Int;
}
const uint64_t *getCounter(IntPtrT CounterPtr) const {
ptrdiff_t Offset = (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t);
@@ -281,19 +282,19 @@ public:
static bool hasFormat(const MemoryBuffer &DataBuffer);
/// Read the file header.
- error_code readHeader() override;
+ std::error_code readHeader() override;
/// Read a single record.
- error_code readNextRecord(InstrProfRecord &Record) override;
+ std::error_code readNextRecord(InstrProfRecord &Record) override;
/// Fill Counts with the profile data for the given function name.
- error_code getFunctionCounts(StringRef FuncName, uint64_t &FuncHash,
- std::vector<uint64_t> &Counts);
+ std::error_code getFunctionCounts(StringRef FuncName, uint64_t &FuncHash,
+ std::vector<uint64_t> &Counts);
/// Return the maximum of all known function counts.
uint64_t getMaximumFunctionCount() { return MaxFunctionCount; }
/// Factory method to create an indexed reader.
- static error_code create(std::string Path,
- std::unique_ptr<IndexedInstrProfReader> &Result);
+ static std::error_code
+ create(std::string Path, std::unique_ptr<IndexedInstrProfReader> &Result);
};
} // end namespace llvm
diff --git a/include/llvm/ProfileData/InstrProfWriter.h b/include/llvm/ProfileData/InstrProfWriter.h
index fa37bf1..6e68bee 100644
--- a/include/llvm/ProfileData/InstrProfWriter.h
+++ b/include/llvm/ProfileData/InstrProfWriter.h
@@ -38,8 +38,9 @@ public:
/// Add function counts for the given function. If there are already counts
/// for this function and the hash and number of counts match, each counter is
/// summed.
- error_code addFunctionCounts(StringRef FunctionName, uint64_t FunctionHash,
- ArrayRef<uint64_t> Counters);
+ std::error_code addFunctionCounts(StringRef FunctionName,
+ uint64_t FunctionHash,
+ ArrayRef<uint64_t> Counters);
/// Ensure that all data is written to disk.
void write(raw_fd_ostream &OS);
};
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h
index 1631200..f63e0a6 100644
--- a/include/llvm/Support/ARMBuildAttributes.h
+++ b/include/llvm/Support/ARMBuildAttributes.h
@@ -159,6 +159,11 @@ enum {
AddressDirect = 1, // Address imported data directly
AddressGOT = 2, // Address imported data indirectly (via GOT)
+ // Tag_ABI_PCS_wchar_t, (=18), uleb128
+ WCharProhibited = 0, // wchar_t is not used
+ WCharWidth2Bytes = 2, // sizeof(wchar_t) == 2
+ WCharWidth4Bytes = 4, // sizeof(wchar_t) == 4
+
// Tag_ABI_FP_denormal, (=20), uleb128
PreserveFPSign = 2, // sign when flushed-to-zero is preserved
@@ -166,6 +171,16 @@ enum {
AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings
+ // Tag_ABI_enum_size, (=26), uleb128
+ EnumProhibited = 0, // The user prohibited the use of enums when building
+ // this entity.
+ EnumSmallest = 1, // Enum is smallest container big enough to hold all
+ // values.
+ Enum32Bit = 2, // Enum is at least 32 bits.
+ Enum32BitABI = 3, // Every enumeration visible across an ABI-complying
+ // interface contains a value needing 32 bits to encode
+ // it; other enums can be containerized.
+
// Tag_ABI_HardFP_use, (=27), uleb128
HardFPImplied = 0, // FP use should be implied by Tag_FP_arch
HardFPSinglePrecision = 1, // Single-precision only
diff --git a/include/llvm/Support/ARMWinEH.h b/include/llvm/Support/ARMWinEH.h
new file mode 100644
index 0000000..78deb8d
--- /dev/null
+++ b/include/llvm/Support/ARMWinEH.h
@@ -0,0 +1,384 @@
+//===-- llvm/Support/WinARMEH.h - Windows on ARM EH Constants ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WINARMEH_H
+#define LLVM_SUPPORT_WINARMEH_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace ARM {
+namespace WinEH {
+enum class RuntimeFunctionFlag {
+ RFF_Unpacked, /// unpacked entry
+ RFF_Packed, /// packed entry
+ RFF_PackedFragment, /// packed entry representing a fragment
+ RFF_Reserved, /// reserved
+};
+
+enum class ReturnType {
+ RT_POP, /// return via pop {pc} (L flag must be set)
+ RT_B, /// 16-bit branch
+ RT_BW, /// 32-bit branch
+ RT_NoEpilogue, /// no epilogue (fragment)
+};
+
+/// RuntimeFunction - An entry in the table of procedure data (.pdata)
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +---------------------------------------------------------------+
+/// | Function Start RVA |
+/// +-------------------+-+-+-+-----+-+---+---------------------+---+
+/// | Stack Adjust |C|L|R| Reg |H|Ret| Function Length |Flg|
+/// +-------------------+-+-+-+-----+-+---+---------------------+---+
+///
+/// Flag : 2-bit field with the following meanings:
+/// - 00 = packed unwind data not used; reamining bits point to .xdata record
+/// - 01 = packed unwind data
+/// - 10 = packed unwind data, function assumed to have no prologue; useful
+/// for function fragments that are discontiguous with the start of the
+/// function
+/// - 11 = reserved
+/// Function Length : 11-bit field providing the length of the entire function
+/// in bytes, divided by 2; if the function is greater than
+/// 4KB, a full .xdata record must be used instead
+/// Ret : 2-bit field indicating how the function returns
+/// - 00 = return via pop {pc} (the L bit must be set)
+/// - 01 = return via 16-bit branch
+/// - 10 = return via 32-bit branch
+/// - 11 = no epilogue; useful for function fragments that may only contain a
+/// prologue but the epilogue is elsewhere
+/// H : 1-bit flag indicating whether the function "homes" the integer parameter
+/// registers (r0-r3), allocating 16-bytes on the stack
+/// Reg : 3-bit field indicating the index of the last saved non-volatile
+/// register. If the R bit is set to 0, then only integer registers are
+/// saved (r4-rN, where N is 4 + Reg). If the R bit is set to 1, then
+/// only floating-point registers are being saved (d8-dN, where N is
+/// 8 + Reg). The special case of the R bit being set to 1 and Reg equal
+/// to 7 indicates that no registers are saved.
+/// R : 1-bit flag indicating whether the non-volatile registers are integer or
+/// floating-point. 0 indicates integer, 1 indicates floating-point. The
+/// special case of the R-flag being set and Reg being set to 7 indicates
+/// that no non-volatile registers are saved.
+/// L : 1-bit flag indicating whether the function saves/restores the link
+/// register (LR)
+/// C : 1-bit flag indicating whether the function includes extra instructions
+/// to setup a frame chain for fast walking. If this flag is set, r11 is
+/// implicitly added to the list of saved non-volatile integer registers.
+/// Stack Adjust : 10-bit field indicating the number of bytes of stack that are
+/// allocated for this function. Only values between 0x000 and
+/// 0x3f3 can be directly encoded. If the value is 0x3f4 or
+/// greater, then the low 4 bits have special meaning as follows:
+/// - Bit 0-1
+/// indicate the number of words' of adjustment (1-4), minus 1
+/// - Bit 2
+/// indicates if the prologue combined adjustment into push
+/// - Bit 3
+/// indicates if the epilogue combined adjustment into pop
+///
+/// RESTRICTIONS:
+/// - IF C is SET:
+/// + L flag must be set since frame chaining requires r11 and lr
+/// + r11 must NOT be included in the set of registers described by Reg
+/// - IF Ret is 0:
+/// + L flag must be set
+
+// NOTE: RuntimeFunction is meant to be a simple class that provides raw access
+// to all fields in the structure. The accessor methods reflect the names of
+// the bitfields that they correspond to. Although some obvious simplifications
+// are possible via merging of methods, it would prevent the use of this class
+// to fully inspect the contents of the data structure which is particularly
+// useful for scenarios such as llvm-readobj to aid in testing.
+
+class RuntimeFunction {
+public:
+ const support::ulittle32_t BeginAddress;
+ const support::ulittle32_t UnwindData;
+
+ RuntimeFunction(const support::ulittle32_t *Data)
+ : BeginAddress(Data[0]), UnwindData(Data[1]) {}
+
+ RuntimeFunction(const support::ulittle32_t BeginAddress,
+ const support::ulittle32_t UnwindData)
+ : BeginAddress(BeginAddress), UnwindData(UnwindData) {}
+
+ RuntimeFunctionFlag Flag() const {
+ return RuntimeFunctionFlag(UnwindData & 0x3);
+ }
+
+ uint32_t ExceptionInformationRVA() const {
+ assert(Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
+ "unpacked form required for this operation");
+ return (UnwindData & ~0x3);
+ }
+
+ uint32_t PackedUnwindData() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return (UnwindData & ~0x3);
+ }
+ uint32_t FunctionLength() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return (((UnwindData & 0x00001ffc) >> 2) << 1);
+ }
+ ReturnType Ret() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ assert(((UnwindData & 0x00006000) || L()) && "L must be set to 1");
+ return ReturnType((UnwindData & 0x00006000) >> 13);
+ }
+ bool H() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x00008000) >> 15);
+ }
+ uint8_t Reg() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x00070000) >> 16);
+ }
+ bool R() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x00080000) >> 19);
+ }
+ bool L() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x00100000) >> 20);
+ }
+ bool C() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ assert(((~UnwindData & 0x00200000) || L()) &&
+ "L flag must be set, chaining requires r11 and LR");
+ assert(((~UnwindData & 0x00200000) || (Reg() < 7) || R()) &&
+ "r11 must not be included in Reg; C implies r11");
+ return ((UnwindData & 0x00200000) >> 21);
+ }
+ uint16_t StackAdjust() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0xffc00000) >> 22);
+ }
+};
+
+/// PrologueFolding - pseudo-flag derived from Stack Adjust indicating that the
+/// prologue has stack adjustment combined into the push
+inline bool PrologueFolding(const RuntimeFunction &RF) {
+ return RF.StackAdjust() >= 0x3f4 && (RF.StackAdjust() & 0x4);
+}
+/// Epilogue - pseudo-flag derived from Stack Adjust indicating that the
+/// epilogue has stack adjustment combined into the pop
+inline bool EpilogueFolding(const RuntimeFunction &RF) {
+ return RF.StackAdjust() >= 0x3f4 && (RF.StackAdjust() & 0x8);
+}
+/// StackAdjustment - calculated stack adjustment in words. The stack
+/// adjustment should be determined via this function to account for the special
+/// handling the special encoding when the value is >= 0x3f4.
+inline uint16_t StackAdjustment(const RuntimeFunction &RF) {
+ uint16_t Adjustment = RF.StackAdjust();
+ if (Adjustment >= 0x3f4)
+ return (Adjustment & 0x3) ? ((Adjustment & 0x3) << 2) - 1 : 0;
+ return Adjustment;
+}
+
+/// SavedRegisterMask - Utility function to calculate the set of saved general
+/// purpose (r0-r15) and VFP (d0-d31) registers.
+std::pair<uint16_t, uint32_t> SavedRegisterMask(const RuntimeFunction &RF);
+
+/// ExceptionDataRecord - An entry in the table of exception data (.xdata)
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +-------+---------+-+-+-+---+-----------------------------------+
+/// | C Wrd | Epi Cnt |F|E|X|Ver| Function Length |
+/// +-------+--------+'-'-'-'---'---+-------------------------------+
+/// | Reserved |Ex. Code Words| (Extended Epilogue Count) |
+/// +-------+--------+--------------+-------------------------------+
+///
+/// Function Length : 18-bit field indicating the total length of the function
+/// in bytes divided by 2. If a function is larger than
+/// 512KB, then multiple pdata and xdata records must be used.
+/// Vers : 2-bit field describing the version of the remaining structure. Only
+/// version 0 is currently defined (values 1-3 are not permitted).
+/// X : 1-bit field indicating the presence of exception data
+/// E : 1-bit field indicating that the single epilogue is packed into the
+/// header
+/// F : 1-bit field indicating that the record describes a function fragment
+/// (implies that no prologue is present, and prologue processing should be
+/// skipped)
+/// Epilogue Count : 5-bit field that differs in meaning based on the E field.
+///
+/// If E is set, then this field specifies the index of the
+/// first unwind code describing the (only) epilogue.
+///
+/// Otherwise, this field indicates the number of exception
+/// scopes. If more than 31 scopes exist, then this field and
+/// the Code Words field must both be set to 0 to indicate that
+/// an extension word is required.
+/// Code Words : 4-bit field that species the number of 32-bit words needed to
+/// contain all the unwind codes. If more than 15 words (63 code
+/// bytes) are required, then this field and the Epilogue Count
+/// field must both be set to 0 to indicate that an extension word
+/// is required.
+/// Extended Epilogue Count, Extended Code Words :
+/// Valid only if Epilog Count and Code Words are both
+/// set to 0. Provides an 8-bit extended code word
+/// count and 16-bits for epilogue count
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +----------------+------+---+---+-------------------------------+
+/// | Ep Start Idx | Cond |Res| Epilogue Start Offset |
+/// +----------------+------+---+-----------------------------------+
+///
+/// If the E bit is unset in the header, the header is followed by a series of
+/// epilogue scopes, which are sorted by their offset.
+///
+/// Epilogue Start Offset: 18-bit field encoding the offset of epilogue relative
+/// to the start of the function in bytes divided by two
+/// Res : 2-bit field reserved for future expansion (must be set to 0)
+/// Condition : 4-bit field providing the condition under which the epilogue is
+/// executed. Unconditional epilogues should set this field to 0xe.
+/// Epilogues must be entirely conditional or unconditional, and in
+/// Thumb-2 mode. The epilogue beings with the first instruction
+/// after the IT opcode.
+/// Epilogue Start Index : 8-bit field indicating the byte index of the first
+/// unwind code describing the epilogue
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +---------------+---------------+---------------+---------------+
+/// | Unwind Code 3 | Unwind Code 2 | Unwind Code 1 | Unwind Code 0 |
+/// +---------------+---------------+---------------+---------------+
+///
+/// Following the epilogue scopes, the byte code describing the unwinding
+/// follows. This is padded to align up to word alignment. Bytes are stored in
+/// little endian.
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +---------------------------------------------------------------+
+/// | Exception Handler RVA (requires X = 1) |
+/// +---------------------------------------------------------------+
+/// | (possibly followed by data required for exception handler) |
+/// +---------------------------------------------------------------+
+///
+/// If the X bit is set in the header, the unwind byte code is followed by the
+/// exception handler information. This constants of one Exception Handler RVA
+/// which is the address to the exception handler, followed immediately by the
+/// variable length data associated with the exception handler.
+///
+
+struct EpilogueScope {
+ const support::ulittle32_t ES;
+
+ EpilogueScope(const support::ulittle32_t Data) : ES(Data) {}
+ uint32_t EpilogueStartOffset() const {
+ return (ES & 0x0003ffff);
+ }
+ uint8_t Res() const {
+ return ((ES & 0x000c0000) >> 18);
+ }
+ uint8_t Condition() const {
+ return ((ES & 0x00f00000) >> 20);
+ }
+ uint8_t EpilogueStartIndex() const {
+ return ((ES & 0xff000000) >> 24);
+ }
+};
+
+struct ExceptionDataRecord;
+inline size_t HeaderWords(const ExceptionDataRecord &XR);
+
+struct ExceptionDataRecord {
+ const support::ulittle32_t *Data;
+
+ ExceptionDataRecord(const support::ulittle32_t *Data) : Data(Data) {}
+
+ uint32_t FunctionLength() const {
+ return (Data[0] & 0x0003ffff);
+ }
+
+ uint8_t Vers() const {
+ return (Data[0] & 0x000C0000) >> 18;
+ }
+
+ bool X() const {
+ return ((Data[0] & 0x00100000) >> 20);
+ }
+
+ bool E() const {
+ return ((Data[0] & 0x00200000) >> 21);
+ }
+
+ bool F() const {
+ return ((Data[0] & 0x00400000) >> 22);
+ }
+
+ uint8_t EpilogueCount() const {
+ if (HeaderWords(*this) == 1)
+ return (Data[0] & 0x0f800000) >> 23;
+ return Data[1] & 0x0000ffff;
+ }
+
+ uint8_t CodeWords() const {
+ if (HeaderWords(*this) == 1)
+ return (Data[0] & 0xf0000000) >> 28;
+ return (Data[1] & 0x00ff0000) >> 16;
+ }
+
+ ArrayRef<support::ulittle32_t> EpilogueScopes() const {
+ assert(E() == 0 && "epilogue scopes are only present when the E bit is 0");
+ size_t Offset = HeaderWords(*this);
+ return ArrayRef<support::ulittle32_t>(&Data[Offset], EpilogueCount());
+ }
+
+ ArrayRef<support::ulittle8_t> UnwindByteCode() const {
+ const size_t Offset = HeaderWords(*this)
+ + (E() ? 0 : EpilogueCount());
+ const support::ulittle8_t *ByteCode =
+ reinterpret_cast<const support::ulittle8_t *>(&Data[Offset]);
+ return ArrayRef<support::ulittle8_t>(ByteCode,
+ CodeWords() * sizeof(uint32_t));
+ }
+
+ uint32_t ExceptionHandlerRVA() const {
+ assert(X() && "Exception Handler RVA is only valid if the X bit is set");
+ return Data[HeaderWords(*this) + EpilogueCount() + CodeWords()];
+ }
+
+ uint32_t ExceptionHandlerParameter() const {
+ assert(X() && "Exception Handler RVA is only valid if the X bit is set");
+ return Data[HeaderWords(*this) + EpilogueCount() + CodeWords() + 1];
+ }
+};
+
+inline size_t HeaderWords(const ExceptionDataRecord &XR) {
+ return (XR.Data[0] & 0xff800000) ? 1 : 2;
+}
+}
+}
+}
+
+#endif
+
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index f0e5c7d..e09ef07 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -553,7 +553,8 @@ namespace COFF {
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
/// Code integrity checks are enforced.
IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
- IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100, ///< Image is NX compatible.
+ ///< Image is NX compatible.
+ IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
/// Isolation aware, but do not isolate the image.
IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200,
/// Does not use structured exception handling (SEH). No SEH handler may be
@@ -561,7 +562,12 @@ namespace COFF {
IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400,
/// Do not bind the image.
IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800,
- IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000, ///< A WDM driver.
+ ///< Image should execute in an AppContainer.
+ IMAGE_DLL_CHARACTERISTICS_APPCONTAINER = 0x1000,
+ ///< A WDM driver.
+ IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000,
+ ///< Image supports Control Flow Guard.
+ IMAGE_DLL_CHARACTERISTICS_GUARD_CF = 0x4000,
/// Terminal Server aware.
IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
};
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 1edcd45..25bf32a 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -61,6 +61,12 @@
#define LLVM_MSC_PREREQ(version) 0
#endif
+#ifndef _MSC_VER
+#define LLVM_NOEXCEPT noexcept
+#else
+#define LLVM_NOEXCEPT
+#endif
+
/// \brief Does the compiler support r-value reference *this?
///
/// Sadly, this is separate from just r-value reference support because GCC
diff --git a/include/llvm/Support/ConvertUTF.h b/include/llvm/Support/ConvertUTF.h
index 2820366..a184d0d 100644
--- a/include/llvm/Support/ConvertUTF.h
+++ b/include/llvm/Support/ConvertUTF.h
@@ -136,7 +136,19 @@ ConversionResult ConvertUTF8toUTF16 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
-ConversionResult ConvertUTF8toUTF32 (
+/**
+ * Convert a partial UTF8 sequence to UTF32. If the sequence ends in an
+ * incomplete code unit sequence, returns \c sourceExhausted.
+ */
+ConversionResult ConvertUTF8toUTF32Partial(
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+/**
+ * Convert a partial UTF8 sequence to UTF32. If the sequence ends in an
+ * incomplete code unit sequence, returns \c sourceIllegal.
+ */
+ConversionResult ConvertUTF8toUTF32(
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h
index c132373..3869ebd 100644
--- a/include/llvm/Support/CrashRecoveryContext.h
+++ b/include/llvm/Support/CrashRecoveryContext.h
@@ -87,6 +87,9 @@ public:
/// requested stack size).
///
/// See RunSafely() and llvm_execute_on_thread().
+ ///
+ /// On Darwin, if PRIO_DARWIN_BG is set on the calling thread, it will be
+ /// propagated to the new thread as well.
bool RunSafelyOnThread(function_ref<void()>, unsigned RequestedStackSize = 0);
bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
unsigned RequestedStackSize = 0) {
diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
index a26070c..1f0c8eb 100644
--- a/include/llvm/Support/DataTypes.h.cmake
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -37,6 +37,16 @@
#include <math.h>
#endif
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#error "Compiler must provide an implementation of stdint.h"
+#endif
+
#ifndef _MSC_VER
/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
@@ -55,14 +65,6 @@
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
#include <sys/types.h>
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
#ifdef _AIX
#include "llvm/Support/AIXDataTypesFix.h"
#endif
@@ -77,11 +79,6 @@ typedef u_int64_t uint64_t;
#endif
#else /* _MSC_VER */
-/* Visual C++ doesn't provide standard integer headers, but it does provide
- built-in data types. */
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
#include <stdlib.h>
#include <stddef.h>
#include <sys/types.h>
@@ -90,93 +87,21 @@ typedef u_int64_t uint64_t;
#else
#include <math.h>
#endif
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-typedef signed int int32_t;
-typedef unsigned int uint32_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
+
#if defined(_WIN64)
- typedef signed __int64 ssize_t;
+typedef signed __int64 ssize_t;
#else
- typedef signed int ssize_t;
-#endif
-#ifndef INT8_MAX
-# define INT8_MAX 127
-#endif
-#ifndef INT8_MIN
-# define INT8_MIN -128
-#endif
-#ifndef UINT8_MAX
-# define UINT8_MAX 255
-#endif
-#ifndef INT16_MAX
-# define INT16_MAX 32767
-#endif
-#ifndef INT16_MIN
-# define INT16_MIN -32768
-#endif
-#ifndef UINT16_MAX
-# define UINT16_MAX 65535
-#endif
-#ifndef INT32_MAX
-# define INT32_MAX 2147483647
-#endif
-#ifndef INT32_MIN
-/* MSC treats -2147483648 as -(2147483648U). */
-# define INT32_MIN (-INT32_MAX - 1)
-#endif
-#ifndef UINT32_MAX
-# define UINT32_MAX 4294967295U
-#endif
-/* Certain compatibility updates to VC++ introduce the `cstdint'
- * header, which defines the INT*_C macros. On default installs they
- * are absent. */
-#ifndef INT8_C
-# define INT8_C(C) C##i8
-#endif
-#ifndef UINT8_C
-# define UINT8_C(C) C##ui8
-#endif
-#ifndef INT16_C
-# define INT16_C(C) C##i16
-#endif
-#ifndef UINT16_C
-# define UINT16_C(C) C##ui16
-#endif
-#ifndef INT32_C
-# define INT32_C(C) C##i32
-#endif
-#ifndef UINT32_C
-# define UINT32_C(C) C##ui32
-#endif
-#ifndef INT64_C
-# define INT64_C(C) C##i64
-#endif
-#ifndef UINT64_C
-# define UINT64_C(C) C##ui64
-#endif
-
-#ifndef PRId64
-# define PRId64 "I64d"
-#endif
-#ifndef PRIi64
-# define PRIi64 "I64i"
-#endif
-#ifndef PRIo64
-# define PRIo64 "I64o"
-#endif
-#ifndef PRIu64
-# define PRIu64 "I64u"
-#endif
-#ifndef PRIx64
-# define PRIx64 "I64x"
-#endif
-#ifndef PRIX64
-# define PRIX64 "I64X"
-#endif
+typedef signed int ssize_t;
+#endif /* _WIN64 */
+
+#ifndef HAVE_INTTYPES_H
+#define PRId64 "I64d"
+#define PRIi64 "I64i"
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+#define PRIx64 "I64x"
+#define PRIX64 "I64X"
+#endif /* HAVE_INTTYPES_H */
#endif /* _MSC_VER */
diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
index 7fc9b72..09cfcdf 100644
--- a/include/llvm/Support/DataTypes.h.in
+++ b/include/llvm/Support/DataTypes.h.in
@@ -37,6 +37,16 @@
#include <math.h>
#endif
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#error "Compiler must provide an implementation of stdint.h"
+#endif
+
#ifndef _MSC_VER
/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
@@ -55,14 +65,6 @@
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
#include <sys/types.h>
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
#ifdef _AIX
#include "llvm/Support/AIXDataTypesFix.h"
#endif
@@ -77,8 +79,6 @@ typedef u_int64_t uint64_t;
#endif
#else /* _MSC_VER */
-/* Visual C++ doesn't provide standard integer headers, but it does provide
- built-in data types. */
#include <stdlib.h>
#include <stddef.h>
#include <sys/types.h>
@@ -87,94 +87,21 @@ typedef u_int64_t uint64_t;
#else
#include <math.h>
#endif
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-typedef signed int int32_t;
-typedef unsigned int uint32_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
+
#if defined(_WIN64)
- typedef signed __int64 ssize_t;
+typedef signed __int64 ssize_t;
#else
- typedef signed int ssize_t;
-#endif
-
-#ifndef INT8_MAX
-# define INT8_MAX 127
-#endif
-#ifndef INT8_MIN
-# define INT8_MIN -128
-#endif
-#ifndef UINT8_MAX
-# define UINT8_MAX 255
-#endif
-#ifndef INT16_MAX
-# define INT16_MAX 32767
-#endif
-#ifndef INT16_MIN
-# define INT16_MIN -32768
-#endif
-#ifndef UINT16_MAX
-# define UINT16_MAX 65535
-#endif
-#ifndef INT32_MAX
-# define INT32_MAX 2147483647
-#endif
-#ifndef INT32_MIN
-/* MSC treats -2147483648 as -(2147483648U). */
-# define INT32_MIN (-INT32_MAX - 1)
-#endif
-#ifndef UINT32_MAX
-# define UINT32_MAX 4294967295U
-#endif
-/* Certain compatibility updates to VC++ introduce the `cstdint'
- * header, which defines the INT*_C macros. On default installs they
- * are absent. */
-#ifndef INT8_C
-# define INT8_C(C) C##i8
-#endif
-#ifndef UINT8_C
-# define UINT8_C(C) C##ui8
-#endif
-#ifndef INT16_C
-# define INT16_C(C) C##i16
-#endif
-#ifndef UINT16_C
-# define UINT16_C(C) C##ui16
-#endif
-#ifndef INT32_C
-# define INT32_C(C) C##i32
-#endif
-#ifndef UINT32_C
-# define UINT32_C(C) C##ui32
-#endif
-#ifndef INT64_C
-# define INT64_C(C) C##i64
-#endif
-#ifndef UINT64_C
-# define UINT64_C(C) C##ui64
-#endif
-
-#ifndef PRId64
-# define PRId64 "I64d"
-#endif
-#ifndef PRIi64
-# define PRIi64 "I64i"
-#endif
-#ifndef PRIo64
-# define PRIo64 "I64o"
-#endif
-#ifndef PRIu64
-# define PRIu64 "I64u"
-#endif
-#ifndef PRIx64
-# define PRIx64 "I64x"
-#endif
-#ifndef PRIX64
-# define PRIX64 "I64X"
-#endif
+typedef signed int ssize_t;
+#endif /* _WIN64 */
+
+#ifndef HAVE_INTTYPES_H
+#define PRId64 "I64d"
+#define PRIi64 "I64i"
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+#define PRIx64 "I64x"
+#define PRIX64 "I64X"
+#endif /* HAVE_INTTYPES_H */
#endif /* _MSC_VER */
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index ca31644..cd9f756 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -57,7 +57,6 @@ enum LLVMConstants : uint32_t {
DW_TAG_user_base = 0x1000, // Recommended base for user tags.
DWARF_VERSION = 4, // Default dwarf version we output.
- DW_CIE_VERSION = 1, // Common frame information version.
DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes.
DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames.
DW_ARANGES_VERSION = 2 // Section version number for .debug_aranges.
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 0b3e55b..67cc651 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -124,6 +124,8 @@ enum {
};
// Machine architectures
+// See current registered ELF machine architectures at:
+// http://www.uxsglobal.com/developers/gabi/latest/ch4.eheader.html
enum {
EM_NONE = 0, // No machine
EM_M32 = 1, // AT&T WE 32100
@@ -287,7 +289,26 @@ enum {
EM_RL78 = 197, // Renesas RL78 family
EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor
EM_78KOR = 199, // Renesas 78KOR family
- EM_56800EX = 200 // Freescale 56800EX Digital Signal Controller (DSC)
+ EM_56800EX = 200, // Freescale 56800EX Digital Signal Controller (DSC)
+ EM_BA1 = 201, // Beyond BA1 CPU architecture
+ EM_BA2 = 202, // Beyond BA2 CPU architecture
+ EM_XCORE = 203, // XMOS xCORE processor family
+ EM_MCHP_PIC = 204, // Microchip 8-bit PIC(r) family
+ EM_INTEL205 = 205, // Reserved by Intel
+ EM_INTEL206 = 206, // Reserved by Intel
+ EM_INTEL207 = 207, // Reserved by Intel
+ EM_INTEL208 = 208, // Reserved by Intel
+ EM_INTEL209 = 209, // Reserved by Intel
+ EM_KM32 = 210, // KM211 KM32 32-bit processor
+ EM_KMX32 = 211, // KM211 KMX32 32-bit processor
+ EM_KMX16 = 212, // KM211 KMX16 16-bit processor
+ EM_KMX8 = 213, // KM211 KMX8 8-bit processor
+ EM_KVARC = 214, // KM211 KVARC processor
+ EM_CDP = 215, // Paneve CDP architecture family
+ EM_COGE = 216, // Cognitive Smart Memory Processor
+ EM_COOL = 217, // iCelero CoolEngine
+ EM_NORC = 218, // Nanoradio Optimized RISC
+ EM_CSR_KALIMBA = 219 // CSR Kalimba architecture family
};
// Object file classes.
@@ -1278,6 +1299,7 @@ enum : unsigned {
SHT_MIPS_REGINFO = 0x70000006, // Register usage information
SHT_MIPS_OPTIONS = 0x7000000d, // General options
+ SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information.
SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
@@ -1595,7 +1617,8 @@ enum {
// MIPS program header types.
PT_MIPS_REGINFO = 0x70000000, // Register usage information.
PT_MIPS_RTPROC = 0x70000001, // Runtime procedure table.
- PT_MIPS_OPTIONS = 0x70000002 // Options segment.
+ PT_MIPS_OPTIONS = 0x70000002, // Options segment.
+ PT_MIPS_ABIFLAGS = 0x70000003 // Abiflags segment.
};
// Segment flag bits.
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index 2c5ab74..455d0fc 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -38,7 +38,7 @@ namespace endian {
template<typename value_type, endianness endian>
inline value_type byte_swap(value_type value) {
if (endian != native && sys::IsBigEndianHost != (endian == big))
- return sys::SwapByteOrder(value);
+ sys::swapByteOrder(value);
return value;
}
diff --git a/include/llvm/Support/Errc.h b/include/llvm/Support/Errc.h
new file mode 100644
index 0000000..80bfe2a
--- /dev/null
+++ b/include/llvm/Support/Errc.h
@@ -0,0 +1,86 @@
+//===- llvm/Support/Errc.h - Defines the llvm::errc enum --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// While std::error_code works OK on all platforms we use, there are some
+// some problems with std::errc that can be avoided by using our own
+// enumeration:
+//
+// * std::errc is a namespace in some implementations. That meas that ADL
+// doesn't work and it is sometimes necessary to write std::make_error_code
+// or in templates:
+// using std::make_error_code;
+// make_error_code(...);
+//
+// with this enum it is safe to always just use make_error_code.
+//
+// * Some implementations define fewer names than others. This header has
+// the intersection of all the ones we support.
+//
+// * std::errc is just marked with is_error_condition_enum. This means that
+// common patters like AnErrorCode == errc::no_such_file_or_directory take
+// 4 virtual calls instead of two comparisons.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ERRC_H
+#define LLVM_SUPPORT_ERRC_H
+
+#include <system_error>
+
+namespace llvm {
+enum class errc {
+ argument_list_too_long = int(std::errc::argument_list_too_long),
+ argument_out_of_domain = int(std::errc::argument_out_of_domain),
+ bad_address = int(std::errc::bad_address),
+ bad_file_descriptor = int(std::errc::bad_file_descriptor),
+ broken_pipe = int(std::errc::broken_pipe),
+ device_or_resource_busy = int(std::errc::device_or_resource_busy),
+ directory_not_empty = int(std::errc::directory_not_empty),
+ executable_format_error = int(std::errc::executable_format_error),
+ file_exists = int(std::errc::file_exists),
+ file_too_large = int(std::errc::file_too_large),
+ filename_too_long = int(std::errc::filename_too_long),
+ function_not_supported = int(std::errc::function_not_supported),
+ illegal_byte_sequence = int(std::errc::illegal_byte_sequence),
+ inappropriate_io_control_operation =
+ int(std::errc::inappropriate_io_control_operation),
+ interrupted = int(std::errc::interrupted),
+ invalid_argument = int(std::errc::invalid_argument),
+ invalid_seek = int(std::errc::invalid_seek),
+ io_error = int(std::errc::io_error),
+ is_a_directory = int(std::errc::is_a_directory),
+ no_child_process = int(std::errc::no_child_process),
+ no_lock_available = int(std::errc::no_lock_available),
+ no_space_on_device = int(std::errc::no_space_on_device),
+ no_such_device_or_address = int(std::errc::no_such_device_or_address),
+ no_such_device = int(std::errc::no_such_device),
+ no_such_file_or_directory = int(std::errc::no_such_file_or_directory),
+ no_such_process = int(std::errc::no_such_process),
+ not_a_directory = int(std::errc::not_a_directory),
+ not_enough_memory = int(std::errc::not_enough_memory),
+ operation_not_permitted = int(std::errc::operation_not_permitted),
+ permission_denied = int(std::errc::permission_denied),
+ read_only_file_system = int(std::errc::read_only_file_system),
+ resource_deadlock_would_occur = int(std::errc::resource_deadlock_would_occur),
+ resource_unavailable_try_again =
+ int(std::errc::resource_unavailable_try_again),
+ result_out_of_range = int(std::errc::result_out_of_range),
+ too_many_files_open_in_system = int(std::errc::too_many_files_open_in_system),
+ too_many_files_open = int(std::errc::too_many_files_open),
+ too_many_links = int(std::errc::too_many_links)
+};
+
+inline std::error_code make_error_code(errc E) {
+ return std::error_code(static_cast<int>(E), std::generic_category());
+}
+}
+
+namespace std {
+template <> struct is_error_code_enum<llvm::errc> : std::true_type {};
+}
+#endif
diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h
index ac3a4d8..9afd52d 100644
--- a/include/llvm/Support/ErrorHandling.h
+++ b/include/llvm/Support/ErrorHandling.h
@@ -30,9 +30,6 @@ namespace llvm {
/// install_fatal_error_handler - Installs a new error handler to be used
/// whenever a serious (non-recoverable) error is encountered by LLVM.
///
- /// If you are using llvm_start_multithreaded, you should register the handler
- /// before doing that.
- ///
/// If no error handler is installed the default is to print the error message
/// to stderr, and call exit(1). If an error handler is installed then it is
/// the handler's responsibility to log the message, it will no longer be
@@ -50,8 +47,6 @@ namespace llvm {
void *user_data = nullptr);
/// Restores default error handling behaviour.
- /// This must not be called between llvm_start_multithreaded() and
- /// llvm_stop_multithreaded().
void remove_fatal_error_handler();
/// ScopedFatalErrorHandler - This is a simple helper class which just
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
index becd957..0742a2d 100644
--- a/include/llvm/Support/ErrorOr.h
+++ b/include/llvm/Support/ErrorOr.h
@@ -18,8 +18,8 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/system_error.h"
#include <cassert>
+#include <system_error>
#include <type_traits>
namespace llvm {
@@ -94,15 +94,16 @@ private:
public:
template <class E>
- ErrorOr(E ErrorCode, typename std::enable_if<is_error_code_enum<E>::value ||
- is_error_condition_enum<E>::value,
- void *>::type = 0)
+ ErrorOr(E ErrorCode,
+ typename std::enable_if<std::is_error_code_enum<E>::value ||
+ std::is_error_condition_enum<E>::value,
+ void *>::type = 0)
: HasError(true) {
- new (getErrorStorage()) error_code(make_error_code(ErrorCode));
+ new (getErrorStorage()) std::error_code(make_error_code(ErrorCode));
}
- ErrorOr(llvm::error_code EC) : HasError(true) {
- new (getErrorStorage()) error_code(EC);
+ ErrorOr(std::error_code EC) : HasError(true) {
+ new (getErrorStorage()) std::error_code(EC);
}
ErrorOr(T Val) : HasError(false) {
@@ -162,8 +163,8 @@ public:
reference get() { return *getStorage(); }
const_reference get() const { return const_cast<ErrorOr<T> >(this)->get(); }
- error_code getError() const {
- return HasError ? *getErrorStorage() : error_code::success();
+ std::error_code getError() const {
+ return HasError ? *getErrorStorage() : std::error_code();
}
pointer operator ->() {
@@ -184,7 +185,7 @@ private:
} else {
// Get other's error.
HasError = true;
- new (getErrorStorage()) error_code(Other.getError());
+ new (getErrorStorage()) std::error_code(Other.getError());
}
}
@@ -216,7 +217,7 @@ private:
} else {
// Get other's error.
HasError = true;
- new (getErrorStorage()) error_code(Other.getError());
+ new (getErrorStorage()) std::error_code(Other.getError());
}
}
@@ -247,28 +248,29 @@ private:
return reinterpret_cast<const storage_type*>(TStorage.buffer);
}
- error_code *getErrorStorage() {
+ std::error_code *getErrorStorage() {
assert(HasError && "Cannot get error when a value exists!");
- return reinterpret_cast<error_code*>(ErrorStorage.buffer);
+ return reinterpret_cast<std::error_code *>(ErrorStorage.buffer);
}
- const error_code *getErrorStorage() const {
+ const std::error_code *getErrorStorage() const {
return const_cast<ErrorOr<T> *>(this)->getErrorStorage();
}
union {
AlignedCharArrayUnion<storage_type> TStorage;
- AlignedCharArrayUnion<error_code> ErrorStorage;
+ AlignedCharArrayUnion<std::error_code> ErrorStorage;
};
bool HasError : 1;
};
-template<class T, class E>
-typename std::enable_if<is_error_code_enum<E>::value ||
- is_error_condition_enum<E>::value, bool>::type
-operator ==(ErrorOr<T> &Err, E Code) {
- return error_code(Err) == Code;
+template <class T, class E>
+typename std::enable_if<std::is_error_code_enum<E>::value ||
+ std::is_error_condition_enum<E>::value,
+ bool>::type
+operator==(ErrorOr<T> &Err, E Code) {
+ return std::error_code(Err) == Code;
}
} // end namespace llvm
diff --git a/include/llvm/Support/FEnv.h b/include/llvm/Support/FEnv.h
deleted file mode 100644
index 8560ee0..0000000
--- a/include/llvm/Support/FEnv.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===- llvm/Support/FEnv.h - Host floating-point exceptions ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides an operating system independent interface to
-// floating-point exception interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_FENV_H
-#define LLVM_SUPPORT_FENV_H
-
-#include "llvm/Config/config.h"
-#include <cerrno>
-#ifdef HAVE_FENV_H
-#include <fenv.h>
-#endif
-
-// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s
-// fenv.h; see PR6907 for details.
-#if defined(__clang__) && defined(_GLIBCXX_FENV_H)
-#undef HAVE_FENV_H
-#endif
-
-namespace llvm {
-namespace sys {
-
-/// llvm_fenv_clearexcept - Clear the floating-point exception state.
-static inline void llvm_fenv_clearexcept() {
-#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT
- feclearexcept(FE_ALL_EXCEPT);
-#endif
- errno = 0;
-}
-
-/// llvm_fenv_testexcept - Test if a floating-point exception was raised.
-static inline bool llvm_fenv_testexcept() {
- int errno_val = errno;
- if (errno_val == ERANGE || errno_val == EDOM)
- return true;
-#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
- if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
- return true;
-#endif
- return false;
-}
-
-} // End sys namespace
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
index a8a48fa..0a9a979 100644
--- a/include/llvm/Support/FileOutputBuffer.h
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -20,8 +20,6 @@
#include "llvm/Support/FileSystem.h"
namespace llvm {
-class error_code;
-
/// FileOutputBuffer - This interface provides simple way to create an in-memory
/// buffer which will be written to a file. During the lifetime of these
/// objects, the content or existence of the specified file is undefined. That
@@ -39,9 +37,9 @@ public:
/// Factory method to create an OutputBuffer object which manages a read/write
/// buffer of the specified size. When committed, the buffer will be written
/// to the file at the specified path.
- static error_code create(StringRef FilePath, size_t Size,
- std::unique_ptr<FileOutputBuffer> &Result,
- unsigned Flags = 0);
+ static std::error_code create(StringRef FilePath, size_t Size,
+ std::unique_ptr<FileOutputBuffer> &Result,
+ unsigned Flags = 0);
/// Returns a pointer to the start of the buffer.
uint8_t *getBufferStart() {
@@ -68,7 +66,7 @@ public:
/// is called, the file is deleted in the destructor. The optional parameter
/// is used if it turns out you want the file size to be smaller than
/// initially requested.
- error_code commit(int64_t NewSmallerSize = -1);
+ std::error_code commit(int64_t NewSmallerSize = -1);
/// If this object was previously committed, the destructor just deletes
/// this object. If this object was not committed, the destructor
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index 806a3e3..556701c 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -33,11 +33,11 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TimeValue.h"
-#include "llvm/Support/system_error.h"
#include <ctime>
#include <iterator>
#include <stack>
#include <string>
+#include <system_error>
#include <tuple>
#include <vector>
@@ -49,26 +49,18 @@ namespace llvm {
namespace sys {
namespace fs {
-/// An "enum class" enumeration for the file system's view of the type.
-struct file_type {
- enum Impl {
- status_error,
- file_not_found,
- regular_file,
- directory_file,
- symlink_file,
- block_file,
- character_file,
- fifo_file,
- socket_file,
- type_unknown
- };
-
- file_type(Impl V) : V(V) {}
- operator Impl() const { return V; }
-
-private:
- Impl V;
+/// An enumeration for the file system's view of the type.
+enum class file_type {
+ status_error,
+ file_not_found,
+ regular_file,
+ directory_file,
+ symlink_file,
+ block_file,
+ character_file,
+ fifo_file,
+ socket_file,
+ type_unknown
};
/// space_info - Self explanatory.
@@ -142,7 +134,7 @@ public:
};
/// file_status - Represents the result of a call to stat and friends. It has
-/// a platform specific member to store the result.
+/// a platform-specific member to store the result.
class file_status
{
#if defined(LLVM_ON_UNIX)
@@ -281,8 +273,8 @@ private:
///
/// @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);
+/// platform-specific error_code.
+std::error_code make_absolute(SmallVectorImpl<char> &path);
/// @brief Normalize path separators in \a Path
///
@@ -290,7 +282,7 @@ error_code make_absolute(SmallVectorImpl<char> &path);
/// This is particularly useful when cross-compiling Windows on Linux, but is
/// safe to invoke on Windows, which accepts both characters as a path
/// separator.
-error_code normalize_separators(SmallVectorImpl<char> &Path);
+std::error_code normalize_separators(SmallVectorImpl<char> &Path);
/// @brief Create all the non-existent directories in path.
///
@@ -298,7 +290,8 @@ error_code normalize_separators(SmallVectorImpl<char> &Path);
/// @returns errc::success if is_directory(path), otherwise a platform
/// specific error_code. If IgnoreExisting is false, also returns
/// error if the directory already existed.
-error_code create_directories(const Twine &path, bool IgnoreExisting = true);
+std::error_code create_directories(const Twine &path,
+ bool IgnoreExisting = true);
/// @brief Create the directory in path.
///
@@ -306,7 +299,7 @@ error_code create_directories(const Twine &path, bool IgnoreExisting = true);
/// @returns errc::success if is_directory(path), otherwise a platform
/// specific error_code. If IgnoreExisting is false, also returns
/// error if the directory already existed.
-error_code create_directory(const Twine &path, bool IgnoreExisting = true);
+std::error_code create_directory(const Twine &path, bool IgnoreExisting = true);
/// @brief Create a link from \a from to \a to.
///
@@ -319,36 +312,42 @@ error_code create_directory(const Twine &path, bool IgnoreExisting = true);
/// @param from The path to hard link from. This is created.
/// @returns errc::success if the link was created, otherwise a platform
/// specific error_code.
-error_code create_link(const Twine &to, const Twine &from);
+std::error_code create_link(const Twine &to, const Twine &from);
/// @brief Get the current path.
///
/// @param result Holds the current path on return.
/// @returns errc::success if the current path has been stored in result,
-/// otherwise a platform specific error_code.
-error_code current_path(SmallVectorImpl<char> &result);
+/// otherwise a platform-specific error_code.
+std::error_code current_path(SmallVectorImpl<char> &result);
/// @brief Remove path. Equivalent to POSIX remove().
///
/// @param path Input path.
/// @returns errc::success if path has been removed or didn't exist, otherwise a
-/// platform specific error code. If IgnoreNonExisting is false, also
+/// platform-specific error code. If IgnoreNonExisting is false, also
/// returns error if the file didn't exist.
-error_code remove(const Twine &path, bool IgnoreNonExisting = true);
+std::error_code remove(const Twine &path, bool IgnoreNonExisting = true);
/// @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);
+std::error_code rename(const Twine &from, const Twine &to);
+
+/// @brief Copy the contents of \a From to \a To.
+///
+/// @param From The path to copy from.
+/// @param To The path to copy to. This is created.
+std::error_code copy_file(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);
+/// platform-specific error_code.
+std::error_code resize_file(const Twine &path, uint64_t size);
/// @}
/// @name Physical Observers
@@ -367,8 +366,8 @@ bool exists(file_status status);
/// @param result Set to true if the file represented by status exists, false if
/// it does not. Undefined otherwise.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code exists(const Twine &path, bool &result);
+/// platform-specific error_code.
+std::error_code exists(const Twine &path, bool &result);
/// @brief Simpler version of exists for clients that don't need to
/// differentiate between an error and false.
@@ -409,8 +408,8 @@ bool equivalent(file_status A, file_status B);
/// @param result Set to true if stat(A) and stat(B) have the same device and
/// inode (or equivalent).
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code equivalent(const Twine &A, const Twine &B, bool &result);
+/// platform-specific error_code.
+std::error_code equivalent(const Twine &A, const Twine &B, bool &result);
/// @brief Simpler version of equivalent for clients that don't need to
/// differentiate between an error and false.
@@ -431,8 +430,8 @@ bool is_directory(file_status status);
/// @param result Set to true if \a path is a directory, false if it is not.
/// Undefined otherwise.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_directory(const Twine &path, bool &result);
+/// platform-specific error_code.
+std::error_code is_directory(const Twine &path, bool &result);
/// @brief Simpler version of is_directory for clients that don't need to
/// differentiate between an error and false.
@@ -453,8 +452,8 @@ bool is_regular_file(file_status status);
/// @param result Set to true if \a path is a regular file, false if it is not.
/// Undefined otherwise.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_regular_file(const Twine &path, bool &result);
+/// platform-specific error_code.
+std::error_code is_regular_file(const Twine &path, bool &result);
/// @brief Simpler version of is_regular_file for clients that don't need to
/// differentiate between an error and false.
@@ -479,41 +478,41 @@ bool is_other(file_status status);
/// @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.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_other(const Twine &path, bool &result);
+/// platform-specific error_code.
+std::error_code is_other(const Twine &path, bool &result);
/// @brief Get file status as if by POSIX stat().
///
/// @param path Input path.
/// @param result Set to the file status.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code status(const Twine &path, file_status &result);
+/// platform-specific error_code.
+std::error_code status(const Twine &path, file_status &result);
/// @brief A version for when a file descriptor is already available.
-error_code status(int FD, file_status &Result);
+std::error_code status(int FD, file_status &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.
-inline error_code file_size(const Twine &Path, uint64_t &Result) {
+/// platform-specific error_code.
+inline std::error_code file_size(const Twine &Path, uint64_t &Result) {
file_status Status;
- error_code EC = status(Path, Status);
+ std::error_code EC = status(Path, Status);
if (EC)
return EC;
Result = Status.getSize();
- return error_code::success();
+ return std::error_code();
}
/// @brief Set the file modification and access time.
///
/// @returns errc::success if the file times were successfully set, otherwise a
-/// platform specific error_code or errc::not_supported on platforms
-/// where the functionality isn't available.
-error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
+/// platform-specific error_code or errc::function_not_supported on
+/// platforms where the functionality isn't available.
+std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
/// @brief Is status available?
///
@@ -526,8 +525,8 @@ bool status_known(file_status s);
/// @param path Input path.
/// @param result Set to true if status() != status_error.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code status_known(const Twine &path, bool &result);
+/// platform-specific error_code.
+std::error_code status_known(const Twine &path, bool &result);
/// @brief Create a uniquely named file.
///
@@ -549,14 +548,14 @@ error_code status_known(const Twine &path, bool &result);
/// @param ResultFD Set to the opened file's file descriptor.
/// @param ResultPath Set to the opened file's absolute path.
/// @returns errc::success if Result{FD,Path} have been successfully set,
-/// otherwise a platform specific error_code.
-error_code createUniqueFile(const Twine &Model, int &ResultFD,
- SmallVectorImpl<char> &ResultPath,
- unsigned Mode = all_read | all_write);
+/// otherwise a platform-specific error_code.
+std::error_code createUniqueFile(const Twine &Model, int &ResultFD,
+ SmallVectorImpl<char> &ResultPath,
+ unsigned Mode = all_read | all_write);
/// @brief Simpler version for clients that don't want an open file.
-error_code createUniqueFile(const Twine &Model,
- SmallVectorImpl<char> &ResultPath);
+std::error_code createUniqueFile(const Twine &Model,
+ SmallVectorImpl<char> &ResultPath);
/// @brief Create a file in the system temporary directory.
///
@@ -566,16 +565,16 @@ error_code createUniqueFile(const Twine &Model,
///
/// This should be used for things like a temporary .s that is removed after
/// running the assembler.
-error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
- int &ResultFD,
- SmallVectorImpl<char> &ResultPath);
+std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+ int &ResultFD,
+ SmallVectorImpl<char> &ResultPath);
/// @brief Simpler version for clients that don't want an open file.
-error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
- SmallVectorImpl<char> &ResultPath);
+std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+ SmallVectorImpl<char> &ResultPath);
-error_code createUniqueDirectory(const Twine &Prefix,
- SmallVectorImpl<char> &ResultPath);
+std::error_code createUniqueDirectory(const Twine &Prefix,
+ SmallVectorImpl<char> &ResultPath);
enum OpenFlags : unsigned {
F_None = 0,
@@ -606,31 +605,10 @@ inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) {
return A;
}
-error_code openFileForWrite(const Twine &Name, int &ResultFD, OpenFlags Flags,
- unsigned Mode = 0666);
+std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
+ OpenFlags Flags, unsigned Mode = 0666);
-error_code openFileForRead(const Twine &Name, int &ResultFD);
-
-/// @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.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_magic(const Twine &path, const Twine &magic, bool &result);
-
-/// @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.
-/// @returns errc::success if result has been successfully set,
-/// errc::value_too_large if len is larger then the file pointed to by
-/// \a path, otherwise a platform specific error_code.
-error_code get_magic(const Twine &path, uint32_t len,
- SmallVectorImpl<char> &result);
+std::error_code openFileForRead(const Twine &Name, int &ResultFD);
/// @brief Identify the type of a binary file based on how magical it is.
file_magic identify_magic(StringRef magic);
@@ -640,10 +618,10 @@ file_magic identify_magic(StringRef magic);
/// @param path Input path.
/// @param result Set to the type of file, or file_magic::unknown.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code identify_magic(const Twine &path, file_magic &result);
+/// platform-specific error_code.
+std::error_code identify_magic(const Twine &path, file_magic &result);
-error_code getUniqueID(const Twine Path, UniqueID &Result);
+std::error_code getUniqueID(const Twine Path, UniqueID &Result);
/// This class represents a memory mapped file. It is based on
/// boost::iostreams::mapped_file.
@@ -660,7 +638,7 @@ public:
};
private:
- /// Platform specific mapping state.
+ /// Platform-specific mapping state.
mapmode Mode;
uint64_t Size;
void *Mapping;
@@ -670,7 +648,7 @@ private:
void *FileMappingHandle;
#endif
- error_code init(int FD, bool CloseFD, uint64_t Offset);
+ std::error_code init(int FD, bool CloseFD, uint64_t Offset);
public:
typedef char char_type;
@@ -692,21 +670,14 @@ public:
/// mapped_file_region::alignment().
/// \param ec This is set to errc::success if the map was constructed
/// successfully. Otherwise it is set to a platform dependent error.
- mapped_file_region(const Twine &path,
- mapmode mode,
- uint64_t length,
- uint64_t offset,
- error_code &ec);
+ mapped_file_region(const Twine &path, mapmode mode, uint64_t length,
+ uint64_t offset, std::error_code &ec);
/// \param fd An open file descriptor to map. mapped_file_region takes
/// ownership if closefd is true. It must have been opended in the correct
/// mode.
- mapped_file_region(int fd,
- bool closefd,
- mapmode mode,
- uint64_t length,
- uint64_t offset,
- error_code &ec);
+ mapped_file_region(int fd, bool closefd, mapmode mode, uint64_t length,
+ uint64_t offset, std::error_code &ec);
~mapped_file_region();
@@ -722,30 +693,6 @@ public:
static int alignment();
};
-/// @brief Memory maps the contents of a file
-///
-/// @param path Path to file to map.
-/// @param file_offset Byte offset in file where mapping should begin.
-/// @param size Byte length of range of the file to map.
-/// @param map_writable If true, the file will be mapped in r/w such
-/// that changes to the mapped buffer will be flushed back
-/// to the file. If false, the file will be mapped read-only
-/// and the buffer will be read-only.
-/// @param result Set to the start address of the mapped buffer.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,
- bool map_writable, void *&result);
-
-
-/// @brief Memory unmaps the contents of a file
-///
-/// @param base Pointer to the start of the buffer.
-/// @param size Byte length of the range to unmmap.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code unmap_file_pages(void *base, size_t size);
-
/// Return the path to the main executable, given the value of argv[0] from
/// program startup and the address of main itself. In extremis, this function
/// may fail and return an empty path.
@@ -777,7 +724,7 @@ public:
void replace_filename(const Twine &filename, file_status st = file_status());
const std::string &path() const { return Path; }
- error_code status(file_status &result) const;
+ std::error_code status(file_status &result) const;
bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; }
bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); }
@@ -790,9 +737,9 @@ public:
namespace detail {
struct DirIterState;
- error_code directory_iterator_construct(DirIterState&, StringRef);
- error_code directory_iterator_increment(DirIterState&);
- error_code directory_iterator_destruct(DirIterState&);
+ std::error_code directory_iterator_construct(DirIterState &, StringRef);
+ std::error_code directory_iterator_increment(DirIterState &);
+ std::error_code directory_iterator_destruct(DirIterState &);
/// DirIterState - Keeps state for the directory_iterator. It is reference
/// counted in order to preserve InputIterator semantics on copy.
@@ -816,14 +763,14 @@ class directory_iterator {
IntrusiveRefCntPtr<detail::DirIterState> State;
public:
- explicit directory_iterator(const Twine &path, error_code &ec) {
+ explicit directory_iterator(const Twine &path, std::error_code &ec) {
State = new detail::DirIterState;
SmallString<128> path_storage;
ec = detail::directory_iterator_construct(*State,
path.toStringRef(path_storage));
}
- explicit directory_iterator(const directory_entry &de, error_code &ec) {
+ explicit directory_iterator(const directory_entry &de, std::error_code &ec) {
State = new detail::DirIterState;
ec = detail::directory_iterator_construct(*State, de.path());
}
@@ -832,7 +779,7 @@ public:
directory_iterator() : State(nullptr) {}
// No operator++ because we need error_code.
- directory_iterator &increment(error_code &ec) {
+ directory_iterator &increment(std::error_code &ec) {
ec = directory_iterator_increment(*State);
return *this;
}
@@ -878,14 +825,14 @@ class recursive_directory_iterator {
public:
recursive_directory_iterator() {}
- explicit recursive_directory_iterator(const Twine &path, error_code &ec)
- : State(new detail::RecDirIterState) {
+ explicit recursive_directory_iterator(const Twine &path, std::error_code &ec)
+ : State(new detail::RecDirIterState) {
State->Stack.push(directory_iterator(path, ec));
if (State->Stack.top() == directory_iterator())
State.reset();
}
// No operator++ because we need error_code.
- recursive_directory_iterator &increment(error_code &ec) {
+ recursive_directory_iterator &increment(std::error_code &ec) {
const directory_iterator end_itr;
if (State->HasNoPushRequest)
@@ -934,7 +881,7 @@ public:
assert(State->Level > 0 && "Cannot pop an iterator with level < 1");
const directory_iterator end_itr;
- error_code ec;
+ std::error_code ec;
do {
if (ec)
report_fatal_error("Error incrementing directory iterator.");
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
index a62801f..b713cc7 100644
--- a/include/llvm/Support/Format.h
+++ b/include/llvm/Support/Format.h
@@ -36,23 +36,23 @@
namespace llvm {
-/// format_object_base - This is a helper class used for handling formatted
-/// output. It is the abstract base class of a templated derived class.
+/// This is a helper class used for handling formatted output. It is the
+/// abstract base class of a templated derived class.
class format_object_base {
protected:
const char *Fmt;
virtual void home(); // Out of line virtual method.
- /// snprint - Call snprintf() for this object, on the given buffer and size.
+ /// Call snprintf() for this object, on the given buffer and size.
virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
public:
format_object_base(const char *fmt) : Fmt(fmt) {}
virtual ~format_object_base() {}
- /// print - Format the object into the specified buffer. On success, this
- /// returns the length of the formatted string. If the buffer is too small,
- /// this returns a length to retry with, which will be larger than BufferSize.
+ /// Format the object into the specified buffer. On success, this returns
+ /// the length of the formatted string. If the buffer is too small, this
+ /// returns a length to retry with, which will be larger than BufferSize.
unsigned print(char *Buffer, unsigned BufferSize) const {
assert(BufferSize && "Invalid buffer size!");
@@ -61,21 +61,23 @@ public:
// VC++ and old GlibC return negative on overflow, just double the size.
if (N < 0)
- return BufferSize*2;
+ return BufferSize * 2;
- // Other impls yield number of bytes needed, not including the final '\0'.
+ // Other implementations yield number of bytes needed, not including the
+ // final '\0'.
if (unsigned(N) >= BufferSize)
- return N+1;
+ return N + 1;
// Otherwise N is the length of output (not including the final '\0').
return N;
}
};
-/// format_object1 - This is a templated helper class used by the format
-/// function that captures the object to be formated and the format string. When
-/// actually printed, this synthesizes the string into a temporary buffer
-/// provided and returns whether or not it is big enough.
+/// These are templated helper classes used by the format function that
+/// capture the object to be formated and the format string. When actually
+/// printed, this synthesizes the string into a temporary buffer provided and
+/// returns whether or not it is big enough.
+
template <typename T>
class format_object1 : public format_object_base {
T Val;
@@ -89,10 +91,6 @@ public:
}
};
-/// format_object2 - This is a templated helper class used by the format
-/// function that captures the object to be formated and the format string. When
-/// actually printed, this synthesizes the string into a temporary buffer
-/// provided and returns whether or not it is big enough.
template <typename T1, typename T2>
class format_object2 : public format_object_base {
T1 Val1;
@@ -107,10 +105,6 @@ public:
}
};
-/// format_object3 - This is a templated helper class used by the format
-/// function that captures the object to be formated and the format string. When
-/// actually printed, this synthesizes the string into a temporary buffer
-/// provided and returns whether or not it is big enough.
template <typename T1, typename T2, typename T3>
class format_object3 : public format_object_base {
T1 Val1;
@@ -126,10 +120,6 @@ public:
}
};
-/// format_object4 - This is a templated helper class used by the format
-/// function that captures the object to be formated and the format string. When
-/// actually printed, this synthesizes the string into a temporary buffer
-/// provided and returns whether or not it is big enough.
template <typename T1, typename T2, typename T3, typename T4>
class format_object4 : public format_object_base {
T1 Val1;
@@ -147,10 +137,6 @@ public:
}
};
-/// format_object5 - This is a templated helper class used by the format
-/// function that captures the object to be formated and the format string. When
-/// actually printed, this synthesizes the string into a temporary buffer
-/// provided and returns whether or not it is big enough.
template <typename T1, typename T2, typename T3, typename T4, typename T5>
class format_object5 : public format_object_base {
T1 Val1;
@@ -170,47 +156,52 @@ public:
}
};
-/// This is a helper function that is used to produce formatted output.
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+class format_object6 : public format_object_base {
+ T1 Val1;
+ T2 Val2;
+ T3 Val3;
+ T4 Val4;
+ T5 Val5;
+ T6 Val6;
+public:
+ format_object6(const char *Fmt, const T1 &Val1, const T2 &Val2,
+ const T3 &Val3, const T4 &Val4, const T5 &Val5, const T6 &Val6)
+ : format_object_base(Fmt), Val1(Val1), Val2(Val2), Val3(Val3), Val4(Val4),
+ Val5(Val5), Val6(Val6) { }
+
+ int snprint(char *Buffer, unsigned BufferSize) const override {
+ return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5, Val6);
+ }
+};
+
+/// These are helper functions used to produce formatted output. They use
+/// template type deduction to construct the appropriate instance of the
+/// format_object class to simplify their construction.
///
/// This is typically used like:
/// \code
/// OS << format("%0.4f", myfloat) << '\n';
/// \endcode
+
template <typename T>
inline format_object1<T> format(const char *Fmt, const T &Val) {
return format_object1<T>(Fmt, Val);
}
-/// This is a helper function that is used to produce formatted output.
-///
-/// This is typically used like:
-/// \code
-/// OS << format("%0.4f", myfloat) << '\n';
-/// \endcode
template <typename T1, typename T2>
inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1,
const T2 &Val2) {
return format_object2<T1, T2>(Fmt, Val1, Val2);
}
-/// This is a helper function that is used to produce formatted output.
-///
-/// This is typically used like:
-/// \code
-/// OS << format("%0.4f", myfloat) << '\n';
-/// \endcode
template <typename T1, typename T2, typename T3>
inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1,
const T2 &Val2, const T3 &Val3) {
return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3);
}
-/// This is a helper function that is used to produce formatted output.
-///
-/// This is typically used like:
-/// \code
-/// OS << format("%0.4f", myfloat) << '\n';
-/// \endcode
template <typename T1, typename T2, typename T3, typename T4>
inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1,
const T2 &Val2, const T3 &Val3,
@@ -218,12 +209,6 @@ inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1,
return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4);
}
-/// This is a helper function that is used to produce formatted output.
-///
-/// This is typically used like:
-/// \code
-/// OS << format("%0.4f", myfloat) << '\n';
-/// \endcode
template <typename T1, typename T2, typename T3, typename T4, typename T5>
inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1,
const T2 &Val2, const T3 &Val3,
@@ -231,6 +216,15 @@ inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1,
return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5);
}
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+inline format_object6<T1, T2, T3, T4, T5, T6>
+format(const char *Fmt, const T1 &Val1, const T2 &Val2, const T3 &Val3,
+ const T4 &Val4, const T5 &Val5, const T6 &Val6) {
+ return format_object6<T1, T2, T3, T4, T5, T6>(Fmt, Val1, Val2, Val3, Val4,
+ Val5, Val6);
+}
+
} // end namespace llvm
#endif
diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h
index e344220..876ab6e 100644
--- a/include/llvm/Support/GenericDomTree.h
+++ b/include/llvm/Support/GenericDomTree.h
@@ -330,6 +330,10 @@ public:
return DomTreeNodes.lookup(BB);
}
+ inline DomTreeNodeBase<NodeT> *operator[](NodeT *BB) const {
+ return getNode(BB);
+ }
+
/// getRootNode - This returns the entry node for the CFG of the function. If
/// this tree represents the post-dominance relations for a function, however,
/// this root may be a node with the block == NULL. This is the case when
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index 539673a..2f02aa7 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -50,7 +50,7 @@ namespace GraphProgram {
};
}
-void DisplayGraph(StringRef Filename, bool wait = true,
+bool DisplayGraph(StringRef Filename, bool wait = true,
GraphProgram::Name program = GraphProgram::DOT);
template<typename GraphType>
diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h
index 523a781..61c65da 100644
--- a/include/llvm/Support/LockFileManager.h
+++ b/include/llvm/Support/LockFileManager.h
@@ -12,11 +12,10 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
#include <utility> // for std::pair
namespace llvm {
-
/// \brief Class that manages the creation of a lock file to aid
/// implicit coordination between different processes.
///
@@ -56,7 +55,7 @@ private:
SmallString<128> UniqueLockFileName;
Optional<std::pair<std::string, int> > Owner;
- Optional<error_code> Error;
+ Optional<std::error_code> Error;
LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION;
LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION;
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 2a0fc7b..bd4dc2f 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -360,11 +360,28 @@ namespace llvm {
enum {
// Constant masks for the "n_desc" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64
+ // The low 3 bits are the for the REFERENCE_TYPE.
+ REFERENCE_TYPE = 0x7,
+ REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0,
+ REFERENCE_FLAG_UNDEFINED_LAZY = 1,
+ REFERENCE_FLAG_DEFINED = 2,
+ REFERENCE_FLAG_PRIVATE_DEFINED = 3,
+ REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4,
+ REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5,
+ // Flag bits (some overlap with the library ordinal bits).
N_ARM_THUMB_DEF = 0x0008u,
+ REFERENCED_DYNAMICALLY = 0x0010u,
N_NO_DEAD_STRIP = 0x0020u,
N_WEAK_REF = 0x0040u,
N_WEAK_DEF = 0x0080u,
- N_SYMBOL_RESOLVER = 0x0100u
+ N_SYMBOL_RESOLVER = 0x0100u,
+ N_ALT_ENTRY = 0x0200u,
+ // For undefined symbols coming from libraries, see GET_LIBRARY_ORDINAL()
+ // as these are in the top 8 bits.
+ SELF_LIBRARY_ORDINAL = 0x0,
+ MAX_LIBRARY_ORDINAL = 0xfd,
+ DYNAMIC_LOOKUP_ORDINAL = 0xfe,
+ EXECUTABLE_ORDINAL = 0xff
};
enum StabType {
@@ -998,8 +1015,8 @@ namespace llvm {
enum : uint32_t {
// Capability bits used in the definition of cpusubtype.
- CPU_SUB_TYPE_MASK = 0xff000000, // Mask for architecture bits
- CPU_SUB_TYPE_LIB64 = 0x80000000, // 64 bit libraries
+ CPU_SUBTYPE_MASK = 0xff000000, // Mask for architecture bits
+ CPU_SUBTYPE_LIB64 = 0x80000000, // 64 bit libraries
// Special CPU subtype constants.
CPU_SUBTYPE_MULTIPLE = ~0u
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index 1bb8cea..d8fbfeb 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -103,9 +103,6 @@ void llvm_shutdown();
/// llvm_shutdown() when it is destroyed.
struct llvm_shutdown_obj {
llvm_shutdown_obj() { }
- explicit llvm_shutdown_obj(bool multithreaded) {
- if (multithreaded) llvm_start_multithreaded();
- }
~llvm_shutdown_obj() { llvm_shutdown(); }
};
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index f1f7b4f..0abba62 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -230,6 +230,9 @@ static const unsigned char BitReverseTable256[256] = {
#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16)
#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4)
R6(0), R6(2), R6(1), R6(3)
+#undef R2
+#undef R4
+#undef R6
};
/// \brief Reverse the bits in \p Val.
@@ -258,6 +261,12 @@ inline uint32_t Lo_32(uint64_t Value) {
return static_cast<uint32_t>(Value);
}
+/// Make_64 - This functions makes a 64-bit integer from a high / low pair of
+/// 32-bit integers.
+inline uint64_t Make_64(uint32_t High, uint32_t Low) {
+ return ((uint64_t)High << 32) | (uint64_t)Low;
+}
+
/// isInt - Checks if an integer fits into the given bit width.
template<unsigned N>
inline bool isInt(int64_t x) {
diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h
index 0996adb..b4305cb 100644
--- a/include/llvm/Support/Memory.h
+++ b/include/llvm/Support/Memory.h
@@ -15,8 +15,8 @@
#define LLVM_SUPPORT_MEMORY_H
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/system_error.h"
#include <string>
+#include <system_error>
namespace llvm {
namespace sys {
@@ -77,7 +77,7 @@ namespace sys {
static MemoryBlock allocateMappedMemory(size_t NumBytes,
const MemoryBlock *const NearBlock,
unsigned Flags,
- error_code &EC);
+ std::error_code &EC);
/// This method releases a block of memory that was allocated with the
/// allocateMappedMemory method. It should not be used to release any
@@ -88,7 +88,7 @@ namespace sys {
/// describing the failure if an error occurred.
///
/// @brief Release mapped memory.
- static error_code releaseMappedMemory(MemoryBlock &Block);
+ static std::error_code releaseMappedMemory(MemoryBlock &Block);
/// This method sets the protection flags for a block of memory to the
/// state specified by /p Flags. The behavior is not specified if the
@@ -105,8 +105,8 @@ namespace sys {
/// describing the failure if an error occurred.
///
/// @brief Set memory protection state.
- static error_code protectMappedMemory(const MemoryBlock &Block,
- unsigned Flags);
+ static std::error_code protectMappedMemory(const MemoryBlock &Block,
+ unsigned Flags);
/// This method allocates a block of Read/Write/Execute memory that is
/// suitable for executing dynamically generated code (e.g. JIT). An
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index 5810c47..147be47 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -19,12 +19,11 @@
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorOr.h"
#include <memory>
+#include <system_error>
namespace llvm {
-
-class error_code;
-
/// 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
@@ -62,19 +61,17 @@ public:
return "Unknown buffer";
}
- /// getFile - Open the specified file as a MemoryBuffer, returning a new
- /// MemoryBuffer if successful, otherwise returning null. If FileSize is
- /// specified, this means that the client knows that the file exists and that
- /// it has the specified size.
+ /// Open the specified file as a MemoryBuffer, returning a new MemoryBuffer
+ /// if successful, otherwise returning null. If FileSize is specified, this
+ /// means that the client knows that the file exists and that it has the
+ /// specified size.
///
/// \param IsVolatileSize Set to true to indicate that the file size may be
/// changing, e.g. when libclang tries to parse while the user is
/// editing/updating the file.
- static error_code getFile(Twine Filename,
- std::unique_ptr<MemoryBuffer> &Result,
- int64_t FileSize = -1,
- bool RequiresNullTerminator = true,
- bool IsVolatileSize = false);
+ static ErrorOr<std::unique_ptr<MemoryBuffer>>
+ getFile(Twine Filename, int64_t FileSize = -1,
+ bool RequiresNullTerminator = true, bool IsVolatileSize = false);
/// Given an already-open file descriptor, map some slice of it into a
/// MemoryBuffer. The slice is specified by an \p Offset and \p MapSize.
@@ -83,10 +80,9 @@ public:
/// \param IsVolatileSize Set to true to indicate that the file size may be
/// changing, e.g. when libclang tries to parse while the user is
/// editing/updating the file.
- static error_code getOpenFileSlice(int FD, const char *Filename,
- std::unique_ptr<MemoryBuffer> &Result,
- uint64_t MapSize, int64_t Offset,
- bool IsVolatileSize = false);
+ static ErrorOr<std::unique_ptr<MemoryBuffer>>
+ getOpenFileSlice(int FD, const char *Filename, uint64_t MapSize,
+ int64_t Offset, bool IsVolatileSize = false);
/// Given an already-open file descriptor, read the file and return a
/// MemoryBuffer.
@@ -94,11 +90,9 @@ public:
/// \param IsVolatileSize Set to true to indicate that the file size may be
/// changing, e.g. when libclang tries to parse while the user is
/// editing/updating the file.
- static error_code getOpenFile(int FD, const char *Filename,
- std::unique_ptr<MemoryBuffer> &Result,
- uint64_t FileSize,
- bool RequiresNullTerminator = true,
- bool IsVolatileSize = false);
+ static ErrorOr<std::unique_ptr<MemoryBuffer>>
+ getOpenFile(int FD, const char *Filename, uint64_t FileSize,
+ bool RequiresNullTerminator = true, bool IsVolatileSize = false);
/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
/// that InputData must be null terminated if RequiresNullTerminator is true.
@@ -125,17 +119,13 @@ public:
static MemoryBuffer *getNewUninitMemBuffer(size_t Size,
StringRef BufferName = "");
- /// getSTDIN - Read all of stdin into a file buffer, and return it.
- /// If an error occurs, this returns null and sets ec.
- static error_code getSTDIN(std::unique_ptr<MemoryBuffer> &Result);
-
+ /// Read all of stdin into a file buffer, and return it.
+ static ErrorOr<std::unique_ptr<MemoryBuffer>> getSTDIN();
- /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
- /// if the Filename is "-". If an error occurs, this returns null and sets
- /// ec.
- static error_code getFileOrSTDIN(StringRef Filename,
- std::unique_ptr<MemoryBuffer> &Result,
- int64_t FileSize = -1);
+ /// Open the specified file as a MemoryBuffer, or open stdin if the Filename
+ /// is "-".
+ static ErrorOr<std::unique_ptr<MemoryBuffer>>
+ getFileOrSTDIN(StringRef Filename, int64_t FileSize = -1);
//===--------------------------------------------------------------------===//
// Provided for performance analysis.
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 7f6441e..30973de 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -31,7 +31,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TimeValue.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
class StringRef;
@@ -171,10 +171,17 @@ public:
// string. \arg Name is assumed to be in UTF-8 encoding too.
static Optional<std::string> GetEnv(StringRef name);
+ /// This function searches for an existing file in the list of directories
+ /// in a PATH like environment variable, and returns the first file found,
+ /// according to the order of the entries in the PATH like environment
+ /// variable.
+ static Optional<std::string> FindInEnvPath(const std::string& EnvName,
+ const std::string& FileName);
+
/// This function returns a SmallVector containing the arguments passed from
/// the operating system to the program. This function expects to be handed
/// the vector passed in from main.
- static error_code
+ static std::error_code
GetArgumentVector(SmallVectorImpl<const char *> &Args,
ArrayRef<const char *> ArgsFromMain,
SpecificBumpPtrAllocator<char> &ArgAllocator);
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 9160b7d..51279a9 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -16,10 +16,9 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
-class error_code;
namespace sys {
/// This is the OS-specific separator for PATH like environment variables:
@@ -67,8 +66,8 @@ struct ProcessInfo {
// These functions change the specified standard stream (stdin or stdout) to
// binary mode. They return errc::success if the specified stream
// was changed. Otherwise a platform dependent error is returned.
- error_code ChangeStdinToBinary();
- error_code ChangeStdoutToBinary();
+ std::error_code ChangeStdinToBinary();
+ std::error_code ChangeStdoutToBinary();
/// This function executes the program using the arguments provided. The
/// invoked program will inherit the stdin, stdout, and stderr file
diff --git a/include/llvm/Support/RandomNumberGenerator.h b/include/llvm/Support/RandomNumberGenerator.h
new file mode 100644
index 0000000..cadc713
--- /dev/null
+++ b/include/llvm/Support/RandomNumberGenerator.h
@@ -0,0 +1,57 @@
+//==- llvm/Support/RandomNumberGenerator.h - RNG for diversity ---*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an abstraction for random number generation (RNG).
+// Note that the current implementation is not cryptographically secure
+// as it uses the C++11 <random> facilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H_
+#define LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H_
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h" // Needed for uint64_t on Windows.
+#include <random>
+
+namespace llvm {
+
+/// A random number generator.
+/// Instances of this class should not be shared across threads.
+class RandomNumberGenerator {
+public:
+ /// Seeds and salts the underlying RNG engine. The salt of type StringRef
+ /// is passed into the constructor. The seed can be set on the command
+ /// line via -rng-seed=<uint64>.
+ /// The reason for the salt is to ensure different random streams even if
+ /// the same seed is used for multiple invocations of the compiler.
+ /// A good salt value should add additional entropy and be constant across
+ /// different machines (i.e., no paths) to allow for reproducible builds.
+ /// An instance of this class can be retrieved from the current Module.
+ /// \see Module::getRNG
+ RandomNumberGenerator(StringRef Salt);
+
+ /// Returns a random number in the range [0, Max).
+ uint64_t next(uint64_t Max);
+
+private:
+ // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000
+ // http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
+ std::mt19937_64 Generator;
+
+ // Noncopyable.
+ RandomNumberGenerator(const RandomNumberGenerator &other)
+ LLVM_DELETED_FUNCTION;
+ RandomNumberGenerator &
+ operator=(const RandomNumberGenerator &other) LLVM_DELETED_FUNCTION;
+};
+}
+
+#endif
diff --git a/include/llvm/Support/ScaledNumber.h b/include/llvm/Support/ScaledNumber.h
new file mode 100644
index 0000000..2bd7e74
--- /dev/null
+++ b/include/llvm/Support/ScaledNumber.h
@@ -0,0 +1,897 @@
+//===- llvm/Support/ScaledNumber.h - Support for scaled numbers -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions (and a class) useful for working with scaled
+// numbers -- in particular, pairs of integers where one represents digits and
+// another represents a scale. The functions are helpers and live in the
+// namespace ScaledNumbers. The class ScaledNumber is useful for modelling
+// certain cost metrics that need simple, integer-like semantics that are easy
+// to reason about.
+//
+// These might remind you of soft-floats. If you want one of those, you're in
+// the wrong place. Look at include/llvm/ADT/APFloat.h instead.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SCALEDNUMBER_H
+#define LLVM_SUPPORT_SCALEDNUMBER_H
+
+#include "llvm/Support/MathExtras.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <tuple>
+#include <utility>
+
+namespace llvm {
+namespace ScaledNumbers {
+
+/// \brief Maximum scale; same as APFloat for easy debug printing.
+const int32_t MaxScale = 16383;
+
+/// \brief Maximum scale; same as APFloat for easy debug printing.
+const int32_t MinScale = -16382;
+
+/// \brief Get the width of a number.
+template <class DigitsT> inline int getWidth() { return sizeof(DigitsT) * 8; }
+
+/// \brief Conditionally round up a scaled number.
+///
+/// Given \c Digits and \c Scale, round up iff \c ShouldRound is \c true.
+/// Always returns \c Scale unless there's an overflow, in which case it
+/// returns \c 1+Scale.
+///
+/// \pre adding 1 to \c Scale will not overflow INT16_MAX.
+template <class DigitsT>
+inline std::pair<DigitsT, int16_t> getRounded(DigitsT Digits, int16_t Scale,
+ bool ShouldRound) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ if (ShouldRound)
+ if (!++Digits)
+ // Overflow.
+ return std::make_pair(DigitsT(1) << (getWidth<DigitsT>() - 1), Scale + 1);
+ return std::make_pair(Digits, Scale);
+}
+
+/// \brief Convenience helper for 32-bit rounding.
+inline std::pair<uint32_t, int16_t> getRounded32(uint32_t Digits, int16_t Scale,
+ bool ShouldRound) {
+ return getRounded(Digits, Scale, ShouldRound);
+}
+
+/// \brief Convenience helper for 64-bit rounding.
+inline std::pair<uint64_t, int16_t> getRounded64(uint64_t Digits, int16_t Scale,
+ bool ShouldRound) {
+ return getRounded(Digits, Scale, ShouldRound);
+}
+
+/// \brief Adjust a 64-bit scaled number down to the appropriate width.
+///
+/// \pre Adding 64 to \c Scale will not overflow INT16_MAX.
+template <class DigitsT>
+inline std::pair<DigitsT, int16_t> getAdjusted(uint64_t Digits,
+ int16_t Scale = 0) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ const int Width = getWidth<DigitsT>();
+ if (Width == 64 || Digits <= std::numeric_limits<DigitsT>::max())
+ return std::make_pair(Digits, Scale);
+
+ // Shift right and round.
+ int Shift = 64 - Width - countLeadingZeros(Digits);
+ return getRounded<DigitsT>(Digits >> Shift, Scale + Shift,
+ Digits & (UINT64_C(1) << (Shift - 1)));
+}
+
+/// \brief Convenience helper for adjusting to 32 bits.
+inline std::pair<uint32_t, int16_t> getAdjusted32(uint64_t Digits,
+ int16_t Scale = 0) {
+ return getAdjusted<uint32_t>(Digits, Scale);
+}
+
+/// \brief Convenience helper for adjusting to 64 bits.
+inline std::pair<uint64_t, int16_t> getAdjusted64(uint64_t Digits,
+ int16_t Scale = 0) {
+ return getAdjusted<uint64_t>(Digits, Scale);
+}
+
+/// \brief Multiply two 64-bit integers to create a 64-bit scaled number.
+///
+/// Implemented with four 64-bit integer multiplies.
+std::pair<uint64_t, int16_t> multiply64(uint64_t LHS, uint64_t RHS);
+
+/// \brief Multiply two 32-bit integers to create a 32-bit scaled number.
+///
+/// Implemented with one 64-bit integer multiply.
+template <class DigitsT>
+inline std::pair<DigitsT, int16_t> getProduct(DigitsT LHS, DigitsT RHS) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ if (getWidth<DigitsT>() <= 32 || (LHS <= UINT32_MAX && RHS <= UINT32_MAX))
+ return getAdjusted<DigitsT>(uint64_t(LHS) * RHS);
+
+ return multiply64(LHS, RHS);
+}
+
+/// \brief Convenience helper for 32-bit product.
+inline std::pair<uint32_t, int16_t> getProduct32(uint32_t LHS, uint32_t RHS) {
+ return getProduct(LHS, RHS);
+}
+
+/// \brief Convenience helper for 64-bit product.
+inline std::pair<uint64_t, int16_t> getProduct64(uint64_t LHS, uint64_t RHS) {
+ return getProduct(LHS, RHS);
+}
+
+/// \brief Divide two 64-bit integers to create a 64-bit scaled number.
+///
+/// Implemented with long division.
+///
+/// \pre \c Dividend and \c Divisor are non-zero.
+std::pair<uint64_t, int16_t> divide64(uint64_t Dividend, uint64_t Divisor);
+
+/// \brief Divide two 32-bit integers to create a 32-bit scaled number.
+///
+/// Implemented with one 64-bit integer divide/remainder pair.
+///
+/// \pre \c Dividend and \c Divisor are non-zero.
+std::pair<uint32_t, int16_t> divide32(uint32_t Dividend, uint32_t Divisor);
+
+/// \brief Divide two 32-bit numbers to create a 32-bit scaled number.
+///
+/// Implemented with one 64-bit integer divide/remainder pair.
+///
+/// Returns \c (DigitsT_MAX, MaxScale) for divide-by-zero (0 for 0/0).
+template <class DigitsT>
+std::pair<DigitsT, int16_t> getQuotient(DigitsT Dividend, DigitsT Divisor) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+ static_assert(sizeof(DigitsT) == 4 || sizeof(DigitsT) == 8,
+ "expected 32-bit or 64-bit digits");
+
+ // Check for zero.
+ if (!Dividend)
+ return std::make_pair(0, 0);
+ if (!Divisor)
+ return std::make_pair(std::numeric_limits<DigitsT>::max(), MaxScale);
+
+ if (getWidth<DigitsT>() == 64)
+ return divide64(Dividend, Divisor);
+ return divide32(Dividend, Divisor);
+}
+
+/// \brief Convenience helper for 32-bit quotient.
+inline std::pair<uint32_t, int16_t> getQuotient32(uint32_t Dividend,
+ uint32_t Divisor) {
+ return getQuotient(Dividend, Divisor);
+}
+
+/// \brief Convenience helper for 64-bit quotient.
+inline std::pair<uint64_t, int16_t> getQuotient64(uint64_t Dividend,
+ uint64_t Divisor) {
+ return getQuotient(Dividend, Divisor);
+}
+
+/// \brief Implementation of getLg() and friends.
+///
+/// Returns the rounded lg of \c Digits*2^Scale and an int specifying whether
+/// this was rounded up (1), down (-1), or exact (0).
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT>
+inline std::pair<int32_t, int> getLgImpl(DigitsT Digits, int16_t Scale) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ if (!Digits)
+ return std::make_pair(INT32_MIN, 0);
+
+ // Get the floor of the lg of Digits.
+ int32_t LocalFloor = sizeof(Digits) * 8 - countLeadingZeros(Digits) - 1;
+
+ // Get the actual floor.
+ int32_t Floor = Scale + LocalFloor;
+ if (Digits == UINT64_C(1) << LocalFloor)
+ return std::make_pair(Floor, 0);
+
+ // Round based on the next digit.
+ assert(LocalFloor >= 1);
+ bool Round = Digits & UINT64_C(1) << (LocalFloor - 1);
+ return std::make_pair(Floor + Round, Round ? 1 : -1);
+}
+
+/// \brief Get the lg (rounded) of a scaled number.
+///
+/// Get the lg of \c Digits*2^Scale.
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT> int32_t getLg(DigitsT Digits, int16_t Scale) {
+ return getLgImpl(Digits, Scale).first;
+}
+
+/// \brief Get the lg floor of a scaled number.
+///
+/// Get the floor of the lg of \c Digits*2^Scale.
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT> int32_t getLgFloor(DigitsT Digits, int16_t Scale) {
+ auto Lg = getLgImpl(Digits, Scale);
+ return Lg.first - (Lg.second > 0);
+}
+
+/// \brief Get the lg ceiling of a scaled number.
+///
+/// Get the ceiling of the lg of \c Digits*2^Scale.
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT> int32_t getLgCeiling(DigitsT Digits, int16_t Scale) {
+ auto Lg = getLgImpl(Digits, Scale);
+ return Lg.first + (Lg.second < 0);
+}
+
+/// \brief Implementation for comparing scaled numbers.
+///
+/// Compare two 64-bit numbers with different scales. Given that the scale of
+/// \c L is higher than that of \c R by \c ScaleDiff, compare them. Return -1,
+/// 1, and 0 for less than, greater than, and equal, respectively.
+///
+/// \pre 0 <= ScaleDiff < 64.
+int compareImpl(uint64_t L, uint64_t R, int ScaleDiff);
+
+/// \brief Compare two scaled numbers.
+///
+/// Compare two scaled numbers. Returns 0 for equal, -1 for less than, and 1
+/// for greater than.
+template <class DigitsT>
+int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ // Check for zero.
+ if (!LDigits)
+ return RDigits ? -1 : 0;
+ if (!RDigits)
+ return 1;
+
+ // Check for the scale. Use getLgFloor to be sure that the scale difference
+ // is always lower than 64.
+ int32_t lgL = getLgFloor(LDigits, LScale), lgR = getLgFloor(RDigits, RScale);
+ if (lgL != lgR)
+ return lgL < lgR ? -1 : 1;
+
+ // Compare digits.
+ if (LScale < RScale)
+ return compareImpl(LDigits, RDigits, RScale - LScale);
+
+ return -compareImpl(RDigits, LDigits, LScale - RScale);
+}
+
+/// \brief Match scales of two numbers.
+///
+/// Given two scaled numbers, match up their scales. Change the digits and
+/// scales in place. Shift the digits as necessary to form equivalent numbers,
+/// losing precision only when necessary.
+///
+/// If the output value of \c LDigits (\c RDigits) is \c 0, the output value of
+/// \c LScale (\c RScale) is unspecified.
+///
+/// As a convenience, returns the matching scale. If the output value of one
+/// number is zero, returns the scale of the other. If both are zero, which
+/// scale is returned is unspecifed.
+template <class DigitsT>
+int16_t matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits,
+ int16_t &RScale) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ if (LScale < RScale)
+ // Swap arguments.
+ return matchScales(RDigits, RScale, LDigits, LScale);
+ if (!LDigits)
+ return RScale;
+ if (!RDigits || LScale == RScale)
+ return LScale;
+
+ // Now LScale > RScale. Get the difference.
+ int32_t ScaleDiff = int32_t(LScale) - RScale;
+ if (ScaleDiff >= 2 * getWidth<DigitsT>()) {
+ // Don't bother shifting. RDigits will get zero-ed out anyway.
+ RDigits = 0;
+ return LScale;
+ }
+
+ // Shift LDigits left as much as possible, then shift RDigits right.
+ int32_t ShiftL = std::min<int32_t>(countLeadingZeros(LDigits), ScaleDiff);
+ assert(ShiftL < getWidth<DigitsT>() && "can't shift more than width");
+
+ int32_t ShiftR = ScaleDiff - ShiftL;
+ if (ShiftR >= getWidth<DigitsT>()) {
+ // Don't bother shifting. RDigits will get zero-ed out anyway.
+ RDigits = 0;
+ return LScale;
+ }
+
+ LDigits <<= ShiftL;
+ RDigits >>= ShiftR;
+
+ LScale -= ShiftL;
+ RScale += ShiftR;
+ assert(LScale == RScale && "scales should match");
+ return LScale;
+}
+
+/// \brief Get the sum of two scaled numbers.
+///
+/// Get the sum of two scaled numbers with as much precision as possible.
+///
+/// \pre Adding 1 to \c LScale (or \c RScale) will not overflow INT16_MAX.
+template <class DigitsT>
+std::pair<DigitsT, int16_t> getSum(DigitsT LDigits, int16_t LScale,
+ DigitsT RDigits, int16_t RScale) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ // Check inputs up front. This is only relevent if addition overflows, but
+ // testing here should catch more bugs.
+ assert(LScale < INT16_MAX && "scale too large");
+ assert(RScale < INT16_MAX && "scale too large");
+
+ // Normalize digits to match scales.
+ int16_t Scale = matchScales(LDigits, LScale, RDigits, RScale);
+
+ // Compute sum.
+ DigitsT Sum = LDigits + RDigits;
+ if (Sum >= RDigits)
+ return std::make_pair(Sum, Scale);
+
+ // Adjust sum after arithmetic overflow.
+ DigitsT HighBit = DigitsT(1) << (getWidth<DigitsT>() - 1);
+ return std::make_pair(HighBit | Sum >> 1, Scale + 1);
+}
+
+/// \brief Convenience helper for 32-bit sum.
+inline std::pair<uint32_t, int16_t> getSum32(uint32_t LDigits, int16_t LScale,
+ uint32_t RDigits, int16_t RScale) {
+ return getSum(LDigits, LScale, RDigits, RScale);
+}
+
+/// \brief Convenience helper for 64-bit sum.
+inline std::pair<uint64_t, int16_t> getSum64(uint64_t LDigits, int16_t LScale,
+ uint64_t RDigits, int16_t RScale) {
+ return getSum(LDigits, LScale, RDigits, RScale);
+}
+
+/// \brief Get the difference of two scaled numbers.
+///
+/// Get LHS minus RHS with as much precision as possible.
+///
+/// Returns \c (0, 0) if the RHS is larger than the LHS.
+template <class DigitsT>
+std::pair<DigitsT, int16_t> getDifference(DigitsT LDigits, int16_t LScale,
+ DigitsT RDigits, int16_t RScale) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ // Normalize digits to match scales.
+ const DigitsT SavedRDigits = RDigits;
+ const int16_t SavedRScale = RScale;
+ matchScales(LDigits, LScale, RDigits, RScale);
+
+ // Compute difference.
+ if (LDigits <= RDigits)
+ return std::make_pair(0, 0);
+ if (RDigits || !SavedRDigits)
+ return std::make_pair(LDigits - RDigits, LScale);
+
+ // Check if RDigits just barely lost its last bit. E.g., for 32-bit:
+ //
+ // 1*2^32 - 1*2^0 == 0xffffffff != 1*2^32
+ const auto RLgFloor = getLgFloor(SavedRDigits, SavedRScale);
+ if (!compare(LDigits, LScale, DigitsT(1), RLgFloor + getWidth<DigitsT>()))
+ return std::make_pair(std::numeric_limits<DigitsT>::max(), RLgFloor);
+
+ return std::make_pair(LDigits, LScale);
+}
+
+/// \brief Convenience helper for 32-bit difference.
+inline std::pair<uint32_t, int16_t> getDifference32(uint32_t LDigits,
+ int16_t LScale,
+ uint32_t RDigits,
+ int16_t RScale) {
+ return getDifference(LDigits, LScale, RDigits, RScale);
+}
+
+/// \brief Convenience helper for 64-bit difference.
+inline std::pair<uint64_t, int16_t> getDifference64(uint64_t LDigits,
+ int16_t LScale,
+ uint64_t RDigits,
+ int16_t RScale) {
+ return getDifference(LDigits, LScale, RDigits, RScale);
+}
+
+} // end namespace ScaledNumbers
+} // end namespace llvm
+
+namespace llvm {
+
+class raw_ostream;
+class ScaledNumberBase {
+public:
+ static const int DefaultPrecision = 10;
+
+ static void dump(uint64_t D, int16_t E, int Width);
+ static raw_ostream &print(raw_ostream &OS, uint64_t D, int16_t E, int Width,
+ unsigned Precision);
+ static std::string toString(uint64_t D, int16_t E, int Width,
+ unsigned Precision);
+ static int countLeadingZeros32(uint32_t N) { return countLeadingZeros(N); }
+ static int countLeadingZeros64(uint64_t N) { return countLeadingZeros(N); }
+ static uint64_t getHalf(uint64_t N) { return (N >> 1) + (N & 1); }
+
+ static std::pair<uint64_t, bool> splitSigned(int64_t N) {
+ if (N >= 0)
+ return std::make_pair(N, false);
+ uint64_t Unsigned = N == INT64_MIN ? UINT64_C(1) << 63 : uint64_t(-N);
+ return std::make_pair(Unsigned, true);
+ }
+ static int64_t joinSigned(uint64_t U, bool IsNeg) {
+ if (U > uint64_t(INT64_MAX))
+ return IsNeg ? INT64_MIN : INT64_MAX;
+ return IsNeg ? -int64_t(U) : int64_t(U);
+ }
+};
+
+/// \brief Simple representation of a scaled number.
+///
+/// ScaledNumber is a number represented by digits and a scale. It uses simple
+/// saturation arithmetic and every operation is well-defined for every value.
+/// It's somewhat similar in behaviour to a soft-float, but is *not* a
+/// replacement for one. If you're doing numerics, look at \a APFloat instead.
+/// Nevertheless, we've found these semantics useful for modelling certain cost
+/// metrics.
+///
+/// The number is split into a signed scale and unsigned digits. The number
+/// represented is \c getDigits()*2^getScale(). In this way, the digits are
+/// much like the mantissa in the x87 long double, but there is no canonical
+/// form so the same number can be represented by many bit representations.
+///
+/// ScaledNumber is templated on the underlying integer type for digits, which
+/// is expected to be unsigned.
+///
+/// Unlike APFloat, ScaledNumber does not model architecture floating point
+/// behaviour -- while this might make it a little faster and easier to reason
+/// about, it certainly makes it more dangerous for general numerics.
+///
+/// ScaledNumber is totally ordered. However, there is no canonical form, so
+/// there are multiple representations of most scalars. E.g.:
+///
+/// ScaledNumber(8u, 0) == ScaledNumber(4u, 1)
+/// ScaledNumber(4u, 1) == ScaledNumber(2u, 2)
+/// ScaledNumber(2u, 2) == ScaledNumber(1u, 3)
+///
+/// ScaledNumber implements most arithmetic operations. Precision is kept
+/// where possible. Uses simple saturation arithmetic, so that operations
+/// saturate to 0.0 or getLargest() rather than under or overflowing. It has
+/// some extra arithmetic for unit inversion. 0.0/0.0 is defined to be 0.0.
+/// Any other division by 0.0 is defined to be getLargest().
+///
+/// As a convenience for modifying the exponent, left and right shifting are
+/// both implemented, and both interpret negative shifts as positive shifts in
+/// the opposite direction.
+///
+/// Scales are limited to the range accepted by x87 long double. This makes
+/// it trivial to add functionality to convert to APFloat (this is already
+/// relied on for the implementation of printing).
+///
+/// Possible (and conflicting) future directions:
+///
+/// 1. Turn this into a wrapper around \a APFloat.
+/// 2. Share the algorithm implementations with \a APFloat.
+/// 3. Allow \a ScaledNumber to represent a signed number.
+template <class DigitsT> class ScaledNumber : ScaledNumberBase {
+public:
+ static_assert(!std::numeric_limits<DigitsT>::is_signed,
+ "only unsigned floats supported");
+
+ typedef DigitsT DigitsType;
+
+private:
+ typedef std::numeric_limits<DigitsType> DigitsLimits;
+
+ static const int Width = sizeof(DigitsType) * 8;
+ static_assert(Width <= 64, "invalid integer width for digits");
+
+private:
+ DigitsType Digits;
+ int16_t Scale;
+
+public:
+ ScaledNumber() : Digits(0), Scale(0) {}
+
+ ScaledNumber(DigitsType Digits, int16_t Scale)
+ : Digits(Digits), Scale(Scale) {}
+
+private:
+ ScaledNumber(const std::pair<uint64_t, int16_t> &X)
+ : Digits(X.first), Scale(X.second) {}
+
+public:
+ static ScaledNumber getZero() { return ScaledNumber(0, 0); }
+ static ScaledNumber getOne() { return ScaledNumber(1, 0); }
+ static ScaledNumber getLargest() {
+ return ScaledNumber(DigitsLimits::max(), ScaledNumbers::MaxScale);
+ }
+ static ScaledNumber get(uint64_t N) { return adjustToWidth(N, 0); }
+ static ScaledNumber getInverse(uint64_t N) {
+ return get(N).invert();
+ }
+ static ScaledNumber getFraction(DigitsType N, DigitsType D) {
+ return getQuotient(N, D);
+ }
+
+ int16_t getScale() const { return Scale; }
+ DigitsType getDigits() const { return Digits; }
+
+ /// \brief Convert to the given integer type.
+ ///
+ /// Convert to \c IntT using simple saturating arithmetic, truncating if
+ /// necessary.
+ template <class IntT> IntT toInt() const;
+
+ bool isZero() const { return !Digits; }
+ bool isLargest() const { return *this == getLargest(); }
+ bool isOne() const {
+ if (Scale > 0 || Scale <= -Width)
+ return false;
+ return Digits == DigitsType(1) << -Scale;
+ }
+
+ /// \brief The log base 2, rounded.
+ ///
+ /// Get the lg of the scalar. lg 0 is defined to be INT32_MIN.
+ int32_t lg() const { return ScaledNumbers::getLg(Digits, Scale); }
+
+ /// \brief The log base 2, rounded towards INT32_MIN.
+ ///
+ /// Get the lg floor. lg 0 is defined to be INT32_MIN.
+ int32_t lgFloor() const { return ScaledNumbers::getLgFloor(Digits, Scale); }
+
+ /// \brief The log base 2, rounded towards INT32_MAX.
+ ///
+ /// Get the lg ceiling. lg 0 is defined to be INT32_MIN.
+ int32_t lgCeiling() const {
+ return ScaledNumbers::getLgCeiling(Digits, Scale);
+ }
+
+ bool operator==(const ScaledNumber &X) const { return compare(X) == 0; }
+ bool operator<(const ScaledNumber &X) const { return compare(X) < 0; }
+ bool operator!=(const ScaledNumber &X) const { return compare(X) != 0; }
+ bool operator>(const ScaledNumber &X) const { return compare(X) > 0; }
+ bool operator<=(const ScaledNumber &X) const { return compare(X) <= 0; }
+ bool operator>=(const ScaledNumber &X) const { return compare(X) >= 0; }
+
+ bool operator!() const { return isZero(); }
+
+ /// \brief Convert to a decimal representation in a string.
+ ///
+ /// Convert to a string. Uses scientific notation for very large/small
+ /// numbers. Scientific notation is used roughly for numbers outside of the
+ /// range 2^-64 through 2^64.
+ ///
+ /// \c Precision indicates the number of decimal digits of precision to use;
+ /// 0 requests the maximum available.
+ ///
+ /// As a special case to make debugging easier, if the number is small enough
+ /// to convert without scientific notation and has more than \c Precision
+ /// digits before the decimal place, it's printed accurately to the first
+ /// digit past zero. E.g., assuming 10 digits of precision:
+ ///
+ /// 98765432198.7654... => 98765432198.8
+ /// 8765432198.7654... => 8765432198.8
+ /// 765432198.7654... => 765432198.8
+ /// 65432198.7654... => 65432198.77
+ /// 5432198.7654... => 5432198.765
+ std::string toString(unsigned Precision = DefaultPrecision) {
+ return ScaledNumberBase::toString(Digits, Scale, Width, Precision);
+ }
+
+ /// \brief Print a decimal representation.
+ ///
+ /// Print a string. See toString for documentation.
+ raw_ostream &print(raw_ostream &OS,
+ unsigned Precision = DefaultPrecision) const {
+ return ScaledNumberBase::print(OS, Digits, Scale, Width, Precision);
+ }
+ void dump() const { return ScaledNumberBase::dump(Digits, Scale, Width); }
+
+ ScaledNumber &operator+=(const ScaledNumber &X) {
+ std::tie(Digits, Scale) =
+ ScaledNumbers::getSum(Digits, Scale, X.Digits, X.Scale);
+ // Check for exponent past MaxScale.
+ if (Scale > ScaledNumbers::MaxScale)
+ *this = getLargest();
+ return *this;
+ }
+ ScaledNumber &operator-=(const ScaledNumber &X) {
+ std::tie(Digits, Scale) =
+ ScaledNumbers::getDifference(Digits, Scale, X.Digits, X.Scale);
+ return *this;
+ }
+ ScaledNumber &operator*=(const ScaledNumber &X);
+ ScaledNumber &operator/=(const ScaledNumber &X);
+ ScaledNumber &operator<<=(int16_t Shift) {
+ shiftLeft(Shift);
+ return *this;
+ }
+ ScaledNumber &operator>>=(int16_t Shift) {
+ shiftRight(Shift);
+ return *this;
+ }
+
+private:
+ void shiftLeft(int32_t Shift);
+ void shiftRight(int32_t Shift);
+
+ /// \brief Adjust two floats to have matching exponents.
+ ///
+ /// Adjust \c this and \c X to have matching exponents. Returns the new \c X
+ /// by value. Does nothing if \a isZero() for either.
+ ///
+ /// The value that compares smaller will lose precision, and possibly become
+ /// \a isZero().
+ ScaledNumber matchScales(ScaledNumber X) {
+ ScaledNumbers::matchScales(Digits, Scale, X.Digits, X.Scale);
+ return X;
+ }
+
+public:
+ /// \brief Scale a large number accurately.
+ ///
+ /// Scale N (multiply it by this). Uses full precision multiplication, even
+ /// if Width is smaller than 64, so information is not lost.
+ uint64_t scale(uint64_t N) const;
+ uint64_t scaleByInverse(uint64_t N) const {
+ // TODO: implement directly, rather than relying on inverse. Inverse is
+ // expensive.
+ return inverse().scale(N);
+ }
+ int64_t scale(int64_t N) const {
+ std::pair<uint64_t, bool> Unsigned = splitSigned(N);
+ return joinSigned(scale(Unsigned.first), Unsigned.second);
+ }
+ int64_t scaleByInverse(int64_t N) const {
+ std::pair<uint64_t, bool> Unsigned = splitSigned(N);
+ return joinSigned(scaleByInverse(Unsigned.first), Unsigned.second);
+ }
+
+ int compare(const ScaledNumber &X) const {
+ return ScaledNumbers::compare(Digits, Scale, X.Digits, X.Scale);
+ }
+ int compareTo(uint64_t N) const {
+ ScaledNumber Scaled = get(N);
+ int Compare = compare(Scaled);
+ if (Width == 64 || Compare != 0)
+ return Compare;
+
+ // Check for precision loss. We know *this == RoundTrip.
+ uint64_t RoundTrip = Scaled.template toInt<uint64_t>();
+ return N == RoundTrip ? 0 : RoundTrip < N ? -1 : 1;
+ }
+ int compareTo(int64_t N) const { return N < 0 ? 1 : compareTo(uint64_t(N)); }
+
+ ScaledNumber &invert() { return *this = ScaledNumber::get(1) / *this; }
+ ScaledNumber inverse() const { return ScaledNumber(*this).invert(); }
+
+private:
+ static ScaledNumber getProduct(DigitsType LHS, DigitsType RHS) {
+ return ScaledNumbers::getProduct(LHS, RHS);
+ }
+ static ScaledNumber getQuotient(DigitsType Dividend, DigitsType Divisor) {
+ return ScaledNumbers::getQuotient(Dividend, Divisor);
+ }
+
+ static int countLeadingZerosWidth(DigitsType Digits) {
+ if (Width == 64)
+ return countLeadingZeros64(Digits);
+ if (Width == 32)
+ return countLeadingZeros32(Digits);
+ return countLeadingZeros32(Digits) + Width - 32;
+ }
+
+ /// \brief Adjust a number to width, rounding up if necessary.
+ ///
+ /// Should only be called for \c Shift close to zero.
+ ///
+ /// \pre Shift >= MinScale && Shift + 64 <= MaxScale.
+ static ScaledNumber adjustToWidth(uint64_t N, int32_t Shift) {
+ assert(Shift >= ScaledNumbers::MinScale && "Shift should be close to 0");
+ assert(Shift <= ScaledNumbers::MaxScale - 64 &&
+ "Shift should be close to 0");
+ auto Adjusted = ScaledNumbers::getAdjusted<DigitsT>(N, Shift);
+ return Adjusted;
+ }
+
+ static ScaledNumber getRounded(ScaledNumber P, bool Round) {
+ // Saturate.
+ if (P.isLargest())
+ return P;
+
+ return ScaledNumbers::getRounded(P.Digits, P.Scale, Round);
+ }
+};
+
+#define SCALED_NUMBER_BOP(op, base) \
+ template <class DigitsT> \
+ ScaledNumber<DigitsT> operator op(const ScaledNumber<DigitsT> &L, \
+ const ScaledNumber<DigitsT> &R) { \
+ return ScaledNumber<DigitsT>(L) base R; \
+ }
+SCALED_NUMBER_BOP(+, += )
+SCALED_NUMBER_BOP(-, -= )
+SCALED_NUMBER_BOP(*, *= )
+SCALED_NUMBER_BOP(/, /= )
+SCALED_NUMBER_BOP(<<, <<= )
+SCALED_NUMBER_BOP(>>, >>= )
+#undef SCALED_NUMBER_BOP
+
+template <class DigitsT>
+raw_ostream &operator<<(raw_ostream &OS, const ScaledNumber<DigitsT> &X) {
+ return X.print(OS, 10);
+}
+
+#define SCALED_NUMBER_COMPARE_TO_TYPE(op, T1, T2) \
+ template <class DigitsT> \
+ bool operator op(const ScaledNumber<DigitsT> &L, T1 R) { \
+ return L.compareTo(T2(R)) op 0; \
+ } \
+ template <class DigitsT> \
+ bool operator op(T1 L, const ScaledNumber<DigitsT> &R) { \
+ return 0 op R.compareTo(T2(L)); \
+ }
+#define SCALED_NUMBER_COMPARE_TO(op) \
+ SCALED_NUMBER_COMPARE_TO_TYPE(op, uint64_t, uint64_t) \
+ SCALED_NUMBER_COMPARE_TO_TYPE(op, uint32_t, uint64_t) \
+ SCALED_NUMBER_COMPARE_TO_TYPE(op, int64_t, int64_t) \
+ SCALED_NUMBER_COMPARE_TO_TYPE(op, int32_t, int64_t)
+SCALED_NUMBER_COMPARE_TO(< )
+SCALED_NUMBER_COMPARE_TO(> )
+SCALED_NUMBER_COMPARE_TO(== )
+SCALED_NUMBER_COMPARE_TO(!= )
+SCALED_NUMBER_COMPARE_TO(<= )
+SCALED_NUMBER_COMPARE_TO(>= )
+#undef SCALED_NUMBER_COMPARE_TO
+#undef SCALED_NUMBER_COMPARE_TO_TYPE
+
+template <class DigitsT>
+uint64_t ScaledNumber<DigitsT>::scale(uint64_t N) const {
+ if (Width == 64 || N <= DigitsLimits::max())
+ return (get(N) * *this).template toInt<uint64_t>();
+
+ // Defer to the 64-bit version.
+ return ScaledNumber<uint64_t>(Digits, Scale).scale(N);
+}
+
+template <class DigitsT>
+template <class IntT>
+IntT ScaledNumber<DigitsT>::toInt() const {
+ typedef std::numeric_limits<IntT> Limits;
+ if (*this < 1)
+ return 0;
+ if (*this >= Limits::max())
+ return Limits::max();
+
+ IntT N = Digits;
+ if (Scale > 0) {
+ assert(size_t(Scale) < sizeof(IntT) * 8);
+ return N << Scale;
+ }
+ if (Scale < 0) {
+ assert(size_t(-Scale) < sizeof(IntT) * 8);
+ return N >> -Scale;
+ }
+ return N;
+}
+
+template <class DigitsT>
+ScaledNumber<DigitsT> &ScaledNumber<DigitsT>::
+operator*=(const ScaledNumber &X) {
+ if (isZero())
+ return *this;
+ if (X.isZero())
+ return *this = X;
+
+ // Save the exponents.
+ int32_t Scales = int32_t(Scale) + int32_t(X.Scale);
+
+ // Get the raw product.
+ *this = getProduct(Digits, X.Digits);
+
+ // Combine with exponents.
+ return *this <<= Scales;
+}
+template <class DigitsT>
+ScaledNumber<DigitsT> &ScaledNumber<DigitsT>::
+operator/=(const ScaledNumber &X) {
+ if (isZero())
+ return *this;
+ if (X.isZero())
+ return *this = getLargest();
+
+ // Save the exponents.
+ int32_t Scales = int32_t(Scale) - int32_t(X.Scale);
+
+ // Get the raw quotient.
+ *this = getQuotient(Digits, X.Digits);
+
+ // Combine with exponents.
+ return *this <<= Scales;
+}
+template <class DigitsT> void ScaledNumber<DigitsT>::shiftLeft(int32_t Shift) {
+ if (!Shift || isZero())
+ return;
+ assert(Shift != INT32_MIN);
+ if (Shift < 0) {
+ shiftRight(-Shift);
+ return;
+ }
+
+ // Shift as much as we can in the exponent.
+ int32_t ScaleShift = std::min(Shift, ScaledNumbers::MaxScale - Scale);
+ Scale += ScaleShift;
+ if (ScaleShift == Shift)
+ return;
+
+ // Check this late, since it's rare.
+ if (isLargest())
+ return;
+
+ // Shift the digits themselves.
+ Shift -= ScaleShift;
+ if (Shift > countLeadingZerosWidth(Digits)) {
+ // Saturate.
+ *this = getLargest();
+ return;
+ }
+
+ Digits <<= Shift;
+ return;
+}
+
+template <class DigitsT> void ScaledNumber<DigitsT>::shiftRight(int32_t Shift) {
+ if (!Shift || isZero())
+ return;
+ assert(Shift != INT32_MIN);
+ if (Shift < 0) {
+ shiftLeft(-Shift);
+ return;
+ }
+
+ // Shift as much as we can in the exponent.
+ int32_t ScaleShift = std::min(Shift, Scale - ScaledNumbers::MinScale);
+ Scale -= ScaleShift;
+ if (ScaleShift == Shift)
+ return;
+
+ // Shift the digits themselves.
+ Shift -= ScaleShift;
+ if (Shift >= Width) {
+ // Saturate.
+ *this = getZero();
+ return;
+ }
+
+ Digits >>= Shift;
+ return;
+}
+
+template <typename T> struct isPodLike;
+template <typename T> struct isPodLike<ScaledNumber<T>> {
+ static const bool value = true;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index 39f896d..4717553 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -30,7 +30,7 @@ namespace llvm {
class Twine;
class raw_ostream;
-/// SourceMgr - This owns the files read by a parser, handles include stacks,
+/// This owns the files read by a parser, handles include stacks,
/// and handles diagnostic wrangling.
class SourceMgr {
public:
@@ -40,34 +40,34 @@ public:
DK_Note
};
- /// DiagHandlerTy - Clients that want to handle their own diagnostics in a
- /// custom way can register a function pointer+context as a diagnostic
- /// handler. It gets called each time PrintMessage is invoked.
+ /// Clients that want to handle their own diagnostics in a custom way can
+ /// register a function pointer+context as a diagnostic handler.
+ /// It gets called each time PrintMessage is invoked.
typedef void (*DiagHandlerTy)(const SMDiagnostic &, void *Context);
private:
struct SrcBuffer {
- /// Buffer - The memory buffer for the file.
+ /// The memory buffer for the file.
MemoryBuffer *Buffer;
- /// IncludeLoc - This is the location of the parent include, or null if at
- /// the top level.
+ /// This is the location of the parent include, or null if at the top level.
SMLoc IncludeLoc;
};
- /// Buffers - This is all of the buffers that we are reading from.
+ /// This is all of the buffers that we are reading from.
std::vector<SrcBuffer> Buffers;
- // IncludeDirectories - This is the list of directories we should search for
- // include files in.
+ // This is the list of directories we should search for include files in.
std::vector<std::string> IncludeDirectories;
- /// LineNoCache - This is a cache for line number queries, its implementation
- /// is really private to SourceMgr.cpp.
+ /// This is a cache for line number queries, its implementation is really
+ /// private to SourceMgr.cpp.
mutable void *LineNoCache;
DiagHandlerTy DiagHandler;
void *DiagContext;
+ bool isValidBufferID(unsigned i) const { return i && i <= Buffers.size(); }
+
SourceMgr(const SourceMgr&) LLVM_DELETED_FUNCTION;
void operator=(const SourceMgr&) LLVM_DELETED_FUNCTION;
public:
@@ -79,8 +79,8 @@ public:
IncludeDirectories = Dirs;
}
- /// setDiagHandler - Specify a diagnostic handler to be invoked every time
- /// PrintMessage is called. Ctx is passed into the handler when it is invoked.
+ /// Specify a diagnostic handler to be invoked every time PrintMessage is
+ /// called. \p Ctx is passed into the handler when it is invoked.
void setDiagHandler(DiagHandlerTy DH, void *Ctx = nullptr) {
DiagHandler = DH;
DiagContext = Ctx;
@@ -90,60 +90,67 @@ public:
void *getDiagContext() const { return DiagContext; }
const SrcBuffer &getBufferInfo(unsigned i) const {
- assert(i < Buffers.size() && "Invalid Buffer ID!");
- return Buffers[i];
+ assert(isValidBufferID(i));
+ return Buffers[i - 1];
}
const MemoryBuffer *getMemoryBuffer(unsigned i) const {
- assert(i < Buffers.size() && "Invalid Buffer ID!");
- return Buffers[i].Buffer;
+ assert(isValidBufferID(i));
+ return Buffers[i - 1].Buffer;
}
- size_t getNumBuffers() const {
+ unsigned getNumBuffers() const {
return Buffers.size();
}
+ unsigned getMainFileID() const {
+ assert(getNumBuffers());
+ return 1;
+ }
+
SMLoc getParentIncludeLoc(unsigned i) const {
- assert(i < Buffers.size() && "Invalid Buffer ID!");
- return Buffers[i].IncludeLoc;
+ assert(isValidBufferID(i));
+ return Buffers[i - 1].IncludeLoc;
}
- /// AddNewSourceBuffer - Add a new source buffer to this source manager. This
- /// takes ownership of the memory buffer.
- size_t AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
+ /// Add a new source buffer to this source manager. This takes ownership of
+ /// the memory buffer.
+ unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
SrcBuffer NB;
NB.Buffer = F;
NB.IncludeLoc = IncludeLoc;
Buffers.push_back(NB);
- return Buffers.size() - 1;
+ return Buffers.size();
}
- /// AddIncludeFile - Search for a file with the specified name in the current
- /// directory or in one of the IncludeDirs. If no file is found, this returns
- /// ~0, otherwise it returns the buffer ID of the stacked file.
- /// The full path to the included file can be found in IncludedFile.
- size_t AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
- std::string &IncludedFile);
+ /// Search for a file with the specified name in the current directory or in
+ /// one of the IncludeDirs.
+ ///
+ /// If no file is found, this returns 0, otherwise it returns the buffer ID
+ /// of the stacked file. The full path to the included file can be found in
+ /// \p IncludedFile.
+ unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
+ std::string &IncludedFile);
- /// FindBufferContainingLoc - Return the ID of the buffer containing the
- /// specified location, returning -1 if not found.
- int FindBufferContainingLoc(SMLoc Loc) const;
+ /// Return the ID of the buffer containing the specified location.
+ ///
+ /// 0 is returned if the buffer is not found.
+ unsigned FindBufferContainingLoc(SMLoc Loc) const;
- /// FindLineNumber - Find the line number for the specified location in the
- /// specified file. This is not a fast method.
- unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const {
+ /// Find the line number for the specified location in the specified file.
+ /// This is not a fast method.
+ unsigned FindLineNumber(SMLoc Loc, unsigned BufferID = 0) const {
return getLineAndColumn(Loc, BufferID).first;
}
- /// getLineAndColumn - Find the line and column number for the specified
- /// location in the specified file. This is not a fast method.
- std::pair<unsigned, unsigned>
- getLineAndColumn(SMLoc Loc, int BufferID = -1) const;
+ /// Find the line and column number for the specified location in the
+ /// specified file. This is not a fast method.
+ std::pair<unsigned, unsigned> getLineAndColumn(SMLoc Loc,
+ unsigned BufferID = 0) const;
- /// PrintMessage - Emit a message about the specified location with the
- /// specified string.
+ /// Emit a message about the specified location with the specified string.
///
- /// @param ShowColors - Display colored messages if output is a terminal and
+ /// \param ShowColors Display colored messages if output is a terminal and
/// the default error handler is used.
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind,
const Twine &Msg,
@@ -157,21 +164,28 @@ public:
ArrayRef<SMFixIt> FixIts = None,
bool ShowColors = true) const;
- /// GetMessage - Return an SMDiagnostic at the specified location with the
- /// specified string.
+ /// Emits a manually-constructed diagnostic to the given output stream.
+ ///
+ /// \param ShowColors Display colored messages if output is a terminal and
+ /// the default error handler is used.
+ void PrintMessage(raw_ostream &OS, const SMDiagnostic &Diagnostic,
+ bool ShowColors = true) const;
+
+ /// Return an SMDiagnostic at the specified location with the specified
+ /// string.
///
- /// @param Msg If non-null, the kind of message (e.g., "error") which is
+ /// \param Msg If non-null, the kind of message (e.g., "error") which is
/// prefixed to the message.
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
ArrayRef<SMRange> Ranges = None,
ArrayRef<SMFixIt> FixIts = None) const;
- /// PrintIncludeStack - Prints the names of included files and the line of the
- /// file they were included from. A diagnostic handler can use this before
- /// printing its custom formatted message.
+ /// Prints the names of included files and the line of the file they were
+ /// included from. A diagnostic handler can use this before printing its
+ /// custom formatted message.
///
- /// @param IncludeLoc - The line of the include.
- /// @param OS the raw_ostream to print on.
+ /// \param IncludeLoc The location of the include.
+ /// \param OS the raw_ostream to print on.
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
};
@@ -208,8 +222,8 @@ public:
};
-/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
-/// allowing printing to a raw_ostream as a caret diagnostic.
+/// Instances of this class encapsulate one diagnostic report, allowing
+/// printing to a raw_ostream as a caret diagnostic.
class SMDiagnostic {
const SourceMgr *SM;
SMLoc Loc;
diff --git a/include/llvm/Support/SpecialCaseList.h b/include/llvm/Support/SpecialCaseList.h
new file mode 100644
index 0000000..098b9c7
--- /dev/null
+++ b/include/llvm/Support/SpecialCaseList.h
@@ -0,0 +1,96 @@
+//===-- SpecialCaseList.h - special case list for sanitizers ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+//
+// This is a utility class used to parse user-provided text files with
+// "special case lists" for code sanitizers. Such files are used to
+// define "ABI list" for DataFlowSanitizer and blacklists for another sanitizers
+// like AddressSanitizer or UndefinedBehaviorSanitizer.
+//
+// Empty lines and lines starting with "#" are ignored. All the rest lines
+// should have the form:
+// section:wildcard_expression[=category]
+// If category is not specified, it is assumed to be empty string.
+// Definitions of "section" and "category" are sanitizer-specific. For example,
+// sanitizer blacklists support sections "src", "fun" and "global".
+// Wildcard expressions define, respectively, source files, functions or
+// globals which shouldn't be instrumented.
+// Examples of categories:
+// "functional": used in DFSan to list functions with pure functional
+// semantics.
+// "init": used in ASan blacklist to disable initialization-order bugs
+// detection for certain globals or source files.
+// Full special case list file example:
+// ---
+// # Blacklisted items:
+// fun:*_ZN4base6subtle*
+// global:*global_with_bad_access_or_initialization*
+// global:*global_with_initialization_issues*=init
+// type:*Namespace::ClassName*=init
+// src:file_with_tricky_code.cc
+// src:ignore-global-initializers-issues.cc=init
+//
+// # Functions with pure functional semantics:
+// fun:cos=functional
+// fun:sin=functional
+// ---
+// Note that the wild card is in fact an llvm::Regex, but * is automatically
+// replaced with .*
+// This is similar to the "ignore" feature of ThreadSanitizer.
+// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SPECIALCASELIST_H
+#define LLVM_SUPPORT_SPECIALCASELIST_H
+
+#include "llvm/ADT/StringMap.h"
+
+namespace llvm {
+class MemoryBuffer;
+class Regex;
+class StringRef;
+
+class SpecialCaseList {
+ public:
+ /// Parses the special case list from a file. If Path is empty, returns
+ /// an empty special case list. On failure, returns 0 and writes an error
+ /// message to string.
+ static SpecialCaseList *create(const StringRef Path, std::string &Error);
+ /// Parses the special case list from a memory buffer. On failure, returns
+ /// 0 and writes an error message to string.
+ static SpecialCaseList *create(const MemoryBuffer *MB, std::string &Error);
+ /// Parses the special case list from a file. On failure, reports a fatal
+ /// error.
+ static SpecialCaseList *createOrDie(const StringRef Path);
+
+ ~SpecialCaseList();
+
+ /// Returns true, if special case list contains a line
+ /// \code
+ /// @Section:<E>=@Category
+ /// \endcode
+ /// and @Query satisfies a wildcard expression <E>.
+ bool inSection(const StringRef Section, const StringRef Query,
+ const StringRef Category = StringRef()) const;
+
+ private:
+ SpecialCaseList(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
+ SpecialCaseList &operator=(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
+
+ struct Entry;
+ StringMap<StringMap<Entry> > Entries;
+
+ SpecialCaseList();
+ /// Parses just-constructed SpecialCaseList entries from a memory buffer.
+ bool parse(const MemoryBuffer *MB, std::string &Error);
+};
+
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_SPECIALCASELIST_H
+
diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
index 9c9e55c..6e71ad4 100644
--- a/include/llvm/Support/StreamableMemoryObject.h
+++ b/include/llvm/Support/StreamableMemoryObject.h
@@ -13,6 +13,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataStream.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryObject.h"
#include <cassert>
#include <memory>
@@ -115,7 +116,7 @@ public:
// requiring that the bitcode size be known, or otherwise ensuring that
// the memory doesn't go away/get reallocated, but it's
// not currently necessary. Users that need the pointer don't stream.
- assert(0 && "getPointer in streaming memory objects not allowed");
+ llvm_unreachable("getPointer in streaming memory objects not allowed");
return nullptr;
}
bool isValidAddress(uint64_t address) const override;
@@ -154,8 +155,8 @@ private:
kChunkSize);
BytesRead += bytes;
if (bytes < kChunkSize) {
- if (ObjectSize && BytesRead < Pos)
- assert(0 && "Unexpected short read fetching bitcode");
+ assert((!ObjectSize || BytesRead >= Pos) &&
+ "Unexpected short read fetching bitcode");
if (BytesRead <= Pos) { // reached EOF/ran out of bytes
ObjectSize = BytesRead;
EOFReached = true;
diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h
index 7e1394c..3e04653 100644
--- a/include/llvm/Support/StringPool.h
+++ b/include/llvm/Support/StringPool.h
@@ -29,6 +29,7 @@
#ifndef LLVM_SUPPORT_STRINGPOOL_H
#define LLVM_SUPPORT_STRINGPOOL_H
+#include "llvm/Support/Compiler.h"
#include "llvm/ADT/StringMap.h"
#include <cassert>
#include <new>
@@ -128,10 +129,10 @@ namespace llvm {
}
inline const char *operator*() const { return begin(); }
- inline operator bool() const { return S != nullptr; }
+ inline LLVM_EXPLICIT operator bool() const { return S != nullptr; }
- inline bool operator==(const PooledStringPtr &That) { return S == That.S; }
- inline bool operator!=(const PooledStringPtr &That) { return S != That.S; }
+ inline bool operator==(const PooledStringPtr &That) const { return S == That.S; }
+ inline bool operator!=(const PooledStringPtr &That) const { return S != That.S; }
};
} // End llvm namespace
diff --git a/include/llvm/Support/SwapByteOrder.h b/include/llvm/Support/SwapByteOrder.h
index e65f9cc..340954f 100644
--- a/include/llvm/Support/SwapByteOrder.h
+++ b/include/llvm/Support/SwapByteOrder.h
@@ -68,33 +68,38 @@ inline uint64_t SwapByteOrder_64(uint64_t value) {
#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 char getSwappedBytes(unsigned char C) { return C; }
+inline signed char getSwappedBytes(signed char C) { return C; }
+inline char getSwappedBytes(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 short getSwappedBytes(unsigned short C) { return SwapByteOrder_16(C); }
+inline signed short getSwappedBytes( 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); }
+inline unsigned int getSwappedBytes(unsigned int C) { return SwapByteOrder_32(C); }
+inline signed int getSwappedBytes( 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); }
+inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_32(C); }
+inline signed long getSwappedBytes( 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); }
+inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_64(C); }
+inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_64(C); }
#else
#error "Unknown long size!"
#endif
-inline unsigned long long SwapByteOrder(unsigned long long C) {
+inline unsigned long long getSwappedBytes(unsigned long long C) {
return SwapByteOrder_64(C);
}
-inline signed long long SwapByteOrder(signed long long C) {
+inline signed long long getSwappedBytes(signed long long C) {
return SwapByteOrder_64(C);
}
+template<typename T>
+inline void swapByteOrder(T &Value) {
+ Value = getSwappedBytes(Value);
+}
+
} // end namespace sys
} // end namespace llvm
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index fcdc604..5d5b86a 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -51,6 +51,7 @@ namespace llvm {
class raw_ostream;
class formatted_raw_ostream;
+ MCStreamer *createNullStreamer(MCContext &Ctx);
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
@@ -139,6 +140,7 @@ namespace llvm {
MCCodeEmitter *CE,
MCAsmBackend *TAB,
bool ShowInst);
+ typedef MCStreamer *(*NullStreamerCtorTy)(MCContext &Ctx);
typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT,
MCContext &Ctx);
typedef MCSymbolizer *(*MCSymbolizerCtorTy)(StringRef TT,
@@ -225,6 +227,10 @@ namespace llvm {
/// AsmStreamer, if registered (default = llvm::createAsmStreamer).
AsmStreamerCtorTy AsmStreamerCtorFn;
+ /// Construction function for this target's NullStreamer, if registered
+ /// (default = llvm::createNullStreamer).
+ NullStreamerCtorTy NullStreamerCtorFn;
+
/// MCRelocationInfoCtorFn - Construction function for this target's
/// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
@@ -235,8 +241,8 @@ namespace llvm {
public:
Target()
- : AsmStreamerCtorFn(nullptr), MCRelocationInfoCtorFn(nullptr),
- MCSymbolizerCtorFn(nullptr) {}
+ : AsmStreamerCtorFn(nullptr), NullStreamerCtorFn(nullptr),
+ MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
/// @name Target Information
/// @{
@@ -447,6 +453,12 @@ namespace llvm {
InstPrint, CE, TAB, ShowInst);
}
+ MCStreamer *createNullStreamer(MCContext &Ctx) const {
+ if (NullStreamerCtorFn)
+ return NullStreamerCtorFn(Ctx);
+ return llvm::createNullStreamer(Ctx);
+ }
+
/// createMCRelocationInfo - Create a target specific MCRelocationInfo.
///
/// \param TT The target triple.
@@ -553,13 +565,6 @@ namespace llvm {
Triple &TheTriple,
std::string &Error);
- /// getClosestTargetForJIT - Pick the best target that is compatible with
- /// the current host. If no close target can be found, this returns null
- /// and sets the Error string to a reason.
- ///
- /// Maintained for compatibility through 2.6.
- static const Target *getClosestTargetForJIT(std::string &Error);
-
/// @}
/// @name Target Registration
/// @{
@@ -780,6 +785,10 @@ namespace llvm {
T.AsmStreamerCtorFn = Fn;
}
+ static void RegisterNullStreamer(Target &T, Target::NullStreamerCtorTy Fn) {
+ T.NullStreamerCtorFn = Fn;
+ }
+
/// RegisterMCRelocationInfo - Register an MCRelocationInfo
/// implementation for the given target.
///
diff --git a/include/llvm/Support/Threading.h b/include/llvm/Support/Threading.h
index a7e8774..7e87584 100644
--- a/include/llvm/Support/Threading.h
+++ b/include/llvm/Support/Threading.h
@@ -7,7 +7,8 @@
//
//===----------------------------------------------------------------------===//
//
-// TThis file defines llvm_start_multithreaded() and friends.
+// This file declares helper functions for running LLVM in a multi-threaded
+// environment.
//
//===----------------------------------------------------------------------===//
@@ -15,32 +16,10 @@
#define LLVM_SUPPORT_THREADING_H
namespace llvm {
- /// llvm_start_multithreaded - Allocate and initialize structures needed to
- /// make LLVM safe for multithreading. The return value indicates whether
- /// multithreaded initialization succeeded. LLVM will still be operational
- /// on "failed" return, and will still be safe for hosting threading
- /// applications in the JIT, but will not be safe for concurrent calls to the
- /// LLVM APIs.
- /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
- bool llvm_start_multithreaded();
-
- /// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM
- /// safe for multithreading.
- /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
- void llvm_stop_multithreaded();
-
- /// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe
- /// mode or not.
+ /// Returns true if LLVM is compiled with support for multi-threading, and
+ /// false otherwise.
bool llvm_is_multithreaded();
- /// acquire_global_lock - Acquire the global lock. This is a no-op if called
- /// before llvm_start_multithreaded().
- void llvm_acquire_global_lock();
-
- /// release_global_lock - Release the global lock. This is a no-op if called
- /// before llvm_start_multithreaded().
- void llvm_release_global_lock();
-
/// llvm_execute_on_thread - Execute the given \p UserFn on a separate
/// thread, passing it the provided \p UserData.
///
diff --git a/include/llvm/Support/WindowsError.h b/include/llvm/Support/WindowsError.h
new file mode 100644
index 0000000..0e909a0
--- /dev/null
+++ b/include/llvm/Support/WindowsError.h
@@ -0,0 +1,19 @@
+//===-- WindowsError.h - Support for mapping windows errors to posix-------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WINDOWS_ERROR_H
+#define LLVM_SUPPORT_WINDOWS_ERROR_H
+
+#include <system_error>
+
+namespace llvm {
+std::error_code mapWindowsError(unsigned EV);
+}
+
+#endif
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 4ee05ed..a23faf6 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -24,7 +24,7 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
namespace yaml {
@@ -880,7 +880,7 @@ public:
~Input();
// Check if there was an syntax or semantic error during parsing.
- llvm::error_code error();
+ std::error_code error();
private:
bool outputting() override;
@@ -982,13 +982,13 @@ public:
// These are only used by operator>>. They could be private
// if those templated things could be made friends.
bool setCurrentDocument();
- void nextDocument();
+ bool nextDocument();
private:
llvm::SourceMgr SrcMgr; // must be before Strm
std::unique_ptr<llvm::yaml::Stream> Strm;
std::unique_ptr<HNode> TopNode;
- llvm::error_code EC;
+ std::error_code EC;
llvm::BumpPtrAllocator StringAllocator;
llvm::yaml::document_iterator DocIterator;
std::vector<bool> BitValuesUsed;
diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h
deleted file mode 100644
index aa5e9f7..0000000
--- a/include/llvm/Support/system_error.h
+++ /dev/null
@@ -1,901 +0,0 @@
-//===---------------------------- system_error ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This was lifted from libc++ and modified for C++03. This is called
-// system_error even though it does not define that class because that's what
-// it's called in C++0x. We don't define system_error because it is only used
-// for exception handling, which we don't use in LLVM.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_SYSTEM_ERROR_H
-#define LLVM_SUPPORT_SYSTEM_ERROR_H
-
-#include "llvm/Support/Compiler.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 std::false_type {};
-
-template <class T> struct is_error_condition_enum
- : public std::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> : std::true_type { }
-
-error_code make_error_code(errc e);
-error_condition make_error_condition(errc e);
-
-// Comparison operators:
-bool operator==(const error_code& lhs, const error_code& rhs);
-bool operator==(const error_code& lhs, const error_condition& rhs);
-bool operator==(const error_condition& lhs, const error_code& rhs);
-bool operator==(const error_condition& lhs, const error_condition& rhs);
-bool operator!=(const error_code& lhs, const error_code& rhs);
-bool operator!=(const error_code& lhs, const error_condition& rhs);
-bool operator!=(const error_condition& lhs, const error_code& rhs);
-bool operator!=(const error_condition& lhs, const error_condition& rhs);
-
-template <> struct hash<std::error_code>;
-
-} // std
-
-*/
-
-#include "llvm/Config/llvm-config.h"
-#include <cerrno>
-#include <string>
-
-// This must be here instead of a .inc file because it is used in the definition
-// of the enum values below.
-#ifdef LLVM_ON_WIN32
-
- // The following numbers were taken from VS2010.
-# ifndef EAFNOSUPPORT
-# define EAFNOSUPPORT 102
-# endif
-# ifndef EADDRINUSE
-# define EADDRINUSE 100
-# endif
-# ifndef EADDRNOTAVAIL
-# define EADDRNOTAVAIL 101
-# endif
-# ifndef EISCONN
-# define EISCONN 113
-# endif
-# ifndef E2BIG
-# define E2BIG 7
-# endif
-# ifndef EDOM
-# define EDOM 33
-# endif
-# ifndef EFAULT
-# define EFAULT 14
-# endif
-# ifndef EBADF
-# define EBADF 9
-# endif
-# ifndef EBADMSG
-# define EBADMSG 104
-# endif
-# ifndef EPIPE
-# define EPIPE 32
-# endif
-# ifndef ECONNABORTED
-# define ECONNABORTED 106
-# endif
-# ifndef EALREADY
-# define EALREADY 103
-# endif
-# ifndef ECONNREFUSED
-# define ECONNREFUSED 107
-# endif
-# ifndef ECONNRESET
-# define ECONNRESET 108
-# endif
-# ifndef EXDEV
-# define EXDEV 18
-# endif
-# ifndef EDESTADDRREQ
-# define EDESTADDRREQ 109
-# endif
-# ifndef EBUSY
-# define EBUSY 16
-# endif
-# ifndef ENOTEMPTY
-# define ENOTEMPTY 41
-# endif
-# ifndef ENOEXEC
-# define ENOEXEC 8
-# endif
-# ifndef EEXIST
-# define EEXIST 17
-# endif
-# ifndef EFBIG
-# define EFBIG 27
-# endif
-# ifndef ENAMETOOLONG
-# define ENAMETOOLONG 38
-# endif
-# ifndef ENOSYS
-# define ENOSYS 40
-# endif
-# ifndef EHOSTUNREACH
-# define EHOSTUNREACH 110
-# endif
-# ifndef EIDRM
-# define EIDRM 111
-# endif
-# ifndef EILSEQ
-# define EILSEQ 42
-# endif
-# ifndef ENOTTY
-# define ENOTTY 25
-# endif
-# ifndef EINTR
-# define EINTR 4
-# endif
-# ifndef EINVAL
-# define EINVAL 22
-# endif
-# ifndef ESPIPE
-# define ESPIPE 29
-# endif
-# ifndef EIO
-# define EIO 5
-# endif
-# ifndef EISDIR
-# define EISDIR 21
-# endif
-# ifndef EMSGSIZE
-# define EMSGSIZE 115
-# endif
-# ifndef ENETDOWN
-# define ENETDOWN 116
-# endif
-# ifndef ENETRESET
-# define ENETRESET 117
-# endif
-# ifndef ENETUNREACH
-# define ENETUNREACH 118
-# endif
-# ifndef ENOBUFS
-# define ENOBUFS 119
-# endif
-# ifndef ECHILD
-# define ECHILD 10
-# endif
-# ifndef ENOLINK
-# define ENOLINK 121
-# endif
-# ifndef ENOLCK
-# define ENOLCK 39
-# endif
-# ifndef ENODATA
-# define ENODATA 120
-# endif
-# ifndef ENOMSG
-# define ENOMSG 122
-# endif
-# ifndef ENOPROTOOPT
-# define ENOPROTOOPT 123
-# endif
-# ifndef ENOSPC
-# define ENOSPC 28
-# endif
-# ifndef ENOSR
-# define ENOSR 124
-# endif
-# ifndef ENXIO
-# define ENXIO 6
-# endif
-# ifndef ENODEV
-# define ENODEV 19
-# endif
-# ifndef ENOENT
-# define ENOENT 2
-# endif
-# ifndef ESRCH
-# define ESRCH 3
-# endif
-# ifndef ENOTDIR
-# define ENOTDIR 20
-# endif
-# ifndef ENOTSOCK
-# define ENOTSOCK 128
-# endif
-# ifndef ENOSTR
-# define ENOSTR 125
-# endif
-# ifndef ENOTCONN
-# define ENOTCONN 126
-# endif
-# ifndef ENOMEM
-# define ENOMEM 12
-# endif
-# ifndef ENOTSUP
-# define ENOTSUP 129
-# endif
-# ifndef ECANCELED
-# define ECANCELED 105
-# endif
-# ifndef EINPROGRESS
-# define EINPROGRESS 112
-# endif
-# ifndef EPERM
-# define EPERM 1
-# endif
-# ifndef EOPNOTSUPP
-# define EOPNOTSUPP 130
-# endif
-# ifndef EWOULDBLOCK
-# define EWOULDBLOCK 140
-# endif
-# ifndef EOWNERDEAD
-# define EOWNERDEAD 133
-# endif
-# ifndef EACCES
-# define EACCES 13
-# endif
-# ifndef EPROTO
-# define EPROTO 134
-# endif
-# ifndef EPROTONOSUPPORT
-# define EPROTONOSUPPORT 135
-# endif
-# ifndef EROFS
-# define EROFS 30
-# endif
-# ifndef EDEADLK
-# define EDEADLK 36
-# endif
-# ifndef EAGAIN
-# define EAGAIN 11
-# endif
-# ifndef ERANGE
-# define ERANGE 34
-# endif
-# ifndef ENOTRECOVERABLE
-# define ENOTRECOVERABLE 127
-# endif
-# ifndef ETIME
-# define ETIME 137
-# endif
-# ifndef ETXTBSY
-# define ETXTBSY 139
-# endif
-# ifndef ETIMEDOUT
-# define ETIMEDOUT 138
-# endif
-# ifndef ENFILE
-# define ENFILE 23
-# endif
-# ifndef EMFILE
-# define EMFILE 24
-# endif
-# ifndef EMLINK
-# define EMLINK 31
-# endif
-# ifndef ELOOP
-# define ELOOP 114
-# endif
-# ifndef EOVERFLOW
-# define EOVERFLOW 132
-# endif
-# ifndef EPROTOTYPE
-# define EPROTOTYPE 136
-# endif
-#endif
-
-namespace llvm {
-
-// is_error_code_enum
-
-template <class Tp> struct is_error_code_enum : public std::false_type {};
-
-// is_error_condition_enum
-
-template <class Tp> struct is_error_condition_enum : public std::false_type {};
-
-// Some error codes are not present on all platforms, so we provide equivalents
-// for them:
-
-//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> : std::true_type { };
-
-template <> struct is_error_condition_enum<errc::_> : std::true_type { };
-
-class error_condition;
-class error_code;
-
-// class error_category
-
-class _do_message;
-
-class error_category
-{
-public:
- virtual ~error_category();
-
- error_category();
-private:
- error_category(const error_category&) LLVM_DELETED_FUNCTION;
- error_category& operator=(const error_category&) LLVM_DELETED_FUNCTION;
-
-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:
- std::string message(int ev) const override;
-};
-
-const error_category& generic_category();
-const error_category& system_category();
-
-/// Get the error_category used for errno values from POSIX functions. This is
-/// the same as the system_category on POSIX systems, but is the same as the
-/// generic_category on Windows.
-const error_category& posix_category();
-
-class error_condition
-{
- int _val_;
- const error_category* _cat_;
-public:
- error_condition() : _val_(0), _cat_(&generic_category()) {}
-
- error_condition(int _val, const error_category& _cat)
- : _val_(_val), _cat_(&_cat) {}
-
- template <class E>
- error_condition(E _e, typename std::enable_if<
- 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 std::enable_if<is_error_condition_enum<E>::value,
- error_condition &>::type
- operator=(E _e) {
- *this = make_error_condition(_e);
- return *this;
- }
-
- void clear() {
- _val_ = 0;
- _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 ? nullptr : unspecified_bool_true;
- }
-};
-
-inline error_condition make_error_condition(errc _e) {
- return error_condition(static_cast<int>(_e), generic_category());
-}
-
-inline bool operator<(const error_condition& _x, const error_condition& _y) {
- return _x.category() < _y.category()
- || (_x.category() == _y.category() && _x.value() < _y.value());
-}
-
-// error_code
-
-class error_code {
- int _val_;
- const error_category* _cat_;
-public:
- error_code() : _val_(0), _cat_(&system_category()) {}
-
- static error_code success() {
- return error_code();
- }
-
- error_code(int _val, const error_category& _cat)
- : _val_(_val), _cat_(&_cat) {}
-
- template <class E>
- error_code(E _e, typename std::enable_if<
- 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 std::enable_if<is_error_code_enum<E>::value, error_code &>::type
- operator=(E _e) {
- *this = make_error_code(_e);
- return *this;
- }
-
- void clear() {
- _val_ = 0;
- _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 ? nullptr : 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> : std::true_type { };
-
-template <> struct is_error_code_enum<windows_error::_> : std::true_type { };
-
-inline error_code make_error_code(windows_error e) {
- return error_code(static_cast<int>(e), system_category());
-}
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/TableGen/SetTheory.h b/include/llvm/TableGen/SetTheory.h
new file mode 100644
index 0000000..5baed79
--- /dev/null
+++ b/include/llvm/TableGen/SetTheory.h
@@ -0,0 +1,142 @@
+//===- SetTheory.h - Generate ordered sets from DAG expressions -*- 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 SetTheory class that computes ordered sets of
+// Records from DAG expressions. Operators for standard set operations are
+// predefined, and it is possible to add special purpose set operators as well.
+//
+// The user may define named sets as Records of predefined classes. Set
+// expanders can be added to a SetTheory instance to teach it how to find the
+// elements of such a named set.
+//
+// These are the predefined operators. The argument lists can be individual
+// elements (defs), other sets (defs of expandable classes), lists, or DAG
+// expressions that are evaluated recursively.
+//
+// - (add S1, S2 ...) Union sets. This is also how sets are created from element
+// lists.
+//
+// - (sub S1, S2, ...) Set difference. Every element in S1 except for the
+// elements in S2, ...
+//
+// - (and S1, S2) Set intersection. Every element in S1 that is also in S2.
+//
+// - (shl S, N) Shift left. Remove the first N elements from S.
+//
+// - (trunc S, N) Truncate. The first N elements of S.
+//
+// - (rotl S, N) Rotate left. Same as (add (shl S, N), (trunc S, N)).
+//
+// - (rotr S, N) Rotate right.
+//
+// - (decimate S, N) Decimate S by picking every N'th element, starting with
+// the first one. For instance, (decimate S, 2) returns the even elements of
+// S.
+//
+// - (sequence "Format", From, To) Generate a sequence of defs with printf.
+// For instance, (sequence "R%u", 0, 3) -> [ R0, R1, R2, R3 ]
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SETTHEORY_H
+#define SETTHEORY_H
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/SourceMgr.h"
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+class DagInit;
+class Init;
+class Record;
+class RecordKeeper;
+
+class SetTheory {
+public:
+ typedef std::vector<Record*> RecVec;
+ typedef SmallSetVector<Record*, 16> RecSet;
+
+ /// Operator - A callback representing a DAG operator.
+ class Operator {
+ virtual void anchor();
+ public:
+ virtual ~Operator() {}
+
+ /// apply - Apply this operator to Expr's arguments and insert the result
+ /// in Elts.
+ virtual void apply(SetTheory&, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) =0;
+ };
+
+ /// Expander - A callback function that can transform a Record representing a
+ /// set into a fully expanded list of elements. Expanders provide a way for
+ /// users to define named sets that can be used in DAG expressions.
+ class Expander {
+ virtual void anchor();
+ public:
+ virtual ~Expander() {}
+
+ virtual void expand(SetTheory&, Record*, RecSet &Elts) =0;
+ };
+
+private:
+ // Map set defs to their fully expanded contents. This serves as a memoization
+ // cache and it makes it possible to return const references on queries.
+ typedef std::map<Record*, RecVec> ExpandMap;
+ ExpandMap Expansions;
+
+ // Known DAG operators by name.
+ StringMap<Operator*> Operators;
+
+ // Typed expanders by class name.
+ StringMap<Expander*> Expanders;
+
+public:
+ /// Create a SetTheory instance with only the standard operators.
+ SetTheory();
+
+ /// addExpander - Add an expander for Records with the named super class.
+ void addExpander(StringRef ClassName, Expander*);
+
+ /// addFieldExpander - Add an expander for ClassName that simply evaluates
+ /// FieldName in the Record to get the set elements. That is all that is
+ /// needed for a class like:
+ ///
+ /// class Set<dag d> {
+ /// dag Elts = d;
+ /// }
+ ///
+ void addFieldExpander(StringRef ClassName, StringRef FieldName);
+
+ /// addOperator - Add a DAG operator.
+ void addOperator(StringRef Name, Operator*);
+
+ /// evaluate - Evaluate Expr and append the resulting set to Elts.
+ void evaluate(Init *Expr, RecSet &Elts, ArrayRef<SMLoc> Loc);
+
+ /// evaluate - Evaluate a sequence of Inits and append to Elts.
+ template<typename Iter>
+ void evaluate(Iter begin, Iter end, RecSet &Elts, ArrayRef<SMLoc> Loc) {
+ while (begin != end)
+ evaluate(*begin++, Elts, Loc);
+ }
+
+ /// expand - Expand a record into a set of elements if possible. Return a
+ /// pointer to the expanded elements, or NULL if Set cannot be expanded
+ /// further.
+ const RecVec *expand(Record *Set);
+};
+
+} // end namespace llvm
+
+#endif
+
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 7d1f19c..f77cc7a 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -587,6 +587,11 @@ class Operand<ValueType ty> : DAGOperand {
string OperandType = "OPERAND_UNKNOWN";
dag MIOperandInfo = (ops);
+ // MCOperandPredicate - Optionally, a code fragment operating on
+ // const MCOperand &MCOp, and returning a bool, to indicate if
+ // the value of MCOp is valid for the specific subclass of Operand
+ code MCOperandPredicate;
+
// ParserMatchClass - The "match class" that operands of this type fit
// in. Match classes are used to define the order in which instructions are
// match, to ensure that which instructions gets matched is deterministic.
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
index 7c42e23..bfddd06 100644
--- a/include/llvm/Target/TargetFrameLowering.h
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -93,6 +93,19 @@ public:
/// stack pointer.
virtual bool isFPCloseToIncomingSP() const { return true; }
+ /// assignCalleeSavedSpillSlots - Allows target to override spill slot
+ /// assignment logic. If implemented, assignCalleeSavedSpillSlots() should
+ /// assign frame slots to all CSI entries and return true. If this method
+ /// returns false, spill slots will be assigned using generic implementation.
+ /// assignCalleeSavedSpillSlots() may add, delete or rearrange elements of
+ /// CSI.
+ virtual bool
+ assignCalleeSavedSpillSlots(MachineFunction &MF,
+ const TargetRegisterInfo *TRI,
+ std::vector<CalleeSavedInfo> &CSI) const {
+ return false;
+ }
+
/// 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.
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 165b35f..87e7c14 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -29,6 +29,7 @@ class MachineRegisterInfo;
class MDNode;
class MCInst;
class MCSchedModel;
+class MCSymbolRefExpr;
class SDNode;
class ScheduleHazardRecognizer;
class SelectionDAG;
@@ -36,6 +37,7 @@ class ScheduleDAG;
class TargetRegisterClass;
class TargetRegisterInfo;
class BranchProbability;
+class TargetSubtargetInfo;
template<class T> class SmallVectorImpl;
@@ -321,6 +323,20 @@ public:
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
MachineBasicBlock *NewDest) const;
+ /// getUnconditionalBranch - Get an instruction that performs an unconditional
+ /// branch to the given symbol.
+ virtual void
+ getUnconditionalBranch(MCInst &MI,
+ const MCSymbolRefExpr *BranchTarget) const {
+ llvm_unreachable("Target didn't implement "
+ "TargetInstrInfo::getUnconditionalBranch!");
+ }
+
+ /// getTrap - Get a machine trap instruction
+ virtual void getTrap(MCInst &MI) const {
+ llvm_unreachable("Target didn't implement TargetInstrInfo::getTrap!");
+ }
+
/// isLegalToSplitMBBAt - Return true if it's legal to split the given basic
/// block at the specified instruction (i.e. instruction would be the start
/// of a new basic block).
@@ -728,7 +744,7 @@ public:
/// use for this target when scheduling the machine instructions before
/// register allocation.
virtual ScheduleHazardRecognizer*
- CreateTargetHazardRecognizer(const TargetMachine *TM,
+ CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
const ScheduleDAG *DAG) const;
/// CreateTargetMIHazardRecognizer - Allocate and return a hazard recognizer
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 60a4079..5e9978d 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -185,10 +185,15 @@ public:
/// Return true if the target has BitExtract instructions.
bool hasExtractBitsInsn() const { return HasExtractBitsInsn; }
- /// Return true if a vector of the given type should be split
- /// (TypeSplitVector) instead of promoted (TypePromoteInteger) during type
- /// legalization.
- virtual bool shouldSplitVectorType(EVT /*VT*/) const { return false; }
+ /// Return the preferred vector type legalization action.
+ virtual TargetLoweringBase::LegalizeTypeAction
+ getPreferredVectorAction(EVT VT) const {
+ // The default action for one element vectors is to scalarize
+ if (VT.getVectorNumElements() == 1)
+ return TypeScalarizeVector;
+ // The default action for other vectors is to promote
+ return TypePromoteInteger;
+ }
// There are two general methods for expanding a BUILD_VECTOR node:
// 1. Use SCALAR_TO_VECTOR on the defined scalar values and then shuffle
@@ -279,8 +284,17 @@ public:
/// selects between the two kinds. For example on X86 a scalar boolean should
/// be zero extended from i1, while the elements of a vector of booleans
/// should be sign extended from i1.
- BooleanContent getBooleanContents(bool isVec) const {
- return isVec ? BooleanVectorContents : BooleanContents;
+ ///
+ /// Some cpus also treat floating point types the same way as they treat
+ /// vectors instead of the way they treat scalars.
+ BooleanContent getBooleanContents(bool isVec, bool isFloat) const {
+ if (isVec)
+ return BooleanVectorContents;
+ return isFloat ? BooleanFloatContents : BooleanContents;
+ }
+
+ BooleanContent getBooleanContents(EVT Type) const {
+ return getBooleanContents(Type.isVector(), Type.isFloatingPoint());
}
/// Return target scheduling preference.
@@ -711,6 +725,13 @@ public:
/// reduce runtime.
virtual bool ShouldShrinkFPConstant(EVT) const { return true; }
+ /// When splitting a value of the specified type into parts, does the Lo
+ /// or Hi part come first? This usually follows the endianness, except
+ /// for ppcf128, where the Hi part always comes first.
+ bool hasBigEndianPartOrdering(EVT VT) const {
+ return isBigEndian() || VT == MVT::ppcf128;
+ }
+
/// If true, the target has custom DAG combine transformations that it can
/// perform for the specified node.
bool hasTargetDAGCombine(ISD::NodeType NT) const {
@@ -938,9 +959,19 @@ public:
virtual void resetOperationActions() {}
protected:
- /// 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; }
+ /// Specify how the target extends the result of integer and floating point
+ /// boolean values from i1 to a wider type. See getBooleanContents.
+ void setBooleanContents(BooleanContent Ty) {
+ BooleanContents = Ty;
+ BooleanFloatContents = Ty;
+ }
+
+ /// Specify how the target extends the result of integer and floating point
+ /// boolean values from i1 to a wider type. See getBooleanContents.
+ void setBooleanContents(BooleanContent IntTy, BooleanContent FloatTy) {
+ BooleanContents = IntTy;
+ BooleanFloatContents = FloatTy;
+ }
/// Specify how the target extends the result of a vector boolean value from a
/// vector of i1 to a wider type. See getBooleanContents.
@@ -1484,6 +1515,10 @@ private:
/// a type wider than i1. See getBooleanContents.
BooleanContent BooleanContents;
+ /// Information about the contents of the high-bits in boolean values held in
+ /// a type wider than i1. See getBooleanContents.
+ BooleanContent BooleanFloatContents;
+
/// Information about the contents of the high-bits in boolean vector values
/// when the element type is wider than i1. See getBooleanContents.
BooleanContent BooleanVectorContents;
@@ -2111,7 +2146,7 @@ public:
unsigned NumFixedArgs;
CallingConv::ID CallConv;
SDValue Callee;
- ArgListTy *Args;
+ ArgListTy Args;
SelectionDAG &DAG;
SDLoc DL;
ImmutableCallSite *CS;
@@ -2123,7 +2158,7 @@ public:
: RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false),
IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true),
IsTailCall(false), NumFixedArgs(-1), CallConv(CallingConv::C),
- Args(nullptr), DAG(DAG), CS(nullptr) {}
+ DAG(DAG), CS(nullptr) {}
CallLoweringInfo &setDebugLoc(SDLoc dl) {
DL = dl;
@@ -2136,19 +2171,19 @@ public:
}
CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultType,
- SDValue Target, ArgListTy *ArgsList,
+ SDValue Target, ArgListTy &&ArgsList,
unsigned FixedArgs = -1) {
RetTy = ResultType;
Callee = Target;
CallConv = CC;
NumFixedArgs =
- (FixedArgs == static_cast<unsigned>(-1) ? Args->size() : FixedArgs);
- Args = ArgsList;
+ (FixedArgs == static_cast<unsigned>(-1) ? Args.size() : FixedArgs);
+ Args = std::move(ArgsList);
return *this;
}
CallLoweringInfo &setCallee(Type *ResultType, FunctionType *FTy,
- SDValue Target, ArgListTy *ArgsList,
+ SDValue Target, ArgListTy &&ArgsList,
ImmutableCallSite &Call) {
RetTy = ResultType;
@@ -2163,7 +2198,7 @@ public:
CallConv = Call.getCallingConv();
NumFixedArgs = FTy->getNumParams();
- Args = ArgsList;
+ Args = std::move(ArgsList);
CS = &Call;
@@ -2206,8 +2241,7 @@ public:
}
ArgListTy &getArgs() {
- assert(Args && "Arguments must be set before accessing them");
- return *Args;
+ return Args;
}
};
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 374a163..419eced 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -131,14 +131,12 @@ public:
MCStreamer &Streamer) const;
virtual const MCSection *getStaticCtorSection(unsigned Priority,
- const MCSymbol *KeySym,
- const MCSection *KeySec) const {
+ const MCSymbol *KeySym) const {
return StaticCtorSection;
}
virtual const MCSection *getStaticDtorSection(unsigned Priority,
- const MCSymbol *KeySym,
- const MCSection *KeySec) const {
+ const MCSymbol *KeySym) const {
return StaticDtorSection;
}
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index 636eaf5..922fae5 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -39,6 +39,17 @@ namespace llvm {
};
}
+ namespace JumpTable {
+ enum JumpTableType {
+ Single, // Use a single table for all indirect jumptable calls.
+ Arity, // Use one table per number of function parameters.
+ Simplified, // Use one table per function type, with types projected
+ // into 4 types: pointer to non-function, struct,
+ // primitive, and function pointer.
+ Full // Use one table per unique function type
+ };
+ }
+
class TargetOptions {
public:
TargetOptions()
@@ -54,7 +65,7 @@ namespace llvm {
CompressDebugSections(false), FunctionSections(false),
DataSections(false), TrapUnreachable(false), TrapFuncName(""),
FloatABIType(FloatABI::Default),
- AllowFPOpFusion(FPOpFusion::Standard) {}
+ AllowFPOpFusion(FPOpFusion::Standard), JTType(JumpTable::Single) {}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
/// option is specified on the command line, and should enable debugging
@@ -205,6 +216,10 @@ namespace llvm {
/// the value of this option.
FPOpFusion::FPOpFusionMode AllowFPOpFusion;
+ /// JTType - This flag specifies the type of jump-instruction table to
+ /// create for functions that have the jumptable attribute.
+ JumpTable::JumpTableType JTType;
+
/// Machine level options.
MCTargetOptions MCOptions;
};
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index a162297..c6f3fbf 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -813,12 +813,6 @@ public:
/// getFrameRegister - This method should return the register used as a base
/// for values allocated in the current stack frame.
virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0;
-
- /// getCompactUnwindRegNum - This function maps the register to the number for
- /// compact unwind encoding. Return -1 if the register isn't valid.
- virtual int getCompactUnwindRegNum(unsigned, bool) const {
- return -1;
- }
};
diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h
index 98a5149..78a2db1 100644
--- a/include/llvm/Target/TargetSelectionDAGInfo.h
+++ b/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -37,7 +37,7 @@ protected:
const DataLayout *getDataLayout() const { return DL; }
public:
- explicit TargetSelectionDAGInfo(const TargetMachine &TM);
+ explicit TargetSelectionDAGInfo(const DataLayout *DL);
virtual ~TargetSelectionDAGInfo();
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index c0c342b..bbb83ef 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -66,6 +66,16 @@ public:
/// scheduler. It does not yet disable the postRA scheduler.
virtual bool enableMachineScheduler() const;
+ /// \brief True if the subtarget should run PostMachineScheduler.
+ ///
+ /// This only takes effect if the target has configured the
+ /// PostMachineScheduler pass to run, or if the global cl::opt flag,
+ /// MISchedPostRA, is set.
+ virtual bool enablePostMachineScheduler() const;
+
+ /// \brief True if the subtarget should run the atomic expansion pass.
+ virtual bool enableAtomicExpandLoadLinked() const;
+
/// \brief Override generic scheduling policy within a region.
///
/// This is a convenient way for targets that don't provide any custom
@@ -90,6 +100,12 @@ public:
AntiDepBreakMode& Mode,
RegClassVector& CriticalPathRCs) const;
+ /// \brief True if the subtarget should run the local reassignment
+ /// heuristic of the register allocator.
+ /// This heuristic may be compile time intensive, \p OptLevel provides
+ /// a finer grain to tune the register allocator.
+ virtual bool enableRALocalReassignment(CodeGenOpt::Level OptLevel) const;
+
/// \brief Enable use of alias analysis during code generation (during MI
/// scheduling, DAGCombine, etc.).
virtual bool useAA() const;
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 023de08..50877d0 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -117,6 +117,7 @@ public:
bool SLPVectorize;
bool LoopVectorize;
bool RerollLoops;
+ bool LoadCombine;
private:
/// ExtensionList - This is list of all of the extensions that are registered.
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index 61d5c26..c6a339b 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -64,18 +64,14 @@ ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
GCOVOptions::getDefault());
// Insert AddressSanitizer (address sanity checking) instrumentation
-FunctionPass *createAddressSanitizerFunctionPass(
- bool CheckInitOrder = true, bool CheckUseAfterReturn = false,
- bool CheckLifetime = false, StringRef BlacklistFile = StringRef());
-ModulePass *createAddressSanitizerModulePass(
- bool CheckInitOrder = true, StringRef BlacklistFile = StringRef());
+FunctionPass *createAddressSanitizerFunctionPass();
+ModulePass *createAddressSanitizerModulePass();
// Insert MemorySanitizer instrumentation (detection of uninitialized reads)
-FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0,
- StringRef BlacklistFile = StringRef());
+FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0);
// Insert ThreadSanitizer (race detection) instrumentation
-FunctionPass *createThreadSanitizerPass(StringRef BlacklistFile = StringRef());
+FunctionPass *createThreadSanitizerPass();
// Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation
ModulePass *createDataFlowSanitizerPass(StringRef ABIListFile = StringRef(),
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index cf1d655..8ecfd80 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -19,6 +19,7 @@
namespace llvm {
+class BasicBlockPass;
class FunctionPass;
class Pass;
class GetElementPtrInst;
@@ -381,6 +382,12 @@ FunctionPass *createAddDiscriminatorsPass();
//
FunctionPass *createSeparateConstOffsetFromGEPPass();
+//===----------------------------------------------------------------------===//
+//
+// LoadCombine - Combine loads into bigger loads.
+//
+BasicBlockPass *createLoadCombinePass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 6f64269..c0c6906 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -148,7 +148,7 @@ bool FlattenCFG(BasicBlock *BB, AliasAnalysis *AA = nullptr);
/// and if a predecessor branches to us and one of our successors, fold the
/// setcc into the predecessor and use logical operations to pick the right
/// destination.
-bool FoldBranchToCommonDest(BranchInst *BI);
+bool FoldBranchToCommonDest(BranchInst *BI, const DataLayout *DL = nullptr);
/// DemoteRegToStack - This function takes a virtual register computed by an
/// Instruction and replaces it with a slot in the stack frame, allocated via
diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
index ee26d83..7e3a74a 100644
--- a/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -17,6 +17,7 @@
namespace llvm {
class AliasAnalysis;
class BasicBlock;
+class DataLayout;
class DominatorTree;
class Loop;
class LoopInfo;
@@ -32,7 +33,8 @@ BasicBlock *InsertPreheaderForLoop(Loop *L, Pass *P);
/// will optionally update \c AliasAnalysis and \c ScalarEvolution analyses if
/// passed into it.
bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, Pass *PP,
- AliasAnalysis *AA = nullptr, ScalarEvolution *SE = nullptr);
+ AliasAnalysis *AA = nullptr, ScalarEvolution *SE = nullptr,
+ const DataLayout *DL = nullptr);
/// \brief Put loop into LCSSA form.
///
diff --git a/include/llvm/Transforms/Utils/SpecialCaseList.h b/include/llvm/Transforms/Utils/SpecialCaseList.h
deleted file mode 100644
index 508a6df..0000000
--- a/include/llvm/Transforms/Utils/SpecialCaseList.h
+++ /dev/null
@@ -1,114 +0,0 @@
-//===-- SpecialCaseList.h - special case list for sanitizers ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===//
-//
-// This is a utility class for instrumentation passes (like AddressSanitizer
-// or ThreadSanitizer) to avoid instrumenting some functions or global
-// variables based on a user-supplied list.
-//
-// The list can also specify categories for specific globals, which can be used
-// to instruct an instrumentation pass to treat certain functions or global
-// variables in a specific way, such as by omitting certain aspects of
-// instrumentation while keeping others, or informing the instrumentation pass
-// that a specific uninstrumentable function has certain semantics, thus
-// allowing the pass to instrument callers according to those semantics.
-//
-// For example, AddressSanitizer uses the "init" category for globals whose
-// initializers should not be instrumented, but which in all other respects
-// should be instrumented.
-//
-// Each line contains a prefix, followed by a colon and a wild card expression,
-// followed optionally by an equals sign and an instrumentation-specific
-// category. Empty lines and lines starting with "#" are ignored.
-// ---
-// # Blacklisted items:
-// fun:*_ZN4base6subtle*
-// global:*global_with_bad_access_or_initialization*
-// global:*global_with_initialization_issues*=init
-// type:*Namespace::ClassName*=init
-// src:file_with_tricky_code.cc
-// src:ignore-global-initializers-issues.cc=init
-//
-// # Functions with pure functional semantics:
-// fun:cos=functional
-// fun:sin=functional
-// ---
-// Note that the wild card is in fact an llvm::Regex, but * is automatically
-// replaced with .*
-// This is similar to the "ignore" feature of ThreadSanitizer.
-// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_SPECIALCASELIST_H
-#define LLVM_TRANSFORMS_UTILS_SPECIALCASELIST_H
-
-#include "llvm/ADT/StringMap.h"
-
-namespace llvm {
-class Function;
-class GlobalAlias;
-class GlobalVariable;
-class MemoryBuffer;
-class Module;
-class Regex;
-class StringRef;
-
-class SpecialCaseList {
- public:
- /// Parses the special case list from a file. If Path is empty, returns
- /// an empty special case list. On failure, returns 0 and writes an error
- /// message to string.
- static SpecialCaseList *create(const StringRef Path, std::string &Error);
- /// Parses the special case list from a memory buffer. On failure, returns
- /// 0 and writes an error message to string.
- static SpecialCaseList *create(const MemoryBuffer *MB, std::string &Error);
- /// Parses the special case list from a file. On failure, reports a fatal
- /// error.
- static SpecialCaseList *createOrDie(const StringRef Path);
-
- ~SpecialCaseList();
-
- /// Returns whether either this function or its source file are listed in the
- /// given category, which may be omitted to search the empty category.
- bool isIn(const Function &F, const StringRef Category = StringRef()) const;
-
- /// Returns whether this global, its type or its source file are listed in the
- /// given category, which may be omitted to search the empty category.
- bool isIn(const GlobalVariable &G,
- const StringRef Category = StringRef()) const;
-
- /// Returns whether this global alias is listed in the given category, which
- /// may be omitted to search the empty category.
- ///
- /// If GA aliases a function, the alias's name is matched as a function name
- /// would be. Similarly, aliases of globals are matched like globals.
- bool isIn(const GlobalAlias &GA,
- const StringRef Category = StringRef()) const;
-
- /// Returns whether this module is listed in the given category, which may be
- /// omitted to search the empty category.
- bool isIn(const Module &M, const StringRef Category = StringRef()) const;
-
- private:
- SpecialCaseList(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
- SpecialCaseList &operator=(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
-
- struct Entry;
- StringMap<StringMap<Entry> > Entries;
-
- SpecialCaseList();
- /// Parses just-constructed SpecialCaseList entries from a memory buffer.
- bool parse(const MemoryBuffer *MB, std::string &Error);
-
- bool inSectionCategory(const StringRef Section, const StringRef Query,
- const StringRef Category) const;
-};
-
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_SPECIALCASELIST_H
diff --git a/include/llvm/Transforms/Utils/VectorUtils.h b/include/llvm/Transforms/Utils/VectorUtils.h
index e1d6c56..44a7149 100644
--- a/include/llvm/Transforms/Utils/VectorUtils.h
+++ b/include/llvm/Transforms/Utils/VectorUtils.h
@@ -48,12 +48,27 @@ static inline bool isTriviallyVectorizable(Intrinsic::ID ID) {
case Intrinsic::pow:
case Intrinsic::fma:
case Intrinsic::fmuladd:
+ case Intrinsic::ctlz:
+ case Intrinsic::cttz:
+ case Intrinsic::powi:
return true;
default:
return false;
}
}
+static bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID,
+ unsigned ScalarOpdIdx) {
+ switch (ID) {
+ case Intrinsic::ctlz:
+ case Intrinsic::cttz:
+ case Intrinsic::powi:
+ return (ScalarOpdIdx == 1);
+ default:
+ return false;
+ }
+}
+
static Intrinsic::ID checkUnaryFloatSignature(const CallInst &I,
Intrinsic::ID ValidIntrinsicID) {
if (I.getNumArgOperands() != 1 ||