aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorPirama Arumuga Nainar <pirama@google.com>2015-05-06 11:46:36 -0700
committerPirama Arumuga Nainar <pirama@google.com>2015-05-18 10:52:30 -0700
commit2c3e0051c31c3f5b2328b447eadf1cf9c4427442 (patch)
treec0104029af14e9f47c2ef58ca60e6137691f3c9b /include
parente1bc145815f4334641be19f1c45ecf85d25b6e5a (diff)
downloadexternal_llvm-2c3e0051c31c3f5b2328b447eadf1cf9c4427442.zip
external_llvm-2c3e0051c31c3f5b2328b447eadf1cf9c4427442.tar.gz
external_llvm-2c3e0051c31c3f5b2328b447eadf1cf9c4427442.tar.bz2
Update aosp/master LLVM for rebase to r235153
Change-Id: I9bf53792f9fc30570e81a8d80d296c681d005ea7 (cherry picked from commit 0c7f116bb6950ef819323d855415b2f2b0aad987)
Diffstat (limited to 'include')
-rw-r--r--include/llvm-c/Core.h1
-rw-r--r--include/llvm/ADT/DenseMap.h15
-rw-r--r--include/llvm/ADT/DepthFirstIterator.h10
-rw-r--r--include/llvm/ADT/EpochTracker.h2
-rw-r--r--include/llvm/ADT/Hashing.h2
-rw-r--r--include/llvm/ADT/PostOrderIterator.h33
-rw-r--r--include/llvm/ADT/Twine.h2
-rw-r--r--include/llvm/ADT/iterator.h4
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h35
-rw-r--r--include/llvm/Analysis/AssumptionCache.h2
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfo.h2
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfoImpl.h3
-rw-r--r--include/llvm/Analysis/CallGraph.h2
-rw-r--r--include/llvm/Analysis/DependenceAnalysis.h2
-rw-r--r--include/llvm/Analysis/InlineCost.h2
-rw-r--r--include/llvm/Analysis/JumpInstrTableInfo.h2
-rw-r--r--include/llvm/Analysis/LazyValueInfo.h2
-rw-r--r--include/llvm/Analysis/LibCallAliasAnalysis.h4
-rw-r--r--include/llvm/Analysis/LoopAccessAnalysis.h15
-rw-r--r--include/llvm/Analysis/LoopInfo.h13
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h35
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h2
-rw-r--r--include/llvm/Analysis/Passes.h7
-rw-r--r--include/llvm/Analysis/PostDominators.h2
-rw-r--r--include/llvm/Analysis/RegionInfo.h6
-rw-r--r--include/llvm/Analysis/RegionInfoImpl.h8
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h4
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h119
-rw-r--r--include/llvm/Analysis/TargetFolder.h25
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h18
-rw-r--r--include/llvm/Analysis/TargetTransformInfoImpl.h4
-rw-r--r--include/llvm/Bitcode/BitCodes.h2
-rw-r--r--include/llvm/Bitcode/BitcodeWriterPass.h14
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h3
-rw-r--r--include/llvm/Bitcode/ReaderWriter.h15
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h2
-rw-r--r--include/llvm/CodeGen/BasicTTIImpl.h2
-rw-r--r--include/llvm/CodeGen/GCStrategy.h6
-rw-r--r--include/llvm/CodeGen/LexicalScopes.h52
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h2
-rw-r--r--include/llvm/CodeGen/LiveRangeEdit.h2
-rw-r--r--include/llvm/CodeGen/MachineBlockFrequencyInfo.h2
-rw-r--r--include/llvm/CodeGen/MachineDominators.h2
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h4
-rw-r--r--include/llvm/CodeGen/MachineFunctionAnalysis.h2
-rw-r--r--include/llvm/CodeGen/MachineInstr.h4
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h13
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h49
-rw-r--r--include/llvm/CodeGen/MachineModuleInfoImpls.h16
-rw-r--r--include/llvm/CodeGen/MachinePassRegistry.h2
-rw-r--r--include/llvm/CodeGen/MachinePostDominators.h2
-rw-r--r--include/llvm/CodeGen/MachineRegionInfo.h6
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h17
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h4
-rw-r--r--include/llvm/CodeGen/Passes.h2
-rw-r--r--include/llvm/CodeGen/RegisterPressure.h15
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h2
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h304
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h2
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h34
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h7
-rw-r--r--include/llvm/CodeGen/WinEHFuncInfo.h153
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFUnit.h2
-rw-r--r--include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h2
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h71
-rw-r--r--include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h96
-rw-r--r--include/llvm/ExecutionEngine/Orc/ExecutionUtils.h182
-rw-r--r--include/llvm/ExecutionEngine/Orc/IRCompileLayer.h14
-rw-r--r--include/llvm/ExecutionEngine/Orc/IRTransformLayer.h101
-rw-r--r--include/llvm/ExecutionEngine/Orc/IndirectionUtils.h54
-rw-r--r--include/llvm/ExecutionEngine/Orc/JITSymbol.h2
-rw-r--r--include/llvm/ExecutionEngine/Orc/LambdaResolver.h62
-rw-r--r--include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h45
-rw-r--r--include/llvm/ExecutionEngine/Orc/LookasideRTDyldMM.h92
-rw-r--r--include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h105
-rw-r--r--include/llvm/ExecutionEngine/RTDyldMemoryManager.h138
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h114
-rw-r--r--include/llvm/ExecutionEngine/SectionMemoryManager.h4
-rw-r--r--include/llvm/IR/Attributes.h26
-rw-r--r--include/llvm/IR/BasicBlock.h46
-rw-r--r--include/llvm/IR/CallSite.h31
-rw-r--r--include/llvm/IR/ConstantFolder.h25
-rw-r--r--include/llvm/IR/Constants.h26
-rw-r--r--include/llvm/IR/DIBuilder.h438
-rw-r--r--include/llvm/IR/DebugInfo.h1460
-rw-r--r--include/llvm/IR/DebugInfoMetadata.h884
-rw-r--r--include/llvm/IR/DebugLoc.h116
-rw-r--r--include/llvm/IR/Function.h31
-rw-r--r--include/llvm/IR/GVMaterializer.h1
-rw-r--r--include/llvm/IR/GlobalObject.h2
-rw-r--r--include/llvm/IR/GlobalValue.h16
-rw-r--r--include/llvm/IR/GlobalVariable.h2
-rw-r--r--include/llvm/IR/IRBuilder.h78
-rw-r--r--include/llvm/IR/IRPrintingPasses.h7
-rw-r--r--include/llvm/IR/InlineAsm.h2
-rw-r--r--include/llvm/IR/InstrTypes.h4
-rw-r--r--include/llvm/IR/Instruction.h42
-rw-r--r--include/llvm/IR/Instructions.h50
-rw-r--r--include/llvm/IR/Intrinsics.td5
-rw-r--r--include/llvm/IR/IntrinsicsBPF.td2
-rw-r--r--include/llvm/IR/IntrinsicsPowerPC.td36
-rw-r--r--include/llvm/IR/IntrinsicsSystemZ.td46
-rw-r--r--include/llvm/IR/IntrinsicsX86.td57
-rw-r--r--include/llvm/IR/LegacyPassManager.h4
-rw-r--r--include/llvm/IR/LegacyPassNameParser.h2
-rw-r--r--include/llvm/IR/Metadata.h85
-rw-r--r--include/llvm/IR/Module.h7
-rw-r--r--include/llvm/IR/NoFolder.h25
-rw-r--r--include/llvm/IR/Operator.h14
-rw-r--r--include/llvm/IR/PatternMatch.h49
-rw-r--r--include/llvm/IR/Type.h4
-rw-r--r--include/llvm/IR/UseListOrder.h6
-rw-r--r--include/llvm/IR/User.h4
-rw-r--r--include/llvm/IR/ValueMap.h17
-rw-r--r--include/llvm/InitializePasses.h3
-rw-r--r--include/llvm/LTO/LTOCodeGenerator.h3
-rw-r--r--include/llvm/LineEditor/LineEditor.h2
-rw-r--r--include/llvm/LinkAllPasses.h7
-rw-r--r--include/llvm/MC/ConstantPools.h3
-rw-r--r--include/llvm/MC/MCAsmBackend.h57
-rw-r--r--include/llvm/MC/MCAsmInfoELF.h3
-rw-r--r--include/llvm/MC/MCAsmLayout.h5
-rw-r--r--include/llvm/MC/MCAssembler.h16
-rw-r--r--include/llvm/MC/MCContext.h88
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h18
-rw-r--r--include/llvm/MC/MCELFStreamer.h27
-rw-r--r--include/llvm/MC/MCInstPrinter.h11
-rw-r--r--include/llvm/MC/MCLinkerOptimizationHint.h2
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h8
-rw-r--r--include/llvm/MC/MCObjectStreamer.h17
-rw-r--r--include/llvm/MC/MCObjectWriter.h35
-rw-r--r--include/llvm/MC/MCParser/AsmLexer.h2
-rw-r--r--include/llvm/MC/MCSectionCOFF.h2
-rw-r--r--include/llvm/MC/MCSectionELF.h19
-rw-r--r--include/llvm/MC/MCStreamer.h7
-rw-r--r--include/llvm/MC/MCSymbol.h26
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h4
-rw-r--r--include/llvm/MC/MCWinCOFFObjectWriter.h3
-rw-r--r--include/llvm/MC/MCWinCOFFStreamer.h3
-rw-r--r--include/llvm/MC/SubtargetFeature.h2
-rw-r--r--include/llvm/Object/IRObjectFile.h2
-rw-r--r--include/llvm/Object/SymbolicFile.h2
-rw-r--r--include/llvm/Option/ArgList.h4
-rw-r--r--include/llvm/Pass.h4
-rw-r--r--include/llvm/Support/Allocator.h3
-rw-r--r--include/llvm/Support/Compiler.h53
-rw-r--r--include/llvm/Support/ELFRelocs/Mips.def1
-rw-r--r--include/llvm/Support/FileSystem.h2
-rw-r--r--include/llvm/Support/FormattedStream.h72
-rw-r--r--include/llvm/Support/GenericDomTree.h53
-rw-r--r--include/llvm/Support/MathExtras.h20
-rw-r--r--include/llvm/Support/OnDiskHashTable.h7
-rw-r--r--include/llvm/Support/Options.h2
-rw-r--r--include/llvm/Support/Signals.h2
-rw-r--r--include/llvm/Support/TargetRegistry.h42
-rw-r--r--include/llvm/Support/ToolOutputFile.h21
-rw-r--r--include/llvm/Support/YAMLTraits.h8
-rw-r--r--include/llvm/Support/circular_raw_ostream.h23
-rw-r--r--include/llvm/Support/raw_os_ostream.h2
-rw-r--r--include/llvm/Support/raw_ostream.h231
-rw-r--r--include/llvm/TableGen/Record.h2
-rw-r--r--include/llvm/Target/Target.td11
-rw-r--r--include/llvm/Target/TargetMachine.h112
-rw-r--r--include/llvm/Target/TargetOptions.h6
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h3
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h27
-rw-r--r--include/llvm/Transforms/Scalar.h17
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h4
-rw-r--r--include/llvm/Transforms/Utils/ModuleUtils.h7
-rw-r--r--include/llvm/Transforms/Utils/SymbolRewriter.h3
-rw-r--r--include/llvm/Transforms/Utils/UnrollLoop.h10
171 files changed, 3831 insertions, 3157 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 8873fdb..effbd15 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -169,6 +169,7 @@ typedef enum {
LLVMNonNullAttribute = 1ULL << 37,
LLVMJumpTableAttribute = 1ULL << 38,
LLVMDereferenceableAttribute = 1ULL << 39,
+ LLVMDereferenceableOrNullAttribute = 1ULL << 40,
*/
} LLVMAttribute;
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 8c65f70..9c2365a 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -100,16 +100,18 @@ public:
}
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ unsigned NumEntries = getNumEntries();
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) {
if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) {
P->getSecond().~ValueT();
- decrementNumEntries();
+ --NumEntries;
}
P->getFirst() = EmptyKey;
}
}
- assert(getNumEntries() == 0 && "Node count imbalance!");
+ assert(NumEntries == 0 && "Node count imbalance!");
+ setNumEntries(0);
setNumTombstones(0);
}
@@ -257,7 +259,7 @@ public:
const void *getPointerIntoBucketsArray() const { return getBuckets(); }
protected:
- DenseMapBase() {}
+ DenseMapBase() = default;
void destroyAll() {
if (getNumBuckets() == 0) // Nothing to do.
@@ -341,11 +343,6 @@ protected:
}
}
- void swap(DenseMapBase& RHS) {
- std::swap(getNumEntries(), RHS.getNumEntries());
- std::swap(getNumTombstones(), RHS.getNumTombstones());
- }
-
static unsigned getHashValue(const KeyT &Val) {
return KeyInfoT::getHashValue(Val);
}
@@ -589,6 +586,8 @@ public:
}
void swap(DenseMap& RHS) {
+ this->incrementEpoch();
+ RHS.incrementEpoch();
std::swap(Buckets, RHS.Buckets);
std::swap(NumEntries, RHS.NumEntries);
std::swap(NumTombstones, RHS.NumTombstones);
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
index 5186333..e9668c4 100644
--- a/include/llvm/ADT/DepthFirstIterator.h
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -209,7 +209,7 @@ df_iterator<T> df_end(const T& G) {
// Provide an accessor method to use them in range-based patterns.
template <class T>
iterator_range<df_iterator<T>> depth_first(const T& G) {
- return iterator_range<df_iterator<T>>(df_begin(G), df_end(G));
+ return make_range(df_begin(G), df_end(G));
}
// Provide global definitions of external depth first iterators...
@@ -232,8 +232,7 @@ df_ext_iterator<T, SetTy> df_ext_end(const T& G, SetTy &S) {
template <class T, class SetTy>
iterator_range<df_ext_iterator<T, SetTy>> depth_first_ext(const T& G,
SetTy &S) {
- return iterator_range<df_ext_iterator<T, SetTy>>(df_ext_begin(G, S),
- df_ext_end(G, S));
+ return make_range(df_ext_begin(G, S), df_ext_end(G, S));
}
@@ -259,7 +258,7 @@ idf_iterator<T> idf_end(const T& G){
// Provide an accessor method to use them in range-based patterns.
template <class T>
iterator_range<idf_iterator<T>> inverse_depth_first(const T& G) {
- return iterator_range<idf_iterator<T>>(idf_begin(G), idf_end(G));
+ return make_range(idf_begin(G), idf_end(G));
}
// Provide global definitions of external inverse depth first iterators...
@@ -284,8 +283,7 @@ idf_ext_iterator<T, SetTy> idf_ext_end(const T& G, SetTy &S) {
template <class T, class SetTy>
iterator_range<idf_ext_iterator<T, SetTy>> inverse_depth_first_ext(const T& G,
SetTy &S) {
- return iterator_range<idf_ext_iterator<T, SetTy>>(idf_ext_begin(G, S),
- idf_ext_end(G, S));
+ return make_range(idf_ext_begin(G, S), idf_ext_end(G, S));
}
} // End llvm namespace
diff --git a/include/llvm/ADT/EpochTracker.h b/include/llvm/ADT/EpochTracker.h
index d593073..582d581 100644
--- a/include/llvm/ADT/EpochTracker.h
+++ b/include/llvm/ADT/EpochTracker.h
@@ -30,7 +30,7 @@ public:
class HandleBase {
public:
- HandleBase() {}
+ HandleBase() = default;
explicit HandleBase(const DebugEpochBase *) {}
bool isHandleInSync() const { return true; }
const void *getEpochAddress() const { return nullptr; }
diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h
index a1e7864..77e6d77 100644
--- a/include/llvm/ADT/Hashing.h
+++ b/include/llvm/ADT/Hashing.h
@@ -75,7 +75,7 @@ class hash_code {
public:
/// \brief Default construct a hash_code.
/// Note that this leaves the value uninitialized.
- hash_code() {}
+ hash_code() = default;
/// \brief Form a hash code directly from a numerical value.
hash_code(size_t value) : value(value) {}
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
index fa337e9..759a2db 100644
--- a/include/llvm/ADT/PostOrderIterator.h
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/iterator_range.h"
#include <set>
#include <vector>
@@ -174,9 +175,13 @@ public:
// Provide global constructors that automatically figure out correct types...
//
template <class T>
-po_iterator<T> po_begin(T G) { return po_iterator<T>::begin(G); }
+po_iterator<T> po_begin(const T &G) { return po_iterator<T>::begin(G); }
template <class T>
-po_iterator<T> po_end (T G) { return po_iterator<T>::end(G); }
+po_iterator<T> po_end (const T &G) { return po_iterator<T>::end(G); }
+
+template <class T> iterator_range<po_iterator<T>> post_order(const T &G) {
+ return make_range(po_begin(G), po_end(G));
+}
// Provide global definitions of external postorder iterators...
template<class T, class SetType=std::set<typename GraphTraits<T>::NodeType*> >
@@ -195,6 +200,11 @@ po_ext_iterator<T, SetType> po_ext_end(T G, SetType &S) {
return po_ext_iterator<T, SetType>::end(G, S);
}
+template <class T, class SetType>
+iterator_range<po_ext_iterator<T, SetType>> post_order_ext(const T &G, SetType &S) {
+ return make_range(po_ext_begin(G, S), po_ext_end(G, S));
+}
+
// Provide global definitions of inverse post order iterators...
template <class T,
class SetType = std::set<typename GraphTraits<T>::NodeType*>,
@@ -205,15 +215,20 @@ struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External > {
};
template <class T>
-ipo_iterator<T> ipo_begin(T G, bool Reverse = false) {
+ipo_iterator<T> ipo_begin(const T &G, bool Reverse = false) {
return ipo_iterator<T>::begin(G, Reverse);
}
template <class T>
-ipo_iterator<T> ipo_end(T G){
+ipo_iterator<T> ipo_end(const T &G){
return ipo_iterator<T>::end(G);
}
+template <class T>
+iterator_range<ipo_iterator<T>> inverse_post_order(const T &G, bool Reverse = false) {
+ return make_range(ipo_begin(G, Reverse), ipo_end(G));
+}
+
// Provide global definitions of external inverse postorder iterators...
template <class T,
class SetType = std::set<typename GraphTraits<T>::NodeType*> >
@@ -225,15 +240,21 @@ struct ipo_ext_iterator : public ipo_iterator<T, SetType, true> {
};
template <class T, class SetType>
-ipo_ext_iterator<T, SetType> ipo_ext_begin(T G, SetType &S) {
+ipo_ext_iterator<T, SetType> ipo_ext_begin(const T &G, SetType &S) {
return ipo_ext_iterator<T, SetType>::begin(G, S);
}
template <class T, class SetType>
-ipo_ext_iterator<T, SetType> ipo_ext_end(T G, SetType &S) {
+ipo_ext_iterator<T, SetType> ipo_ext_end(const T &G, SetType &S) {
return ipo_ext_iterator<T, SetType>::end(G, S);
}
+template <class T, class SetType>
+iterator_range<ipo_ext_iterator<T, SetType>>
+inverse_post_order_ext(const T &G, SetType &S) {
+ return make_range(ipo_ext_begin(G, S), ipo_ext_end(G, S));
+}
+
//===--------------------------------------------------------------------===//
// Reverse Post Order CFG iterator code
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h
index 51bb18d..fbe5b65 100644
--- a/include/llvm/ADT/Twine.h
+++ b/include/llvm/ADT/Twine.h
@@ -430,7 +430,7 @@ namespace llvm {
/// Return the twine contents as a std::string.
std::string str() const;
- /// Write the concatenated string into the given SmallString or SmallVector.
+ /// Append the concatenated string into the given SmallString or SmallVector.
void toVector(SmallVectorImpl<char> &Out) const;
/// This returns the twine as a single StringRef. This method is only valid
diff --git a/include/llvm/ADT/iterator.h b/include/llvm/ADT/iterator.h
index e2c9e5e..54a288d 100644
--- a/include/llvm/ADT/iterator.h
+++ b/include/llvm/ADT/iterator.h
@@ -150,7 +150,7 @@ class iterator_adaptor_base
protected:
WrappedIteratorT I;
- iterator_adaptor_base() {}
+ iterator_adaptor_base() = default;
template <typename U>
explicit iterator_adaptor_base(
@@ -231,7 +231,7 @@ struct pointee_iterator
pointee_iterator<WrappedIteratorT>, WrappedIteratorT,
typename std::iterator_traits<WrappedIteratorT>::iterator_category,
T> {
- pointee_iterator() {}
+ pointee_iterator() = default;
template <typename U>
pointee_iterator(U &&u)
: pointee_iterator::iterator_adaptor_base(std::forward<U &&>(u)) {}
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index 43bcc34..6999bd1 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -145,6 +145,19 @@ public:
Location getLocation(const AtomicRMWInst *RMWI);
static Location getLocationForSource(const MemTransferInst *MTI);
static Location getLocationForDest(const MemIntrinsic *MI);
+ Location getLocation(const Instruction *Inst) {
+ if (auto *I = dyn_cast<LoadInst>(Inst))
+ return getLocation(I);
+ else if (auto *I = dyn_cast<StoreInst>(Inst))
+ return getLocation(I);
+ else if (auto *I = dyn_cast<VAArgInst>(Inst))
+ return getLocation(I);
+ else if (auto *I = dyn_cast<AtomicCmpXchgInst>(Inst))
+ return getLocation(I);
+ else if (auto *I = dyn_cast<AtomicRMWInst>(Inst))
+ return getLocation(I);
+ llvm_unreachable("unsupported memory instruction");
+ }
/// Alias analysis result - Either we know for sure that it does not alias, we
/// know for sure it must alias, or we don't know anything: The two pointers
@@ -352,6 +365,24 @@ public:
return (MRB & ModRef) && (MRB & ArgumentPointees);
}
+ /// getModRefInfo - Return information about whether or not an
+ /// instruction may read or write memory (without regard to a
+ /// specific location)
+ ModRefResult getModRefInfo(const Instruction *I) {
+ if (auto CS = ImmutableCallSite(I)) {
+ auto MRB = getModRefBehavior(CS);
+ if (MRB & ModRef)
+ return ModRef;
+ else if (MRB & Ref)
+ return Ref;
+ else if (MRB & Mod)
+ return Mod;
+ return NoModRef;
+ }
+
+ return getModRefInfo(I, Location());
+ }
+
/// getModRefInfo - Return information about whether or not an instruction may
/// read or write the specified memory location. An instruction
/// that doesn't read or write memory may be trivially LICM'd for example.
@@ -472,6 +503,10 @@ public:
ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size){
return getModRefInfo(I, Location(P, Size));
}
+ /// getModRefInfo - Return information about whether a call and an instruction
+ /// may refer to the same memory locations.
+ ModRefResult getModRefInfo(Instruction *I,
+ ImmutableCallSite Call);
/// getModRefInfo - Return information about whether two call sites may refer
/// to the same set of memory locations. See
diff --git a/include/llvm/Analysis/AssumptionCache.h b/include/llvm/Analysis/AssumptionCache.h
index fc1393f..1f00b69 100644
--- a/include/llvm/Analysis/AssumptionCache.h
+++ b/include/llvm/Analysis/AssumptionCache.h
@@ -165,7 +165,7 @@ public:
AssumptionCache &getAssumptionCache(Function &F);
AssumptionCacheTracker();
- ~AssumptionCacheTracker();
+ ~AssumptionCacheTracker() override;
void releaseMemory() override { AssumptionCaches.shrink_and_clear(); }
diff --git a/include/llvm/Analysis/BlockFrequencyInfo.h b/include/llvm/Analysis/BlockFrequencyInfo.h
index 3289a28..f27c32d 100644
--- a/include/llvm/Analysis/BlockFrequencyInfo.h
+++ b/include/llvm/Analysis/BlockFrequencyInfo.h
@@ -34,7 +34,7 @@ public:
BlockFrequencyInfo();
- ~BlockFrequencyInfo();
+ ~BlockFrequencyInfo() override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
index 57b5154..9acc863 100644
--- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -718,9 +718,6 @@ void IrreducibleGraph::addEdges(const BlockNode &Node,
///
/// It has some known flaws.
///
-/// - Loop scale is limited to 4096 per loop (2^12) to avoid exhausting
-/// BlockFrequency's 64-bit integer precision.
-///
/// - The model of irreducible control flow is a rough approximation.
///
/// Modelling irreducible control flow exactly involves setting up and
diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h
index 64d288a..14b8822 100644
--- a/include/llvm/Analysis/CallGraph.h
+++ b/include/llvm/Analysis/CallGraph.h
@@ -318,7 +318,7 @@ public:
static char ID; // Class identification, replacement for typeinfo
CallGraphWrapperPass();
- virtual ~CallGraphWrapperPass();
+ ~CallGraphWrapperPass() override;
/// \brief The internal \c CallGraph around which the rest of this interface
/// is wrapped.
diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h
index ce0b899..0b3b2ea 100644
--- a/include/llvm/Analysis/DependenceAnalysis.h
+++ b/include/llvm/Analysis/DependenceAnalysis.h
@@ -219,7 +219,7 @@ namespace llvm {
public:
FullDependence(Instruction *Src, Instruction *Dst, bool LoopIndependent,
unsigned Levels);
- ~FullDependence() { delete[] DV; }
+ ~FullDependence() override { delete[] DV; }
/// isLoopIndependent - Returns true if this is a loop-independent
/// dependence.
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
index fdee9f8..79ed74d 100644
--- a/include/llvm/Analysis/InlineCost.h
+++ b/include/llvm/Analysis/InlineCost.h
@@ -107,7 +107,7 @@ public:
static char ID;
InlineCostAnalysis();
- ~InlineCostAnalysis();
+ ~InlineCostAnalysis() override;
// Pass interface implementation.
void getAnalysisUsage(AnalysisUsage &AU) const override;
diff --git a/include/llvm/Analysis/JumpInstrTableInfo.h b/include/llvm/Analysis/JumpInstrTableInfo.h
index 591e794..b6dad47 100644
--- a/include/llvm/Analysis/JumpInstrTableInfo.h
+++ b/include/llvm/Analysis/JumpInstrTableInfo.h
@@ -39,7 +39,7 @@ public:
/// The default byte alignment for jump tables is 16, which is large but
/// usually safe.
JumpInstrTableInfo(uint64_t ByteAlign = 16);
- virtual ~JumpInstrTableInfo();
+ ~JumpInstrTableInfo() override;
const char *getPassName() const override {
return "Jump-Instruction Table Info";
}
diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h
index 8e5bbfb..1051cff 100644
--- a/include/llvm/Analysis/LazyValueInfo.h
+++ b/include/llvm/Analysis/LazyValueInfo.h
@@ -39,7 +39,7 @@ public:
LazyValueInfo() : FunctionPass(ID), PImpl(nullptr) {
initializeLazyValueInfoPass(*PassRegistry::getPassRegistry());
}
- ~LazyValueInfo() { assert(!PImpl && "releaseMemory not called"); }
+ ~LazyValueInfo() override { assert(!PImpl && "releaseMemory not called"); }
/// This is used to return true/false/dunno results.
enum Tristate {
diff --git a/include/llvm/Analysis/LibCallAliasAnalysis.h b/include/llvm/Analysis/LibCallAliasAnalysis.h
index 49e0dc8..df95e0e 100644
--- a/include/llvm/Analysis/LibCallAliasAnalysis.h
+++ b/include/llvm/Analysis/LibCallAliasAnalysis.h
@@ -36,8 +36,8 @@ namespace llvm {
: FunctionPass(ID), LCI(LC) {
initializeLibCallAliasAnalysisPass(*PassRegistry::getPassRegistry());
}
- ~LibCallAliasAnalysis();
-
+ ~LibCallAliasAnalysis() override;
+
ModRefResult getModRefInfo(ImmutableCallSite CS,
const Location &Loc) override;
diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h
index 0a9dc07..a4393bb 100644
--- a/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -339,6 +339,10 @@ public:
bool needsChecking(unsigned I, unsigned J,
const SmallVectorImpl<int> *PtrPartition) const;
+ /// \brief Return true if any pointer requires run-time checking according
+ /// to needsChecking.
+ bool needsAnyChecking(const SmallVectorImpl<int> *PtrPartition) const;
+
/// \brief Print the list run-time memory checks necessary.
///
/// If \p PtrPartition is set, it contains the partition number for
@@ -428,6 +432,13 @@ public:
/// Only used in DEBUG build but we don't want NDEBUG-dependent ABI.
unsigned NumSymbolicStrides;
+ /// \brief Checks existence of store to invariant address inside loop.
+ /// If the loop has any store to invariant address, then it returns true,
+ /// else returns false.
+ bool hasStoreToLoopInvariantAddress() const {
+ return StoreToLoopInvariantAddress;
+ }
+
private:
/// \brief Analyze the loop. Substitute symbolic strides using Strides.
void analyzeLoop(const ValueToValueMap &Strides);
@@ -465,6 +476,10 @@ private:
/// \brief Cache the result of analyzeLoop.
bool CanVecMem;
+ /// \brief Indicator for storing to uniform addresses.
+ /// If a loop has write to a loop invariant address then it should be true.
+ bool StoreToLoopInvariantAddress;
+
/// \brief The diagnostics report generated for the analysis. E.g. why we
/// couldn't analyze the loop.
Optional<LoopAccessReport> Report;
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 85c2da7..f3d85e6 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -464,23 +464,20 @@ public:
/// cannot find a terminating instruction with location information,
/// it returns an unknown location.
DebugLoc getStartLoc() const {
- DebugLoc StartLoc;
BasicBlock *HeadBB;
// Try the pre-header first.
- if ((HeadBB = getLoopPreheader()) != nullptr) {
- StartLoc = HeadBB->getTerminator()->getDebugLoc();
- if (!StartLoc.isUnknown())
- return StartLoc;
- }
+ if ((HeadBB = getLoopPreheader()) != nullptr)
+ if (DebugLoc DL = HeadBB->getTerminator()->getDebugLoc())
+ return DL;
// If we have no pre-header or there are no instructions with debug
// info in it, try the header.
HeadBB = getHeader();
if (HeadBB)
- StartLoc = HeadBB->getTerminator()->getDebugLoc();
+ return HeadBB->getTerminator()->getDebugLoc();
- return StartLoc;
+ return DebugLoc();
}
private:
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
index 7cc4a77..0490bb1 100644
--- a/include/llvm/Analysis/LoopInfoImpl.h
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -409,9 +409,6 @@ class PopulateLoopsDFS {
typedef typename BlockTraits::ChildIteratorType SuccIterTy;
LoopInfoBase<BlockT, LoopT> *LI;
- DenseSet<const BlockT *> VisitedBlocks;
- std::vector<std::pair<BlockT*, SuccIterTy> > DFSStack;
-
public:
PopulateLoopsDFS(LoopInfoBase<BlockT, LoopT> *li):
LI(li) {}
@@ -420,36 +417,13 @@ public:
protected:
void insertIntoLoop(BlockT *Block);
-
- BlockT *dfsSource() { return DFSStack.back().first; }
- SuccIterTy &dfsSucc() { return DFSStack.back().second; }
- SuccIterTy dfsSuccEnd() { return BlockTraits::child_end(dfsSource()); }
-
- void pushBlock(BlockT *Block) {
- DFSStack.push_back(std::make_pair(Block, BlockTraits::child_begin(Block)));
- }
};
/// Top-level driver for the forward DFS within the loop.
template<class BlockT, class LoopT>
void PopulateLoopsDFS<BlockT, LoopT>::traverse(BlockT *EntryBlock) {
- pushBlock(EntryBlock);
- VisitedBlocks.insert(EntryBlock);
- while (!DFSStack.empty()) {
- // Traverse the leftmost path as far as possible.
- while (dfsSucc() != dfsSuccEnd()) {
- BlockT *BB = *dfsSucc();
- ++dfsSucc();
- if (!VisitedBlocks.insert(BB).second)
- continue;
-
- // Push the next DFS successor onto the stack.
- pushBlock(BB);
- }
- // Visit the top of the stack in postorder and backtrack.
- insertIntoLoop(dfsSource());
- DFSStack.pop_back();
- }
+ for (BlockT *BB : post_order(EntryBlock))
+ insertIntoLoop(BB);
}
/// Add a single Block to its ancestor loops in PostOrder. If the block is a
@@ -498,10 +472,9 @@ Analyze(DominatorTreeBase<BlockT> &DomTree) {
// Postorder traversal of the dominator tree.
DomTreeNodeBase<BlockT>* DomRoot = DomTree.getRootNode();
- for (po_iterator<DomTreeNodeBase<BlockT>*> DomIter = po_begin(DomRoot),
- DomEnd = po_end(DomRoot); DomIter != DomEnd; ++DomIter) {
+ for (auto DomNode : post_order(DomRoot)) {
- BlockT *Header = DomIter->getBlock();
+ BlockT *Header = DomNode->getBlock();
SmallVector<BlockT *, 4> Backedges;
// Check each predecessor of the potential loop header.
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index abc2b90..c8453e9 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -329,7 +329,7 @@ namespace llvm {
public:
MemoryDependenceAnalysis();
- ~MemoryDependenceAnalysis();
+ ~MemoryDependenceAnalysis() override;
static char ID;
/// Pass Implementation stuff. This doesn't do any analysis eagerly.
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
index 8d11e80..d112ab1 100644
--- a/include/llvm/Analysis/Passes.h
+++ b/include/llvm/Analysis/Passes.h
@@ -138,6 +138,13 @@ namespace llvm {
//===--------------------------------------------------------------------===//
//
+ // createDivergenceAnalysisPass - This pass determines which branches in a GPU
+ // program are divergent.
+ //
+ FunctionPass *createDivergenceAnalysisPass();
+
+ //===--------------------------------------------------------------------===//
+ //
// Minor pass prototypes, allowing us to expose them through bugpoint and
// analyze.
FunctionPass *createInstCountPass();
diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h
index 72cd357..0f7e2b8 100644
--- a/include/llvm/Analysis/PostDominators.h
+++ b/include/llvm/Analysis/PostDominators.h
@@ -30,7 +30,7 @@ struct PostDominatorTree : public FunctionPass {
DT = new DominatorTreeBase<BasicBlock>(true);
}
- ~PostDominatorTree();
+ ~PostDominatorTree() override;
bool runOnFunction(Function &F) override;
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index 1c7f4d3..7ceb086 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -820,8 +820,6 @@ public:
inline RegionNode(Region *Parent, BasicBlock *Entry, bool isSubRegion = false)
: RegionNodeBase<RegionTraits<Function>>(Parent, Entry, isSubRegion) {}
- ~RegionNode() {}
-
bool operator==(const Region &RN) const {
return this == reinterpret_cast<const RegionNode *>(&RN);
}
@@ -842,7 +840,7 @@ class RegionInfo : public RegionInfoBase<RegionTraits<Function>> {
public:
explicit RegionInfo();
- virtual ~RegionInfo();
+ ~RegionInfo() override;
// updateStatistics - Update statistic about created regions.
void updateStatistics(Region *R) final;
@@ -858,7 +856,7 @@ public:
static char ID;
explicit RegionInfoPass();
- ~RegionInfoPass();
+ ~RegionInfoPass() override;
RegionInfo &getRegionInfo() { return RI; }
diff --git a/include/llvm/Analysis/RegionInfoImpl.h b/include/llvm/Analysis/RegionInfoImpl.h
index b0dc263..b31eefc 100644
--- a/include/llvm/Analysis/RegionInfoImpl.h
+++ b/include/llvm/Analysis/RegionInfoImpl.h
@@ -487,7 +487,7 @@ void RegionBase<Tr>::print(raw_ostream &OS, bool print_tree, unsigned level,
OS.indent(level * 2 + 2);
if (Style == PrintBB) {
- for (const auto &BB : blocks())
+ for (const auto *BB : blocks())
OS << BB->getName() << ", "; // TODO: remove the last ","
} else if (Style == PrintRN) {
for (const_element_iterator I = element_begin(), E = element_end();
@@ -714,10 +714,8 @@ void RegionInfoBase<Tr>::scanForRegions(FuncT &F, BBtoBBMap *ShortCut) {
// regions from the bottom of the dominance tree. If the small regions are
// detected first, detection of bigger regions is faster, as we can jump
// over the small regions.
- for (po_iterator<DomTreeNodeT *> FI = po_begin(N), FE = po_end(N); FI != FE;
- ++FI) {
- findRegionsWithEntry(FI->getBlock(), ShortCut);
- }
+ for (auto DomNode : post_order(N))
+ findRegionsWithEntry(DomNode->getBlock(), ShortCut);
}
template <class Tr>
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 4360414..1240b85 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -256,6 +256,10 @@ namespace llvm {
/// Mark predicate values currently being processed by isImpliedCond.
DenseSet<Value*> PendingLoopPredicates;
+ /// Set to true by isLoopBackedgeGuardedByCond when we're walking the set of
+ /// conditions dominating the backedge of a loop.
+ bool WalkingBEDominatingConds;
+
/// ExitLimit - Information about the number of loop iterations for which a
/// loop exit's branch condition evaluates to the not-taken path. This is a
/// temporary pair of exact and max expressions that are eventually
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index b0b0946..8ec2078 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -28,7 +28,7 @@ namespace llvm {
/// all materialized values are safe to speculate.
bool isSafeToExpand(const SCEV *S, ScalarEvolution &SE);
- /// SCEVExpander - This class uses information about analyze scalars to
+ /// This class uses information about analyze scalars to
/// rewrite expressions in canonical form.
///
/// Clients should create an instance of this class when rewriting is needed,
@@ -48,37 +48,36 @@ namespace llvm {
std::set<AssertingVH<Value> > InsertedValues;
std::set<AssertingVH<Value> > InsertedPostIncValues;
- /// RelevantLoops - A memoization of the "relevant" loop for a given SCEV.
+ /// A memoization of the "relevant" loop for a given SCEV.
DenseMap<const SCEV *, const Loop *> RelevantLoops;
- /// PostIncLoops - Addrecs referring to any of the given loops are expanded
+ /// \brief Addrecs referring to any of the given loops are expanded
/// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mode
/// returns the add instruction that adds one to the phi for {0,+,1}<L>,
/// as opposed to a new phi starting at 1. This is only supported in
/// non-canonical mode.
PostIncLoopSet PostIncLoops;
- /// IVIncInsertPos - When this is non-null, addrecs expanded in the
- /// loop it indicates should be inserted with increments at
- /// IVIncInsertPos.
+ /// \brief When this is non-null, addrecs expanded in the loop it indicates
+ /// should be inserted with increments at IVIncInsertPos.
const Loop *IVIncInsertLoop;
- /// IVIncInsertPos - When expanding addrecs in the IVIncInsertLoop loop,
- /// insert the IV increment at this position.
+ /// \brief When expanding addrecs in the IVIncInsertLoop loop, insert the IV
+ /// increment at this position.
Instruction *IVIncInsertPos;
- /// Phis that complete an IV chain. Reuse
+ /// \brief Phis that complete an IV chain. Reuse
std::set<AssertingVH<PHINode> > ChainedPhis;
- /// CanonicalMode - When true, expressions are expanded in "canonical"
- /// form. In particular, addrecs are expanded as arithmetic based on
- /// a canonical induction variable. When false, expression are expanded
- /// in a more literal form.
+ /// \brief When true, expressions are expanded in "canonical" form. In
+ /// particular, addrecs are expanded as arithmetic based on a canonical
+ /// induction variable. When false, expression are expanded in a more
+ /// literal form.
bool CanonicalMode;
- /// When invoked from LSR, the expander is in "strength reduction" mode. The
- /// only difference is that phi's are only reused if they are already in
- /// "expanded" form.
+ /// \brief When invoked from LSR, the expander is in "strength reduction"
+ /// mode. The only difference is that phi's are only reused if they are
+ /// already in "expanded" form.
bool LSRMode;
typedef IRBuilder<true, TargetFolder> BuilderType;
@@ -91,7 +90,7 @@ namespace llvm {
friend struct SCEVVisitor<SCEVExpander, Value*>;
public:
- /// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
+ /// \brief Construct a SCEVExpander in "canonical" mode.
explicit SCEVExpander(ScalarEvolution &se, const DataLayout &DL,
const char *name)
: SE(se), DL(DL), IVName(name), IVIncInsertLoop(nullptr),
@@ -106,7 +105,7 @@ namespace llvm {
void setDebugType(const char* s) { DebugType = s; }
#endif
- /// clear - Erase the contents of the InsertedExpressions map so that users
+ /// \brief Erase the contents of the InsertedExpressions map so that users
/// trying to expand the same expression into multiple BasicBlocks or
/// different places within the same BasicBlock can do so.
void clear() {
@@ -116,31 +115,38 @@ namespace llvm {
ChainedPhis.clear();
}
- /// getOrInsertCanonicalInductionVariable - This method returns the
- /// canonical induction variable of the specified type for the specified
- /// loop (inserting one if there is none). A canonical induction variable
- /// starts at zero and steps by one on each iteration.
+ /// \brief Return true for expressions that may incur non-trivial cost to
+ /// evaluate at runtime.
+ bool isHighCostExpansion(const SCEV *Expr, Loop *L) {
+ SmallPtrSet<const SCEV *, 8> Processed;
+ return isHighCostExpansionHelper(Expr, L, Processed);
+ }
+
+ /// \brief This method returns the canonical induction variable of the
+ /// specified type for the specified loop (inserting one if there is none).
+ /// A canonical induction variable starts at zero and steps by one on each
+ /// iteration.
PHINode *getOrInsertCanonicalInductionVariable(const Loop *L, Type *Ty);
- /// getIVIncOperand - Return the induction variable increment's IV operand.
+ /// \brief Return the induction variable increment's IV operand.
Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos,
bool allowScale);
- /// hoistIVInc - Utility for hoisting an IV increment.
+ /// \brief Utility for hoisting an IV increment.
bool hoistIVInc(Instruction *IncV, Instruction *InsertPos);
- /// replaceCongruentIVs - replace congruent phis with their most canonical
+ /// \brief replace congruent phis with their most canonical
/// representative. Return the number of phis eliminated.
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
SmallVectorImpl<WeakVH> &DeadInsts,
const TargetTransformInfo *TTI = nullptr);
- /// expandCodeFor - Insert code to directly compute the specified SCEV
- /// expression into the program. The inserted code is inserted into the
- /// specified block.
+ /// \brief Insert code to directly compute the specified SCEV expression
+ /// into the program. The inserted code is inserted into the specified
+ /// block.
Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I);
- /// setIVIncInsertPos - Set the current IV increment loop and position.
+ /// \brief Set the current IV increment loop and position.
void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
assert(!CanonicalMode &&
"IV increment positions are not supported in CanonicalMode");
@@ -148,16 +154,15 @@ namespace llvm {
IVIncInsertPos = Pos;
}
- /// setPostInc - Enable post-inc expansion for addrecs referring to the
- /// given loops. Post-inc expansion is only supported in non-canonical
- /// mode.
+ /// \brief Enable post-inc expansion for addrecs referring to the given
+ /// loops. Post-inc expansion is only supported in non-canonical mode.
void setPostInc(const PostIncLoopSet &L) {
assert(!CanonicalMode &&
"Post-inc expansion is not supported in CanonicalMode");
PostIncLoops = L;
}
- /// clearPostInc - Disable all post-inc expansion.
+ /// \brief Disable all post-inc expansion.
void clearPostInc() {
PostIncLoops.clear();
@@ -166,23 +171,22 @@ namespace llvm {
InsertedPostIncValues.clear();
}
- /// disableCanonicalMode - Disable the behavior of expanding expressions in
- /// canonical form rather than in a more literal form. Non-canonical mode
- /// is useful for late optimization passes.
+ /// \brief Disable the behavior of expanding expressions in canonical form
+ /// rather than in a more literal form. Non-canonical mode is useful for
+ /// late optimization passes.
void disableCanonicalMode() { CanonicalMode = false; }
void enableLSRMode() { LSRMode = true; }
- /// clearInsertPoint - Clear the current insertion point. This is useful
- /// if the instruction that had been serving as the insertion point may
- /// have been deleted.
+ /// \brief Clear the current insertion point. This is useful if the
+ /// instruction that had been serving as the insertion point may have been
+ /// deleted.
void clearInsertPoint() {
Builder.ClearInsertionPoint();
}
- /// isInsertedInstruction - Return true if the specified instruction was
- /// inserted by the code rewriter. If so, the client should not modify the
- /// instruction.
+ /// \brief Return true if the specified instruction was inserted by the code
+ /// rewriter. If so, the client should not modify the instruction.
bool isInsertedInstruction(Instruction *I) const {
return InsertedValues.count(I) || InsertedPostIncValues.count(I);
}
@@ -192,24 +196,27 @@ namespace llvm {
private:
LLVMContext &getContext() const { return SE.getContext(); }
- /// InsertBinop - Insert the specified binary operator, doing a small amount
+ /// \brief Recursive helper function for isHighCostExpansion.
+ bool isHighCostExpansionHelper(const SCEV *S, Loop *L,
+ SmallPtrSetImpl<const SCEV *> &Processed);
+
+ /// \brief Insert the specified binary operator, doing a small amount
/// of work to avoid inserting an obviously redundant operation.
Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS);
- /// ReuseOrCreateCast - Arange for there to be a cast of V to Ty at IP,
- /// reusing an existing cast if a suitable one exists, moving an existing
- /// cast if a suitable one exists but isn't in the right place, or
- /// or creating a new one.
+ /// \brief Arrange for there to be a cast of V to Ty at IP, reusing an
+ /// existing cast if a suitable one exists, moving an existing cast if a
+ /// suitable one exists but isn't in the right place, or or creating a new
+ /// one.
Value *ReuseOrCreateCast(Value *V, Type *Ty,
Instruction::CastOps Op,
BasicBlock::iterator IP);
- /// InsertNoopCastOfTo - Insert a cast of V to the specified type,
- /// which must be possible with a noop cast, doing what we can to
- /// share the casts.
+ /// \brief Insert a cast of V to the specified type, which must be possible
+ /// with a noop cast, doing what we can to share the casts.
Value *InsertNoopCastOfTo(Value *V, Type *Ty);
- /// expandAddToGEP - Expand a SCEVAddExpr with a pointer type into a GEP
+ /// \brief Expand a SCEVAddExpr with a pointer type into a GEP
/// instead of using ptrtoint+arithmetic+inttoptr.
Value *expandAddToGEP(const SCEV *const *op_begin,
const SCEV *const *op_end,
@@ -217,13 +224,13 @@ namespace llvm {
Value *expand(const SCEV *S);
- /// expandCodeFor - Insert code to directly compute the specified SCEV
- /// expression into the program. The inserted code is inserted into the
- /// SCEVExpander's current insertion point. If a type is specified, the
- /// result will be expanded to have that type, with a cast if necessary.
+ /// \brief Insert code to directly compute the specified SCEV expression
+ /// into the program. The inserted code is inserted into the SCEVExpander's
+ /// current insertion point. If a type is specified, the result will be
+ /// expanded to have that type, with a cast if necessary.
Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr);
- /// getRelevantLoop - Determine the most "relevant" loop for the given SCEV.
+ /// \brief Determine the most "relevant" loop for the given SCEV.
const Loop *getRelevantLoop(const SCEV *);
Value *visitConstant(const SCEVConstant *S) {
diff --git a/include/llvm/Analysis/TargetFolder.h b/include/llvm/Analysis/TargetFolder.h
index f691296..12bf9fe 100644
--- a/include/llvm/Analysis/TargetFolder.h
+++ b/include/llvm/Analysis/TargetFolder.h
@@ -130,34 +130,35 @@ public:
// Memory Instructions
//===--------------------------------------------------------------------===//
- Constant *CreateGetElementPtr(Constant *C,
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
- return Fold(ConstantExpr::getGetElementPtr(C, IdxList));
+ return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
}
- Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return Fold(ConstantExpr::getGetElementPtr(C, Idx));
+ return Fold(ConstantExpr::getGetElementPtr(Ty, C, Idx));
}
- Constant *CreateGetElementPtr(Constant *C,
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
- return Fold(ConstantExpr::getGetElementPtr(C, IdxList));
+ return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
}
- Constant *CreateInBoundsGetElementPtr(Constant *C,
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
- return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList));
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
}
- Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
+ Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx));
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx));
}
- Constant *CreateInBoundsGetElementPtr(Constant *C,
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
- return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList));
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
}
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index fdb2010..f4195fb 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -190,12 +190,21 @@ public:
/// comments for a detailed explanation of the cost values.
unsigned getUserCost(const User *U) const;
- /// \brief hasBranchDivergence - Return true if branch divergence exists.
+ /// \brief Return true if branch divergence exists.
+ ///
/// Branch divergence has a significantly negative impact on GPU performance
/// when threads in the same wavefront take different paths due to conditional
/// branches.
bool hasBranchDivergence() const;
+ /// \brief Returns whether V is a source of divergence.
+ ///
+ /// This function provides the target-dependent information for
+ /// the target-independent DivergenceAnalysis. DivergenceAnalysis first
+ /// builds the dependency graph, and then runs the reachability algorithm
+ /// starting with the sources of divergence.
+ bool isSourceOfDivergence(const Value *V) const;
+
/// \brief Test whether calls to a function lower to actual program function
/// calls.
///
@@ -252,6 +261,9 @@ public:
/// loop body even when the number of loop iterations is not known at
/// compile time).
bool Runtime;
+ /// Allow emitting expensive instructions (such as divisions) when computing
+ /// the trip count of a loop for runtime unrolling.
+ bool AllowExpensiveTripCount;
};
/// \brief Get target-customized preferences for the generic loop unrolling
@@ -520,6 +532,7 @@ public:
ArrayRef<const Value *> Arguments) = 0;
virtual unsigned getUserCost(const User *U) = 0;
virtual bool hasBranchDivergence() = 0;
+ virtual bool isSourceOfDivergence(const Value *V) = 0;
virtual bool isLoweredToCall(const Function *F) = 0;
virtual void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) = 0;
virtual bool isLegalAddImmediate(int64_t Imm) = 0;
@@ -619,6 +632,9 @@ public:
}
unsigned getUserCost(const User *U) override { return Impl.getUserCost(U); }
bool hasBranchDivergence() override { return Impl.hasBranchDivergence(); }
+ bool isSourceOfDivergence(const Value *V) override {
+ return Impl.isSourceOfDivergence(V);
+ }
bool isLoweredToCall(const Function *F) override {
return Impl.isLoweredToCall(F);
}
diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h
index f4bf07f..b00de77 100644
--- a/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -164,6 +164,8 @@ public:
bool hasBranchDivergence() { return false; }
+ bool isSourceOfDivergence(const Value *V) { return false; }
+
bool isLoweredToCall(const Function *F) {
// FIXME: These should almost certainly not be handled here, and instead
// handled with the help of TLI or the target itself. This was largely
@@ -408,7 +410,7 @@ public:
->getGEPCost(GEP->getPointerOperand(), Indices);
}
- if (ImmutableCallSite CS = U) {
+ if (auto CS = ImmutableCallSite(U)) {
const Function *F = CS.getCalledFunction();
if (!F) {
// Just use the called value type.
diff --git a/include/llvm/Bitcode/BitCodes.h b/include/llvm/Bitcode/BitCodes.h
index 3f7a77d..96c4201 100644
--- a/include/llvm/Bitcode/BitCodes.h
+++ b/include/llvm/Bitcode/BitCodes.h
@@ -164,8 +164,8 @@ template <> struct isPodLike<BitCodeAbbrevOp> { static const bool value=true; };
/// specialized format instead of the fully-general, fully-vbr, format.
class BitCodeAbbrev : public RefCountedBase<BitCodeAbbrev> {
SmallVector<BitCodeAbbrevOp, 32> OperandList;
- ~BitCodeAbbrev() {}
// Only RefCountedBase is allowed to delete.
+ ~BitCodeAbbrev() = default;
friend class RefCountedBase<BitCodeAbbrev>;
public:
diff --git a/include/llvm/Bitcode/BitcodeWriterPass.h b/include/llvm/Bitcode/BitcodeWriterPass.h
index 8fe9b7e..ae915c6 100644
--- a/include/llvm/Bitcode/BitcodeWriterPass.h
+++ b/include/llvm/Bitcode/BitcodeWriterPass.h
@@ -26,7 +26,11 @@ class PreservedAnalyses;
/// \brief Create and return a pass that writes the module to the specified
/// ostream. Note that this pass is designed for use with the legacy pass
/// manager.
-ModulePass *createBitcodeWriterPass(raw_ostream &Str);
+///
+/// If \c ShouldPreserveUseListOrder, encode use-list order so it can be
+/// reproduced when deserialized.
+ModulePass *createBitcodeWriterPass(raw_ostream &Str,
+ bool ShouldPreserveUseListOrder = false);
/// \brief Pass for writing a module of IR out to a bitcode file.
///
@@ -34,10 +38,16 @@ ModulePass *createBitcodeWriterPass(raw_ostream &Str);
/// a pass for the legacy pass manager, use the function above.
class BitcodeWriterPass {
raw_ostream &OS;
+ bool ShouldPreserveUseListOrder;
public:
/// \brief Construct a bitcode writer pass around a particular output stream.
- explicit BitcodeWriterPass(raw_ostream &OS) : OS(OS) {}
+ ///
+ /// If \c ShouldPreserveUseListOrder, encode use-list order so it can be
+ /// reproduced when deserialized.
+ explicit BitcodeWriterPass(raw_ostream &OS,
+ bool ShouldPreserveUseListOrder = false)
+ : OS(OS), ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
/// \brief Run the bitcode writer pass, and output the module to the selected
/// output stream.
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index d842167..e450db0 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -397,7 +397,8 @@ namespace bitc {
ATTR_KIND_IN_ALLOCA = 38,
ATTR_KIND_NON_NULL = 39,
ATTR_KIND_JUMP_TABLE = 40,
- ATTR_KIND_DEREFERENCEABLE = 41
+ ATTR_KIND_DEREFERENCEABLE = 41,
+ ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42
};
enum ComdatSelectionKindCodes {
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h
index 254949d..9d30098 100644
--- a/include/llvm/Bitcode/ReaderWriter.h
+++ b/include/llvm/Bitcode/ReaderWriter.h
@@ -56,11 +56,16 @@ namespace llvm {
parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
DiagnosticHandlerFunction DiagnosticHandler = nullptr);
- /// WriteBitcodeToFile - Write the specified module to the specified
- /// raw output stream. For streams where it matters, the given stream
- /// should be in "binary" mode.
- void WriteBitcodeToFile(const Module *M, raw_ostream &Out);
-
+ /// \brief Write the specified module to the specified raw output stream.
+ ///
+ /// For streams where it matters, the given stream should be in "binary"
+ /// mode.
+ ///
+ /// If \c ShouldPreserveUseListOrder, encode the use-list order for each \a
+ /// Value in \c M. These will be reconstructed exactly when \a M is
+ /// deserialized.
+ void WriteBitcodeToFile(const Module *M, raw_ostream &Out,
+ bool ShouldPreserveUseListOrder = false);
/// isBitcodeWrapper - Return true if the given bytes are the magic bytes
/// for an LLVM IR bitcode wrapper.
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index d364012..11f98ca 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -140,7 +140,7 @@ protected:
explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);
public:
- virtual ~AsmPrinter();
+ ~AsmPrinter() override;
DwarfDebug *getDwarfDebug() { return DD; }
DwarfDebug *getDwarfDebug() const { return DD; }
diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h
index e1e5112..c5efef3 100644
--- a/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/include/llvm/CodeGen/BasicTTIImpl.h
@@ -114,6 +114,8 @@ public:
bool hasBranchDivergence() { return false; }
+ bool isSourceOfDivergence(const Value *V) { return false; }
+
bool isLegalAddImmediate(int64_t imm) {
return getTLI()->isLegalAddImmediate(imm);
}
diff --git a/include/llvm/CodeGen/GCStrategy.h b/include/llvm/CodeGen/GCStrategy.h
index 869f888..a1b8e89 100644
--- a/include/llvm/CodeGen/GCStrategy.h
+++ b/include/llvm/CodeGen/GCStrategy.h
@@ -60,11 +60,11 @@
namespace llvm {
namespace GC {
-/// PointKind - The type of a collector-safe point.
+/// PointKind - Used to indicate whether the address of the call instruction
+/// or the address after the call instruction is listed in the stackmap. For
+/// most runtimes, PostCall safepoints are appropriate.
///
enum PointKind {
- Loop, ///< Instr is a loop (backwards branch).
- Return, ///< Instr is a return instruction.
PreCall, ///< Instr is a call instruction.
PostCall ///< Instr is the return address of a call.
};
diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h
index b3a8405..aa217d5 100644
--- a/include/llvm/CodeGen/LexicalScopes.h
+++ b/include/llvm/CodeGen/LexicalScopes.h
@@ -23,7 +23,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/DebugLoc.h"
-#include "llvm/IR/Metadata.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/ValueHandle.h"
#include <unordered_map>
#include <utility>
@@ -45,7 +45,8 @@ typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange;
class LexicalScope {
public:
- LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
+ LexicalScope(LexicalScope *P, const MDLocalScope *D, const MDLocation *I,
+ bool A)
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
LastInsn(nullptr), FirstInsn(nullptr), DFSIn(0), DFSOut(0) {
assert((!D || D->isResolved()) && "Expected resolved node");
@@ -57,8 +58,8 @@ public:
// Accessors.
LexicalScope *getParent() const { return Parent; }
const MDNode *getDesc() const { return Desc; }
- const MDNode *getInlinedAt() const { return InlinedAtLocation; }
- const MDNode *getScopeNode() const { return Desc; }
+ const MDLocation *getInlinedAt() const { return InlinedAtLocation; }
+ const MDLocalScope *getScopeNode() const { return Desc; }
bool isAbstractScope() const { return AbstractScope; }
SmallVectorImpl<LexicalScope *> &getChildren() { return Children; }
SmallVectorImpl<InsnRange> &getRanges() { return Ranges; }
@@ -118,8 +119,8 @@ public:
private:
LexicalScope *Parent; // Parent to this scope.
- const MDNode *Desc; // Debug info descriptor.
- const MDNode *InlinedAtLocation; // Location at which this
+ const MDLocalScope *Desc; // Debug info descriptor.
+ const MDLocation *InlinedAtLocation; // Location at which this
// scope is inlined.
bool AbstractScope; // Abstract Scope
SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope.
@@ -158,16 +159,16 @@ public:
/// getMachineBasicBlocks - Populate given set using machine basic blocks
/// which have machine instructions that belong to lexical scope identified by
/// DebugLoc.
- void getMachineBasicBlocks(DebugLoc DL,
+ void getMachineBasicBlocks(const MDLocation *DL,
SmallPtrSetImpl<const MachineBasicBlock *> &MBBs);
/// dominates - Return true if DebugLoc's lexical scope dominates at least one
/// machine instruction's lexical scope in a given machine basic block.
- bool dominates(DebugLoc DL, MachineBasicBlock *MBB);
+ bool dominates(const MDLocation *DL, MachineBasicBlock *MBB);
/// findLexicalScope - Find lexical scope, either regular or inlined, for the
/// given DebugLoc. Return NULL if not found.
- LexicalScope *findLexicalScope(DebugLoc DL);
+ LexicalScope *findLexicalScope(const MDLocation *DL);
/// getAbstractScopesList - Return a reference to list of abstract scopes.
ArrayRef<LexicalScope *> getAbstractScopesList() const {
@@ -175,19 +176,19 @@ public:
}
/// findAbstractScope - Find an abstract scope or return null.
- LexicalScope *findAbstractScope(const MDNode *N) {
+ LexicalScope *findAbstractScope(const MDLocalScope *N) {
auto I = AbstractScopeMap.find(N);
return I != AbstractScopeMap.end() ? &I->second : nullptr;
}
/// findInlinedScope - Find an inlined scope for the given scope/inlined-at.
- LexicalScope *findInlinedScope(const MDNode *N, const MDNode *IA) {
+ LexicalScope *findInlinedScope(const MDLocalScope *N, const MDLocation *IA) {
auto I = InlinedLexicalScopeMap.find(std::make_pair(N, IA));
return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
}
/// findLexicalScope - Find regular lexical scope or return null.
- LexicalScope *findLexicalScope(const MDNode *N) {
+ LexicalScope *findLexicalScope(const MDLocalScope *N) {
auto I = LexicalScopeMap.find(N);
return I != LexicalScopeMap.end() ? &I->second : nullptr;
}
@@ -196,18 +197,24 @@ public:
void dump();
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
- LexicalScope *getOrCreateAbstractScope(const MDNode *N);
+ LexicalScope *getOrCreateAbstractScope(const MDLocalScope *Scope);
private:
- /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
+ /// getOrCreateLexicalScope - Find lexical scope for the given Scope/IA. If
/// not available then create new lexical scope.
- LexicalScope *getOrCreateLexicalScope(DebugLoc DL);
+ LexicalScope *getOrCreateLexicalScope(const MDLocalScope *Scope,
+ const MDLocation *IA = nullptr);
+ LexicalScope *getOrCreateLexicalScope(const MDLocation *DL) {
+ return DL ? getOrCreateLexicalScope(DL->getScope(), DL->getInlinedAt())
+ : nullptr;
+ }
/// getOrCreateRegularScope - Find or create a regular lexical scope.
- LexicalScope *getOrCreateRegularScope(MDNode *Scope);
+ LexicalScope *getOrCreateRegularScope(const MDLocalScope *Scope);
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
- LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt);
+ LexicalScope *getOrCreateInlinedScope(const MDLocalScope *Scope,
+ const MDLocation *InlinedAt);
/// extractLexicalScopes - Extract instruction ranges for each lexical scopes
/// for the given machine function.
@@ -223,17 +230,18 @@ private:
/// LexicalScopeMap - Tracks the scopes in the current function.
// Use an unordered_map to ensure value pointer validity over insertion.
- std::unordered_map<const MDNode *, LexicalScope> LexicalScopeMap;
+ std::unordered_map<const MDLocalScope *, LexicalScope> LexicalScopeMap;
/// InlinedLexicalScopeMap - Tracks inlined function scopes in current
/// function.
- std::unordered_map<std::pair<const MDNode *, const MDNode *>, LexicalScope,
- pair_hash<const MDNode *, const MDNode *>>
- InlinedLexicalScopeMap;
+ std::unordered_map<std::pair<const MDLocalScope *, const MDLocation *>,
+ LexicalScope,
+ pair_hash<const MDLocalScope *, const MDLocation *>>
+ InlinedLexicalScopeMap;
/// AbstractScopeMap - These scopes are not included LexicalScopeMap.
// Use an unordered_map to ensure value pointer validity over insertion.
- std::unordered_map<const MDNode *, LexicalScope> AbstractScopeMap;
+ std::unordered_map<const MDLocalScope *, LexicalScope> AbstractScopeMap;
/// AbstractScopesList - Tracks abstract scopes constructed while processing
/// a function.
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index dc52c0a..9673f80 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -100,7 +100,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
public:
static char ID; // Pass identification, replacement for typeid
LiveIntervals();
- virtual ~LiveIntervals();
+ ~LiveIntervals() override;
// Calculate the spill weight to assign to a single instruction.
static float getSpillWeight(bool isDef, bool isUse,
diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h
index 44c3c4e..de855f2 100644
--- a/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/include/llvm/CodeGen/LiveRangeEdit.h
@@ -122,7 +122,7 @@ public:
MRI.setDelegate(this);
}
- ~LiveRangeEdit() { MRI.resetDelegate(this); }
+ ~LiveRangeEdit() override { MRI.resetDelegate(this); }
LiveInterval &getParent() const {
assert(Parent && "No parent LiveInterval");
diff --git a/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
index 1aef689..feb394e 100644
--- a/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
+++ b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
@@ -35,7 +35,7 @@ public:
MachineBlockFrequencyInfo();
- ~MachineBlockFrequencyInfo();
+ ~MachineBlockFrequencyInfo() override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h
index 19f4e2d..4428fa6 100644
--- a/include/llvm/CodeGen/MachineDominators.h
+++ b/include/llvm/CodeGen/MachineDominators.h
@@ -72,7 +72,7 @@ public:
MachineDominatorTree();
- ~MachineDominatorTree();
+ ~MachineDominatorTree() override;
DominatorTreeBase<MachineBasicBlock> &getBase() {
applySplitCriticalEdges();
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 6677360..1e7fee6 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -516,10 +516,6 @@ public:
/// on the stack. Returns an index with a negative value.
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset);
- /// Allocates memory at a fixed, target-specific offset from the frame
- /// pointer. Marks the function as having its frame address taken.
- int CreateFrameAllocation(uint64_t Size);
-
/// isFixedObjectIndex - Returns true if the specified index corresponds to a
/// fixed stack object.
bool isFixedObjectIndex(int ObjectIdx) const {
diff --git a/include/llvm/CodeGen/MachineFunctionAnalysis.h b/include/llvm/CodeGen/MachineFunctionAnalysis.h
index 36f1c66..023eeb1 100644
--- a/include/llvm/CodeGen/MachineFunctionAnalysis.h
+++ b/include/llvm/CodeGen/MachineFunctionAnalysis.h
@@ -31,7 +31,7 @@ private:
public:
static char ID;
explicit MachineFunctionAnalysis(const TargetMachine &tm);
- ~MachineFunctionAnalysis();
+ ~MachineFunctionAnalysis() override;
MachineFunction &getMF() const { return *MF; }
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 333dcdb..9097150 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -248,9 +248,7 @@ public:
/// this DBG_VALUE instruction.
DIVariable getDebugVariable() const {
assert(isDebugValue() && "not a DBG_VALUE");
- DIVariable Var(getOperand(2).getMetadata());
- assert(Var.Verify() && "not a DIVariable");
- return Var;
+ return cast<MDLocalVariable>(getOperand(2).getMetadata());
}
/// \brief Return the complex address expression referenced by
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index e6cb494..0574ebc 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -174,7 +174,8 @@ public:
const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
MI->addOperand(*MF, MachineOperand::CreateMetadata(MD));
- assert((MI->isDebugValue() ? MI->getDebugVariable().Verify() : true) &&
+ assert((MI->isDebugValue() ? static_cast<bool>(MI->getDebugVariable())
+ : true) &&
"first MDNode argument of a DBG_VALUE not a DIVariable");
return *this;
}
@@ -355,8 +356,10 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL,
const MCInstrDesc &MCID, bool IsIndirect,
unsigned Reg, unsigned Offset,
const MDNode *Variable, const MDNode *Expr) {
- assert(DIVariable(Variable).Verify() && "not a DIVariable");
- assert(DIExpression(Expr)->isValid() && "not a DIExpression");
+ assert(isa<MDLocalVariable>(Variable) && "not a DIVariable");
+ assert(cast<MDExpression>(Expr)->isValid() && "not a DIExpression");
+ assert(cast<MDLocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
+ "Expected inlined-at fields to agree");
if (IsIndirect)
return BuildMI(MF, DL, MCID)
.addReg(Reg, RegState::Debug)
@@ -382,8 +385,8 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
const MCInstrDesc &MCID, bool IsIndirect,
unsigned Reg, unsigned Offset,
const MDNode *Variable, const MDNode *Expr) {
- assert(DIVariable(Variable).Verify() && "not a DIVariable");
- assert(DIExpression(Expr)->isValid() && "not a DIExpression");
+ assert(isa<MDLocalVariable>(Variable) && "not a DIVariable");
+ assert(cast<MDExpression>(Expr)->isValid() && "not a DIExpression");
MachineFunction &MF = *BB.getParent();
MachineInstr *MI =
BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr);
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index f171df2..3965b1d 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -58,22 +58,25 @@ class MachineFunction;
class Module;
class PointerType;
class StructType;
+struct WinEHFuncInfo;
//===----------------------------------------------------------------------===//
/// LandingPadInfo - This structure is used to retain landing pad info for
/// the current function.
///
struct LandingPadInfo {
- MachineBasicBlock *LandingPadBlock; // Landing pad block.
- SmallVector<MCSymbol*, 1> BeginLabels; // Labels prior to invoke.
- SmallVector<MCSymbol*, 1> EndLabels; // Labels after invoke.
- SmallVector<MCSymbol*, 1> ClauseLabels; // Labels for each clause.
- MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
- const Function *Personality; // Personality function.
- std::vector<int> TypeIds; // List of type ids (filters negative)
+ MachineBasicBlock *LandingPadBlock; // Landing pad block.
+ SmallVector<MCSymbol *, 1> BeginLabels; // Labels prior to invoke.
+ SmallVector<MCSymbol *, 1> EndLabels; // Labels after invoke.
+ SmallVector<MCSymbol *, 1> ClauseLabels; // Labels for each clause.
+ MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
+ const Function *Personality; // Personality function.
+ std::vector<int> TypeIds; // List of type ids (filters negative).
+ int WinEHState; // WinEH specific state number.
explicit LandingPadInfo(MachineBasicBlock *MBB)
- : LandingPadBlock(MBB), LandingPadLabel(nullptr), Personality(nullptr) {}
+ : LandingPadBlock(MBB), LandingPadLabel(nullptr), Personality(nullptr),
+ WinEHState(-1) {}
};
//===----------------------------------------------------------------------===//
@@ -88,7 +91,10 @@ public:
virtual ~MachineModuleInfoImpl();
typedef std::vector<std::pair<MCSymbol*, StubValueTy> > SymbolListTy;
protected:
- static SymbolListTy GetSortedStubs(const DenseMap<MCSymbol*, StubValueTy>&);
+
+ /// Return the entries from a DenseMap in a deterministic sorted orer.
+ /// Clears the map.
+ static SymbolListTy getSortedStubs(DenseMap<MCSymbol*, StubValueTy>&);
};
//===----------------------------------------------------------------------===//
@@ -172,16 +178,19 @@ class MachineModuleInfo : public ImmutablePass {
EHPersonality PersonalityTypeCache;
+ DenseMap<const Function *, std::unique_ptr<WinEHFuncInfo>> FuncInfoMap;
+
public:
static char ID; // Pass identification, replacement for typeid
struct VariableDbgInfo {
- TrackingMDNodeRef Var;
- TrackingMDNodeRef Expr;
+ const MDLocalVariable *Var;
+ const MDExpression *Expr;
unsigned Slot;
- DebugLoc Loc;
+ const MDLocation *Loc;
- VariableDbgInfo(MDNode *Var, MDNode *Expr, unsigned Slot, DebugLoc Loc)
+ VariableDbgInfo(const MDLocalVariable *Var, const MDExpression *Expr,
+ unsigned Slot, const MDLocation *Loc)
: Var(Var), Expr(Expr), Slot(Slot), Loc(Loc) {}
};
typedef SmallVector<VariableDbgInfo, 4> VariableDbgInfoMapTy;
@@ -191,7 +200,7 @@ public:
// Real constructor.
MachineModuleInfo(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
const MCObjectFileInfo *MOFI);
- ~MachineModuleInfo();
+ ~MachineModuleInfo() override;
// Initialization and Finalization
bool doInitialization(Module &) override;
@@ -207,6 +216,12 @@ public:
void setModule(const Module *M) { TheModule = M; }
const Module *getModule() const { return TheModule; }
+ const Function *getWinEHParent(const Function *F) const;
+ WinEHFuncInfo &getWinEHFuncInfo(const Function *F);
+ bool hasWinEHFuncInfo(const Function *F) const {
+ return FuncInfoMap.count(getWinEHParent(F)) > 0;
+ }
+
/// getInfo - Keep track of various per-function pieces of information for
/// backends that would like to do so.
///
@@ -304,6 +319,8 @@ public:
void addPersonality(MachineBasicBlock *LandingPad,
const Function *Personality);
+ void addWinEHState(MachineBasicBlock *LandingPad, int State);
+
/// getPersonalityIndex - Get index of the current personality function inside
/// Personalitites array
unsigned getPersonalityIndex() const;
@@ -421,8 +438,8 @@ public:
/// setVariableDbgInfo - Collect information used to emit debugging
/// information of a variable.
- void setVariableDbgInfo(MDNode *Var, MDNode *Expr, unsigned Slot,
- DebugLoc Loc) {
+ void setVariableDbgInfo(const MDLocalVariable *Var, const MDExpression *Expr,
+ unsigned Slot, const MDLocation *Loc) {
VariableDbgInfos.emplace_back(Var, Expr, Slot, Loc);
}
diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h
index 7afc7eb..a67f9b5 100644
--- a/include/llvm/CodeGen/MachineModuleInfoImpls.h
+++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -58,14 +58,14 @@ namespace llvm {
}
/// Accessor methods to return the set of stubs in sorted order.
- SymbolListTy GetFnStubList() const {
- return GetSortedStubs(FnStubs);
+ SymbolListTy GetFnStubList() {
+ return getSortedStubs(FnStubs);
}
- SymbolListTy GetGVStubList() const {
- return GetSortedStubs(GVStubs);
+ SymbolListTy GetGVStubList() {
+ return getSortedStubs(GVStubs);
}
- SymbolListTy GetHiddenGVStubList() const {
- return GetSortedStubs(HiddenGVStubs);
+ SymbolListTy GetHiddenGVStubList() {
+ return getSortedStubs(HiddenGVStubs);
}
};
@@ -87,8 +87,8 @@ namespace llvm {
/// Accessor methods to return the set of stubs in sorted order.
- SymbolListTy GetGVStubList() const {
- return GetSortedStubs(GVStubs);
+ SymbolListTy GetGVStubList() {
+ return getSortedStubs(GVStubs);
}
};
diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h
index 57d1a6d..6731983 100644
--- a/include/llvm/CodeGen/MachinePassRegistry.h
+++ b/include/llvm/CodeGen/MachinePassRegistry.h
@@ -124,7 +124,7 @@ class RegisterPassParser : public MachinePassRegistryListener,
public:
RegisterPassParser(cl::Option &O)
: cl::parser<typename RegistryClass::FunctionPassCtor>(O) {}
- ~RegisterPassParser() { RegistryClass::setListener(nullptr); }
+ ~RegisterPassParser() override { RegistryClass::setListener(nullptr); }
void initialize() {
cl::parser<typename RegistryClass::FunctionPassCtor>::initialize();
diff --git a/include/llvm/CodeGen/MachinePostDominators.h b/include/llvm/CodeGen/MachinePostDominators.h
index aab5c40..70bdb19 100644
--- a/include/llvm/CodeGen/MachinePostDominators.h
+++ b/include/llvm/CodeGen/MachinePostDominators.h
@@ -33,7 +33,7 @@ public:
MachinePostDominatorTree();
- ~MachinePostDominatorTree();
+ ~MachinePostDominatorTree() override;
FunctionPass *createMachinePostDominatorTreePass();
diff --git a/include/llvm/CodeGen/MachineRegionInfo.h b/include/llvm/CodeGen/MachineRegionInfo.h
index 43499db..cf49c29 100644
--- a/include/llvm/CodeGen/MachineRegionInfo.h
+++ b/include/llvm/CodeGen/MachineRegionInfo.h
@@ -57,8 +57,6 @@ public:
}
- ~MachineRegionNode() { }
-
bool operator==(const MachineRegion &RN) const {
return this == reinterpret_cast<const MachineRegionNode*>(&RN);
}
@@ -80,7 +78,7 @@ class MachineRegionInfo : public RegionInfoBase<RegionTraits<MachineFunction>> {
public:
explicit MachineRegionInfo();
- virtual ~MachineRegionInfo();
+ ~MachineRegionInfo() override;
// updateStatistics - Update statistic about created regions.
void updateStatistics(MachineRegion *R) final;
@@ -98,7 +96,7 @@ public:
static char ID;
explicit MachineRegionInfoPass();
- ~MachineRegionInfoPass();
+ ~MachineRegionInfoPass() override;
MachineRegionInfo &getRegionInfo() {
return RI;
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 001d09f..e5b837a 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -620,22 +620,25 @@ public:
/// setRegAllocationHint - Specify a register allocation hint for the
/// specified virtual register.
- void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) {
- RegAllocHints[Reg].first = Type;
- RegAllocHints[Reg].second = PrefReg;
+ void setRegAllocationHint(unsigned VReg, unsigned Type, unsigned PrefReg) {
+ assert(TargetRegisterInfo::isVirtualRegister(VReg));
+ RegAllocHints[VReg].first = Type;
+ RegAllocHints[VReg].second = PrefReg;
}
/// getRegAllocationHint - Return the register allocation hint for the
/// specified virtual register.
std::pair<unsigned, unsigned>
- getRegAllocationHint(unsigned Reg) const {
- return RegAllocHints[Reg];
+ getRegAllocationHint(unsigned VReg) const {
+ assert(TargetRegisterInfo::isVirtualRegister(VReg));
+ return RegAllocHints[VReg];
}
/// getSimpleHint - Return the preferred register allocation hint, or 0 if a
/// standard simple hint (Type == 0) is not set.
- unsigned getSimpleHint(unsigned Reg) const {
- std::pair<unsigned, unsigned> Hint = getRegAllocationHint(Reg);
+ unsigned getSimpleHint(unsigned VReg) const {
+ assert(TargetRegisterInfo::isVirtualRegister(VReg));
+ std::pair<unsigned, unsigned> Hint = getRegAllocationHint(VReg);
return Hint.first ? 0 : Hint.second;
}
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
index a319401..e80e14e 100644
--- a/include/llvm/CodeGen/MachineScheduler.h
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -385,7 +385,7 @@ public:
ShouldTrackPressure(false), RPTracker(RegPressure),
TopRPTracker(TopPressure), BotRPTracker(BotPressure) {}
- virtual ~ScheduleDAGMILive();
+ ~ScheduleDAGMILive() override;
/// Return true if this DAG supports VReg liveness and RegPressure.
bool hasVRegLiveness() const override { return true; }
@@ -909,7 +909,7 @@ public:
PostGenericScheduler(const MachineSchedContext *C):
GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ") {}
- virtual ~PostGenericScheduler() {}
+ ~PostGenericScheduler() override {}
void initPolicy(MachineBasicBlock::iterator Begin,
MachineBasicBlock::iterator End,
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 48e1f21..2505c04 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -125,7 +125,7 @@ public:
// Dummy constructor.
TargetPassConfig();
- virtual ~TargetPassConfig();
+ ~TargetPassConfig() override;
static char ID;
diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h
index cc9e000..fcb6fee 100644
--- a/include/llvm/CodeGen/RegisterPressure.h
+++ b/include/llvm/CodeGen/RegisterPressure.h
@@ -35,21 +35,6 @@ struct RegisterPressure {
SmallVector<unsigned,8> LiveInRegs;
SmallVector<unsigned,8> LiveOutRegs;
- /// Increase register pressure for each pressure set impacted by this register
- /// class. Normally called by RegPressureTracker, but may be called manually
- /// to account for live through (global liveness).
- ///
- /// \param Reg is either a virtual register number or register unit number.
- void increase(unsigned Reg, const TargetRegisterInfo *TRI,
- const MachineRegisterInfo *MRI);
-
- /// Decrease register pressure for each pressure set impacted by this register
- /// class. This is only useful to account for spilling or rematerialization.
- ///
- /// \param Reg is either a virtual register number or register unit number.
- void decrease(unsigned Reg, const TargetRegisterInfo *TRI,
- const MachineRegisterInfo *MRI);
-
void dump(const TargetRegisterInfo *TRI) const;
};
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 00dd8f9..1196783 100644
--- a/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -158,7 +158,7 @@ namespace llvm {
bool RemoveKillFlags = false,
LiveIntervals *LIS = nullptr);
- virtual ~ScheduleDAGInstrs() {}
+ ~ScheduleDAGInstrs() override {}
bool isPostRA() const { return IsPostRA; }
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index dc1c80d..582febd 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -41,14 +41,16 @@ class TargetSelectionDAGInfo;
class SDVTListNode : public FoldingSetNode {
friend struct FoldingSetTrait<SDVTListNode>;
- /// FastID - A reference to an Interned FoldingSetNodeID for this node.
+ /// A reference to an Interned FoldingSetNodeID for this node.
/// The Allocator in SelectionDAG holds the data.
/// SDVTList contains all types which are frequently accessed in SelectionDAG.
- /// The size of this list is not expected big so it won't introduce memory penalty.
+ /// The size of this list is not expected to be big so it won't introduce
+ /// a memory penalty.
FoldingSetNodeIDRef FastID;
const EVT *VTs;
unsigned int NumVTs;
- /// The hash value for SDVTList is fixed so cache it to avoid hash calculation
+ /// The hash value for SDVTList is fixed, so cache it to avoid
+ /// hash calculation.
unsigned HashValue;
public:
SDVTListNode(const FoldingSetNodeIDRef ID, const EVT *VT, unsigned int Num) :
@@ -61,8 +63,8 @@ public:
}
};
-// Specialize FoldingSetTrait for SDVTListNode
-// To avoid computing temp FoldingSetNodeID and hash value.
+/// Specialize FoldingSetTrait for SDVTListNode
+/// to avoid computing temp FoldingSetNodeID and hash value.
template<> struct FoldingSetTrait<SDVTListNode> : DefaultFoldingSetTrait<SDVTListNode> {
static void Profile(const SDVTListNode &X, FoldingSetNodeID& ID) {
ID = X.FastID;
@@ -98,7 +100,7 @@ private:
static void createNode(const SDNode &);
};
-/// SDDbgInfo - Keeps track of dbg_value information through SDISel. We do
+/// Keeps track of dbg_value information through SDISel. We do
/// not build SDNodes for these so as not to perturb the generated code;
/// instead the info is kept off to the side in this structure. Each SDNode may
/// have one or more associated dbg_value entries. This information is kept in
@@ -159,10 +161,10 @@ public:
class SelectionDAG;
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
-/// selection. This DAG is constructed as the first step of instruction
-/// selection in order to allow implementation of machine specific optimizations
+/// This is used to represent a portion of an LLVM function in a low-level
+/// Data Dependence DAG representation suitable for instruction selection.
+/// This DAG is constructed as the first step of instruction selection in order
+/// to allow implementation of machine specific optimizations
/// and code simplifications.
///
/// The representation used by the SelectionDAG is a target-independent
@@ -178,40 +180,39 @@ class SelectionDAG {
LLVMContext *Context;
CodeGenOpt::Level OptLevel;
- /// EntryNode - The starting token.
+ /// The starting token.
SDNode EntryNode;
- /// Root - The root of the entire DAG.
+ /// The root of the entire DAG.
SDValue Root;
- /// AllNodes - A linked list of nodes in the current DAG.
+ /// A linked list of nodes in the current DAG.
ilist<SDNode> AllNodes;
- /// NodeAllocatorType - The AllocatorType for allocating SDNodes. We use
+ /// The AllocatorType for allocating SDNodes. We use
/// pool allocation with recycling.
typedef RecyclingAllocator<BumpPtrAllocator, SDNode, sizeof(LargestSDNode),
AlignOf<MostAlignedSDNode>::Alignment>
NodeAllocatorType;
- /// NodeAllocator - Pool allocation for nodes.
+ /// Pool allocation for nodes.
NodeAllocatorType NodeAllocator;
- /// CSEMap - This structure is used to memoize nodes, automatically performing
+ /// This structure is used to memoize nodes, automatically performing
/// CSE with existing nodes when a duplicate is requested.
FoldingSet<SDNode> CSEMap;
- /// OperandAllocator - Pool allocation for machine-opcode SDNode operands.
+ /// Pool allocation for machine-opcode SDNode operands.
BumpPtrAllocator OperandAllocator;
- /// Allocator - Pool allocation for misc. objects that are created once per
- /// SelectionDAG.
+ /// Pool allocation for misc. objects that are created once per SelectionDAG.
BumpPtrAllocator Allocator;
- /// DbgInfo - Tracks dbg_value information through SDISel.
+ /// Tracks dbg_value information through SDISel.
SDDbgInfo *DbgInfo;
public:
- /// DAGUpdateListener - Clients of various APIs that cause global effects on
+ /// Clients of various APIs that cause global effects on
/// the DAG can optionally implement this interface. This allows the clients
/// to handle the various sorts of updates that happen.
///
@@ -232,15 +233,15 @@ public:
DAG.UpdateListeners = Next;
}
- /// NodeDeleted - The node N that was deleted and, if E is not null, an
+ /// The node N that was deleted and, if E is not null, an
/// equivalent node E that replaced it.
virtual void NodeDeleted(SDNode *N, SDNode *E);
- /// NodeUpdated - The node N that was updated.
+ /// The node N that was updated.
virtual void NodeUpdated(SDNode *N);
};
- /// NewNodesMustHaveLegalTypes - When true, additional steps are taken to
+ /// When true, additional steps are taken to
/// ensure that getConstant() and similar functions return DAG nodes that
/// have legal types. This is important after type legalization since
/// any illegally typed nodes generated after this point will not experience
@@ -251,13 +252,12 @@ private:
/// DAGUpdateListener is a friend so it can manipulate the listener stack.
friend struct DAGUpdateListener;
- /// UpdateListeners - Linked list of registered DAGUpdateListener instances.
+ /// Linked list of registered DAGUpdateListener instances.
/// This stack is maintained by DAGUpdateListener RAII.
DAGUpdateListener *UpdateListeners;
- /// setGraphColorHelper - Implementation of setSubgraphColor.
+ /// Implementation of setSubgraphColor.
/// Return whether we had to truncate the search.
- ///
bool setSubgraphColorHelper(SDNode *N, const char *Color,
DenseSet<SDNode *> &visited,
int level, bool &printed);
@@ -269,14 +269,11 @@ public:
explicit SelectionDAG(const TargetMachine &TM, llvm::CodeGenOpt::Level);
~SelectionDAG();
- /// init - Prepare this SelectionDAG to process code in the given
- /// MachineFunction.
- ///
+ /// Prepare this SelectionDAG to process code in the given MachineFunction.
void init(MachineFunction &mf);
- /// clear - Clear state and free memory necessary to make this
+ /// Clear state and free memory necessary to make this
/// SelectionDAG ready to process a new block.
- ///
void clear();
MachineFunction &getMachineFunction() const { return *MF; }
@@ -286,8 +283,7 @@ public:
const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return *TSI; }
LLVMContext *getContext() const {return Context; }
- /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
- ///
+ /// Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
void viewGraph(const std::string &Title);
void viewGraph();
@@ -295,24 +291,21 @@ public:
std::map<const SDNode *, std::string> NodeGraphAttrs;
#endif
- /// clearGraphAttrs - Clear all previously defined node graph attributes.
+ /// Clear all previously defined node graph attributes.
/// Intended to be used from a debugging tool (eg. gdb).
void clearGraphAttrs();
- /// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
- ///
+ /// Set graph attributes for a node. (eg. "color=red".)
void setGraphAttrs(const SDNode *N, const char *Attrs);
- /// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
+ /// Get graph attributes for a node. (eg. "color=red".)
/// Used from getNodeAttributes.
const std::string getGraphAttrs(const SDNode *N) const;
- /// setGraphColor - Convenience for setting node color attribute.
- ///
+ /// Convenience for setting node color attribute.
void setGraphColor(const SDNode *N, const char *Color);
- /// setGraphColor - Convenience for setting subgraph color attribute.
- ///
+ /// Convenience for setting subgraph color attribute.
void setSubgraphColor(SDNode *N, const char *Color);
typedef ilist<SDNode>::const_iterator allnodes_const_iterator;
@@ -325,17 +318,15 @@ public:
return AllNodes.size();
}
- /// getRoot - Return the root tag of the SelectionDAG.
- ///
+ /// Return the root tag of the SelectionDAG.
const SDValue &getRoot() const { return Root; }
- /// getEntryNode - Return the token chain corresponding to the entry of the
- /// function.
+ /// Return the token chain corresponding to the entry of the function.
SDValue getEntryNode() const {
return SDValue(const_cast<SDNode *>(&EntryNode), 0);
}
- /// setRoot - Set the current root tag of the SelectionDAG.
+ /// Set the current root tag of the SelectionDAG.
///
const SDValue &setRoot(SDValue N) {
assert((!N.getNode() || N.getValueType() == MVT::Other) &&
@@ -348,22 +339,22 @@ public:
return Root;
}
- /// Combine - This iterates over the nodes in the SelectionDAG, folding
+ /// This iterates over the nodes in the SelectionDAG, folding
/// certain types of nodes together, or eliminating superfluous nodes. The
/// Level argument controls whether Combine is allowed to produce nodes and
/// types that are illegal on the target.
void Combine(CombineLevel Level, AliasAnalysis &AA,
CodeGenOpt::Level OptLevel);
- /// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that
- /// only uses types natively supported by the target. Returns "true" if it
- /// made any changes.
+ /// This transforms the SelectionDAG into a SelectionDAG that
+ /// only uses types natively supported by the target.
+ /// Returns "true" if it made any changes.
///
/// Note that this is an involved process that may invalidate pointers into
/// the graph.
bool LegalizeTypes();
- /// Legalize - This transforms the SelectionDAG into a SelectionDAG that is
+ /// This transforms the SelectionDAG into a SelectionDAG that is
/// compatible with the target instruction selector, as indicated by the
/// TargetLowering object.
///
@@ -392,7 +383,7 @@ public:
/// UpdatedNodes with any new nodes replacing those originally in the DAG.
bool LegalizeOp(SDNode *N, SmallSetVector<SDNode *, 16> &UpdatedNodes);
- /// LegalizeVectors - This transforms the SelectionDAG into a SelectionDAG
+ /// This transforms the SelectionDAG into a SelectionDAG
/// that only uses vector math operations supported by the target. This is
/// necessary as a separate step from Legalize because unrolling a vector
/// operation can introduce illegal types, which requires running
@@ -405,16 +396,14 @@ public:
/// the graph.
bool LegalizeVectors();
- /// RemoveDeadNodes - This method deletes all unreachable nodes in the
- /// SelectionDAG.
+ /// This method deletes all unreachable nodes in the SelectionDAG.
void RemoveDeadNodes();
- /// DeleteNode - Remove the specified node from the system. This node must
+ /// Remove the specified node from the system. This node must
/// have no referrers.
void DeleteNode(SDNode *N);
- /// getVTList - Return an SDVTList that represents the list of values
- /// specified.
+ /// Return an SDVTList that represents the list of values specified.
SDVTList getVTList(EVT VT);
SDVTList getVTList(EVT VT1, EVT VT2);
SDVTList getVTList(EVT VT1, EVT VT2, EVT VT3);
@@ -561,10 +550,9 @@ public:
SDValue STy,
SDValue Rnd, SDValue Sat, ISD::CvtCode Code);
- /// getVectorShuffle - Return an ISD::VECTOR_SHUFFLE node. The number of
- /// elements in VT, which must be a vector type, must match the number of
- /// mask elements NumElts. A integer mask element equal to -1 is treated as
- /// undefined.
+ /// Return an ISD::VECTOR_SHUFFLE node. The number of elements in VT,
+ /// which must be a vector type, must match the number of mask elements
+ /// NumElts. An integer mask element equal to -1 is treated as undefined.
SDValue getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, SDValue N2,
const int *MaskElts);
SDValue getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, SDValue N2,
@@ -580,63 +568,62 @@ public:
/// Example: shuffle A, B, <0,5,2,7> -> shuffle B, A, <4,1,6,3>
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV);
- /// getAnyExtOrTrunc - Convert Op, which must be of integer type, to the
+ /// Convert Op, which must be of integer type, to the
/// integer type VT, by either any-extending or truncating it.
SDValue getAnyExtOrTrunc(SDValue Op, SDLoc DL, EVT VT);
- /// getSExtOrTrunc - Convert Op, which must be of integer type, to the
+ /// Convert Op, which must be of integer type, to the
/// integer type VT, by either sign-extending or truncating it.
SDValue getSExtOrTrunc(SDValue Op, SDLoc DL, EVT VT);
- /// getZExtOrTrunc - Convert Op, which must be of integer type, to the
+ /// Convert Op, which must be of integer type, to the
/// integer type VT, by either zero-extending or truncating it.
SDValue getZExtOrTrunc(SDValue Op, SDLoc DL, EVT VT);
- /// getZeroExtendInReg - Return the expression required to zero extend the Op
+ /// Return the expression required to zero extend the Op
/// 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,
+ /// 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,
+ /// 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,
+ /// 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
+ /// Convert Op, which must be of integer type, to the integer type VT,
+ /// by using an extension appropriate for the target's
/// 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).
+ /// Create a bitwise NOT operation as (XOR Val, -1).
SDValue getNOT(SDLoc DL, SDValue Val, EVT VT);
/// \brief Create a logical NOT operation as (XOR Val, BooleanOne).
SDValue getLogicalNOT(SDLoc DL, SDValue Val, EVT VT);
- /// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have
- /// a glue result (to ensure it's not CSE'd). CALLSEQ_START does not have a
- /// useful SDLoc.
+ /// Return a new CALLSEQ_START node, which always must have a glue result
+ /// (to ensure it's not CSE'd). CALLSEQ_START does not have a useful SDLoc.
SDValue getCALLSEQ_START(SDValue Chain, SDValue Op, SDLoc DL) {
SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
SDValue Ops[] = { Chain, Op };
return getNode(ISD::CALLSEQ_START, DL, VTs, Ops);
}
- /// getCALLSEQ_END - Return a new CALLSEQ_END node, which always must have a
- /// glue result (to ensure it's not CSE'd). CALLSEQ_END does not have
- /// a useful SDLoc.
+ /// Return a new CALLSEQ_END node, which always must have a
+ /// glue result (to ensure it's not CSE'd).
+ /// CALLSEQ_END does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2,
SDValue InGlue, SDLoc DL) {
SDVTList NodeTys = getVTList(MVT::Other, MVT::Glue);
@@ -649,18 +636,17 @@ public:
return getNode(ISD::CALLSEQ_END, DL, NodeTys, Ops);
}
- /// getUNDEF - Return an UNDEF node. UNDEF does not have a useful SDLoc.
+ /// Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getUNDEF(EVT VT) {
return getNode(ISD::UNDEF, SDLoc(), VT);
}
- /// getGLOBAL_OFFSET_TABLE - Return a GLOBAL_OFFSET_TABLE node. This does
- /// not have a useful SDLoc.
+ /// Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
SDValue getGLOBAL_OFFSET_TABLE(EVT VT) {
return getNode(ISD::GLOBAL_OFFSET_TABLE, SDLoc(), VT);
}
- /// getNode - Gets or creates the specified node.
+ /// Gets or creates the specified node.
///
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT);
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N);
@@ -692,27 +678,26 @@ public:
SDValue N1, SDValue N2, SDValue N3, SDValue N4,
SDValue N5);
- /// getStackArgumentTokenFactor - Compute a TokenFactor to force all
- /// the incoming stack arguments to be loaded from the stack. This is
- /// used in tail call lowering to protect stack arguments from being
- /// clobbered.
+ /// Compute a TokenFactor to force all the incoming stack arguments to be
+ /// loaded from the stack. This is used in tail call lowering to protect
+ /// stack arguments from being clobbered.
SDValue getStackArgumentTokenFactor(SDValue Chain);
SDValue getMemcpy(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src,
SDValue Size, unsigned Align, bool isVol, bool AlwaysInline,
- MachinePointerInfo DstPtrInfo,
+ bool isTailCall, MachinePointerInfo DstPtrInfo,
MachinePointerInfo SrcPtrInfo);
SDValue getMemmove(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src,
- SDValue Size, unsigned Align, bool isVol,
+ SDValue Size, unsigned Align, bool isVol, bool isTailCall,
MachinePointerInfo DstPtrInfo,
MachinePointerInfo SrcPtrInfo);
SDValue getMemset(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src,
- SDValue Size, unsigned Align, bool isVol,
+ SDValue Size, unsigned Align, bool isVol, bool isTailCall,
MachinePointerInfo DstPtrInfo);
- /// getSetCC - Helper function to make it easier to build SetCC's if you just
+ /// Helper function to make it easier to build SetCC's if you just
/// have an ISD::CondCode instead of an SDValue.
///
SDValue getSetCC(SDLoc DL, EVT VT, SDValue LHS, SDValue RHS,
@@ -726,8 +711,8 @@ public:
return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
}
- // getSelect - Helper function to make it easier to build Select's if you just
- // have operands and don't want to check for vector.
+ /// Helper function to make it easier to build Select's if you just
+ /// have operands and don't want to check for vector.
SDValue getSelect(SDLoc DL, EVT VT, SDValue Cond,
SDValue LHS, SDValue RHS) {
assert(LHS.getValueType() == RHS.getValueType() &&
@@ -738,7 +723,7 @@ public:
Cond, LHS, RHS);
}
- /// getSelectCC - Helper function to make it easier to build SelectCC's if you
+ /// Helper function to make it easier to build SelectCC's if you
/// just have an ISD::CondCode instead of an SDValue.
///
SDValue getSelectCC(SDLoc DL, SDValue LHS, SDValue RHS,
@@ -747,12 +732,12 @@ public:
LHS, RHS, True, False, getCondCode(Cond));
}
- /// getVAArg - VAArg produces a result and token chain, and takes a pointer
+ /// VAArg produces a result and token chain, and takes a pointer
/// and a source value as input.
SDValue getVAArg(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr,
SDValue SV, unsigned Align);
- /// getAtomicCmpSwap - Gets a node for an atomic cmpxchg op. There are two
+ /// Gets a node for an atomic cmpxchg op. There are two
/// valid Opcodes. ISD::ATOMIC_CMO_SWAP produces 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.
@@ -769,7 +754,7 @@ public:
AtomicOrdering FailureOrdering,
SynchronizationScope SynchScope);
- /// getAtomic - Gets a node for an atomic op, produces result (if relevant)
+ /// Gets a node for an atomic op, produces result (if relevant)
/// and chain and takes 2 operands.
SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Val, const Value *PtrVal,
@@ -780,15 +765,15 @@ public:
AtomicOrdering Ordering,
SynchronizationScope SynchScope);
- /// getAtomic - Gets a node for an atomic op, produces result and chain and
+ /// Gets a node for an atomic op, produces result and chain and
/// takes 1 operand.
SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, EVT VT,
SDValue Chain, SDValue Ptr, MachineMemOperand *MMO,
AtomicOrdering Ordering,
SynchronizationScope SynchScope);
- /// getAtomic - Gets a node for an atomic op, produces result and chain and
- /// takes N operands.
+ /// Gets a node for an atomic op, produces result and chain and takes N
+ /// operands.
SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTList,
ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
AtomicOrdering SuccessOrdering,
@@ -798,7 +783,7 @@ public:
ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
AtomicOrdering Ordering, SynchronizationScope SynchScope);
- /// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a
+ /// Creates a MemIntrinsicNode that may produce a
/// result and takes a list of operands. Opcode may be INTRINSIC_VOID,
/// INTRINSIC_W_CHAIN, or a target-specific opcode with a value not
/// less than FIRST_TARGET_MEMORY_OPCODE.
@@ -813,10 +798,10 @@ public:
ArrayRef<SDValue> Ops,
EVT MemVT, MachineMemOperand *MMO);
- /// getMergeValues - Create a MERGE_VALUES node from the given operands.
+ /// Create a MERGE_VALUES node from the given operands.
SDValue getMergeValues(ArrayRef<SDValue> Ops, SDLoc dl);
- /// getLoad - Loads are not normal binary operators: their result type is not
+ /// Loads are not normal binary operators: their result type is not
/// determined by their operands, and they produce a value AND a token chain.
///
SDValue getLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr,
@@ -848,8 +833,7 @@ public:
SDValue Chain, SDValue Ptr, SDValue Offset,
EVT MemVT, MachineMemOperand *MMO);
- /// getStore - Helper function to build ISD::STORE nodes.
- ///
+ /// Helper function to build ISD::STORE nodes.
SDValue getStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr,
MachinePointerInfo PtrInfo, bool isVolatile,
bool isNonTemporal, unsigned Alignment,
@@ -872,21 +856,21 @@ public:
SDValue getMaskedStore(SDValue Chain, SDLoc dl, SDValue Val,
SDValue Ptr, SDValue Mask, EVT MemVT,
MachineMemOperand *MMO, bool IsTrunc);
- /// getSrcValue - Construct a node to track a Value* through the backend.
+ /// Construct a node to track a Value* through the backend.
SDValue getSrcValue(const Value *v);
- /// getMDNode - Return an MDNodeSDNode which holds an MDNode.
+ /// Return an MDNodeSDNode which holds an MDNode.
SDValue getMDNode(const MDNode *MD);
- /// getAddrSpaceCast - Return an AddrSpaceCastSDNode.
+ /// Return an AddrSpaceCastSDNode.
SDValue getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr,
unsigned SrcAS, unsigned DestAS);
- /// getShiftAmountOperand - Return the specified value casted to
+ /// Return the specified value casted to
/// the target's desired shift amount type.
SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op);
- /// UpdateNodeOperands - *Mutate* the specified node in-place to have the
+ /// *Mutate* the specified node in-place to have the
/// specified operands. If the resultant node already exists in the DAG,
/// this does not modify the specified node, instead it returns the node that
/// already exists. If the resultant node does not exist in the DAG, the
@@ -902,7 +886,7 @@ public:
SDValue Op3, SDValue Op4, SDValue Op5);
SDNode *UpdateNodeOperands(SDNode *N, ArrayRef<SDValue> Ops);
- /// SelectNodeTo - These are used for target selectors to *mutate* the
+ /// These are used for target selectors to *mutate* the
/// specified node to have the specified return type, Target opcode, and
/// operands. Note that target opcodes are stored as
/// ~TargetOpcode in the node opcode field. The resultant node is returned.
@@ -932,12 +916,12 @@ public:
SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, SDVTList VTs,
ArrayRef<SDValue> Ops);
- /// MorphNodeTo - This *mutates* the specified node to have the specified
+ /// This *mutates* the specified node to have the specified
/// return type, opcode, and operands.
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs,
ArrayRef<SDValue> Ops);
- /// getMachineNode - These are used for target selectors to create a new node
+ /// These are used for target selectors to create a new node
/// with specified return type(s), MachineInstr opcode, and operands.
///
/// Note that getMachineNode returns the resultant node. If there is already
@@ -976,25 +960,20 @@ public:
MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, SDVTList VTs,
ArrayRef<SDValue> Ops);
- /// getTargetExtractSubreg - A convenience function for creating
- /// TargetInstrInfo::EXTRACT_SUBREG nodes.
+ /// A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue getTargetExtractSubreg(int SRIdx, SDLoc DL, EVT VT,
SDValue Operand);
- /// getTargetInsertSubreg - A convenience function for creating
- /// TargetInstrInfo::INSERT_SUBREG nodes.
+ /// A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
SDValue getTargetInsertSubreg(int SRIdx, SDLoc DL, EVT VT,
SDValue Operand, SDValue Subreg);
- /// getNodeIfExists - Get the specified node if it's already available, or
- /// else return NULL.
+ /// Get the specified node if it's already available, or else return NULL.
SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, ArrayRef<SDValue> Ops,
bool nuw = false, bool nsw = false,
bool exact = false);
- /// getDbgValue - Creates a SDDbgValue node.
- ///
- /// SDNode
+ /// Creates a SDDbgValue node.
SDDbgValue *getDbgValue(MDNode *Var, MDNode *Expr, SDNode *N, unsigned R,
bool IsIndirect, uint64_t Off, DebugLoc DL,
unsigned O);
@@ -1007,16 +986,16 @@ public:
SDDbgValue *getFrameIndexDbgValue(MDNode *Var, MDNode *Expr, unsigned FI,
uint64_t Off, DebugLoc DL, unsigned O);
- /// RemoveDeadNode - Remove the specified node from the system. If any of its
+ /// Remove the specified node from the system. If any of its
/// operands then becomes dead, remove them as well. Inform UpdateListener
/// for each node deleted.
void RemoveDeadNode(SDNode *N);
- /// RemoveDeadNodes - This method deletes the unreachable nodes in the
+ /// This method deletes the unreachable nodes in the
/// given list, and any nodes that become unreachable as a result.
void RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes);
- /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
+ /// Modify anything using 'From' to use 'To' instead.
/// This can cause recursive merging of nodes in the DAG. Use the first
/// version if 'From' is known to have a single result, use the second
/// if you have two nodes with identical results (or if 'To' has a superset
@@ -1035,30 +1014,29 @@ public:
void ReplaceAllUsesWith(SDNode *From, SDNode *To);
void ReplaceAllUsesWith(SDNode *From, const SDValue *To);
- /// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
+ /// Replace any uses of From with To, leaving
/// uses of other values produced by From.Val alone.
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To);
- /// ReplaceAllUsesOfValuesWith - Like ReplaceAllUsesOfValueWith, but
- /// for multiple values at once. This correctly handles the case where
+ /// Like ReplaceAllUsesOfValueWith, but for multiple values at once.
+ /// This correctly handles the case where
/// there is an overlap between the From values and the To values.
void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To,
unsigned Num);
- /// AssignTopologicalOrder - Topological-sort the AllNodes list and a
+ /// Topological-sort the AllNodes list and a
/// assign a unique node id for each node in the DAG based on their
/// topological order. Returns the number of nodes.
unsigned AssignTopologicalOrder();
- /// RepositionNode - Move node N in the AllNodes list to be immediately
+ /// Move node N in the AllNodes list to be immediately
/// before the given iterator Position. This may be used to update the
/// topological ordering when the list of nodes is modified.
void RepositionNode(allnodes_iterator Position, SDNode *N) {
AllNodes.insert(Position, AllNodes.remove(N));
}
- /// isCommutativeBinOp - Returns true if the opcode is a commutative binary
- /// operation.
+ /// Returns true if the opcode is a commutative binary operation.
static bool isCommutativeBinOp(unsigned Opcode) {
// FIXME: This should get its info from the td file, so that we can include
// target info.
@@ -1099,19 +1077,19 @@ public:
}
}
- /// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
+ /// Add a dbg_value SDNode. If SD is non-null that means the
/// value is produced by SD.
void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter);
- /// GetDbgValues - Get the debug values which reference the given SDNode.
+ /// Get the debug values which reference the given SDNode.
ArrayRef<SDDbgValue*> GetDbgValues(const SDNode* SD) {
return DbgInfo->getSDDbgValues(SD);
}
- /// TransferDbgValues - Transfer SDDbgValues.
+ /// Transfer SDDbgValues.
void TransferDbgValues(SDValue From, SDValue To);
- /// hasDebugValues - Return true if there are any SDDbgValue nodes associated
+ /// Return true if there are any SDDbgValue nodes associated
/// with this SelectionDAG.
bool hasDebugValues() const { return !DbgInfo->empty(); }
@@ -1126,28 +1104,27 @@ public:
void dump() const;
- /// CreateStackTemporary - Create a stack temporary, suitable for holding the
+ /// Create a stack temporary, suitable for holding the
/// specified value type. If minAlign is specified, the slot size will have
/// at least that alignment.
SDValue CreateStackTemporary(EVT VT, unsigned minAlign = 1);
- /// CreateStackTemporary - Create a stack temporary suitable for holding
+ /// Create a stack temporary suitable for holding
/// either of the specified value types.
SDValue CreateStackTemporary(EVT VT1, EVT VT2);
- /// FoldConstantArithmetic -
SDValue FoldConstantArithmetic(unsigned Opcode, EVT VT,
SDNode *Cst1, SDNode *Cst2);
- /// FoldSetCC - Constant fold a setcc to true or false.
+ /// Constant fold a setcc to true or false.
SDValue FoldSetCC(EVT VT, SDValue N1,
SDValue N2, ISD::CondCode Cond, SDLoc dl);
- /// SignBitIsZero - Return true if the sign bit of Op is known to be zero. We
- /// use this predicate to simplify operations downstream.
+ /// Return true if the sign bit of Op is known to be zero.
+ /// We use this predicate to simplify operations downstream.
bool SignBitIsZero(SDValue Op, unsigned Depth = 0) const;
- /// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We
+ /// Return true if 'Op & Mask' is known to be zero. We
/// use this predicate to simplify operations downstream. Op and Mask are
/// known to be the same type.
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth = 0)
@@ -1160,7 +1137,7 @@ public:
void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne,
unsigned Depth = 0) const;
- /// ComputeNumSignBits - Return the number of times the sign bit of the
+ /// Return the number of times the sign bit of the
/// register is replicated into the other bits. We know that at least 1 bit
/// is always equal to the sign bit (itself), but other cases can give us
/// information. For example, immediately after an "SRA X, 2", we know that
@@ -1169,26 +1146,26 @@ public:
/// class to allow target nodes to be understood.
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth = 0) const;
- /// isBaseWithConstantOffset - Return true if the specified operand is an
+ /// Return true if the specified operand is an
/// ISD::ADD with a ConstantSDNode on the right-hand side, or if it is an
/// ISD::OR with a ConstantSDNode that is guaranteed to have the same
/// semantics as an ADD. This handles the equivalence:
/// X|Cst == X+Cst iff X&Cst = 0.
bool isBaseWithConstantOffset(SDValue Op) const;
- /// isKnownNeverNan - Test whether the given SDValue is known to never be NaN.
+ /// Test whether the given SDValue is known to never be NaN.
bool isKnownNeverNaN(SDValue Op) const;
- /// isKnownNeverZero - Test whether the given SDValue is known to never be
+ /// Test whether the given SDValue is known to never be
/// positive or negative Zero.
bool isKnownNeverZero(SDValue Op) const;
- /// isEqualTo - Test whether two SDValues are known to compare equal. This
+ /// Test whether two SDValues are known to compare equal. This
/// is true if they are the same value, or if one is negative zero and the
/// other positive zero.
bool isEqualTo(SDValue A, SDValue B) const;
- /// UnrollVectorOp - Utility function used by legalize and lowering to
+ /// Utility function used by legalize and lowering to
/// "unroll" a vector operation by splitting out the scalars and operating
/// on each element individually. If the ResNE is 0, fully unroll the vector
/// op. If ResNE is less than the width of the vector op, unroll up to ResNE.
@@ -1196,43 +1173,40 @@ public:
/// vector op and fill the end of the resulting vector with UNDEFS.
SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0);
- /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a
- /// location that is 'Dist' units away from the location that the 'Base' load
- /// is loading from.
+ /// Return true if LD is loading 'Bytes' bytes from a location that is 'Dist'
+ /// units away from the location that the 'Base' load is loading from.
bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base,
unsigned Bytes, int Dist) const;
- /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if
+ /// Infer alignment of a load / store address. Return 0 if
/// it cannot be inferred.
unsigned InferPtrAlignment(SDValue Ptr) const;
- /// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type
+ /// Compute the VTs needed for the low/hi parts of a type
/// which is split (or expanded) into two not necessarily identical pieces.
std::pair<EVT, EVT> GetSplitDestVTs(const EVT &VT) const;
- /// SplitVector - Split the vector with EXTRACT_SUBVECTOR using the provides
+ /// Split the vector with EXTRACT_SUBVECTOR using the provides
/// VTs and return the low/high part.
std::pair<SDValue, SDValue> SplitVector(const SDValue &N, const SDLoc &DL,
const EVT &LoVT, const EVT &HiVT);
- /// SplitVector - Split the vector with EXTRACT_SUBVECTOR and return the
- /// low/high part.
+ /// Split the vector with EXTRACT_SUBVECTOR and return the low/high part.
std::pair<SDValue, SDValue> SplitVector(const SDValue &N, const SDLoc &DL) {
EVT LoVT, HiVT;
std::tie(LoVT, HiVT) = GetSplitDestVTs(N.getValueType());
return SplitVector(N, DL, LoVT, HiVT);
}
- /// SplitVectorOperand - Split the node's operand with EXTRACT_SUBVECTOR and
+ /// Split the node's operand with EXTRACT_SUBVECTOR and
/// return the low/high part.
std::pair<SDValue, SDValue> SplitVectorOperand(const SDNode *N, unsigned OpNo)
{
return SplitVector(N->getOperand(OpNo), SDLoc(N));
}
- /// ExtractVectorElements - Append the extracted elements from Start to Count
- /// out of the vector Op in Args. If Count is 0, all of the elements will be
- /// extracted.
+ /// Append the extracted elements from Start to Count out of the vector Op
+ /// in Args. If Count is 0, all of the elements will be extracted.
void ExtractVectorElements(SDValue Op, SmallVectorImpl<SDValue> &Args,
unsigned Start = 0, unsigned Count = 0);
@@ -1258,10 +1232,10 @@ private:
SDValue N1, SDValue N2, bool nuw, bool nsw,
bool exact);
- /// VTList - List of non-single value types.
+ /// List of non-single value types.
FoldingSet<SDVTListNode> VTListMap;
- /// CondCodeNodes - Maps to auto-CSE operations.
+ /// Maps to auto-CSE operations.
std::vector<CondCodeSDNode*> CondCodeNodes;
std::vector<SDNode*> ValueTypeNodes;
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index 7acdfc7..a874375 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -58,7 +58,7 @@ public:
explicit SelectionDAGISel(TargetMachine &tm,
CodeGenOpt::Level OL = CodeGenOpt::Default);
- virtual ~SelectionDAGISel();
+ ~SelectionDAGISel() override;
const TargetLowering *getTargetLowering() const { return TLI; }
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 2b3e08c..66f060c 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -50,23 +50,6 @@ template <typename T> struct DenseMapInfo;
template <typename T> struct simplify_type;
template <typename T> struct ilist_traits;
-/// 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);
@@ -967,6 +950,23 @@ public:
}
};
+/// 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;
+ }
+}
+
/// This class is an extension of BinarySDNode
/// used from those opcodes that have associated extra flags.
class BinaryWithFlagsSDNode : public BinarySDNode {
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 75920a3..a868cbd 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -34,11 +34,12 @@ namespace llvm {
class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
bool UseInitArray;
+ mutable unsigned NextUniqueID = 0;
public:
TargetLoweringObjectFileELF() : UseInitArray(false) {}
- virtual ~TargetLoweringObjectFileELF() {}
+ ~TargetLoweringObjectFileELF() override {}
void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM,
const MCSymbol *Sym) const override;
@@ -87,7 +88,7 @@ public:
class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
public:
- virtual ~TargetLoweringObjectFileMachO() {}
+ ~TargetLoweringObjectFileMachO() override {}
TargetLoweringObjectFileMachO();
/// Extract the dependent library name from a linker option string. Returns
@@ -135,7 +136,7 @@ public:
class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
public:
- virtual ~TargetLoweringObjectFileCOFF() {}
+ ~TargetLoweringObjectFileCOFF() override {}
const MCSection *
getExplicitSectionGlobal(const GlobalValue *GV,
diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h
new file mode 100644
index 0000000..5fc2b12
--- /dev/null
+++ b/include/llvm/CodeGen/WinEHFuncInfo.h
@@ -0,0 +1,153 @@
+//===-- llvm/CodeGen/WinEHFuncInfo.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Data structures and associated state for Windows exception handling schemes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_WINEHFUNCINFO_H
+#define LLVM_CODEGEN_WINEHFUNCINFO_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+class BasicBlock;
+class Constant;
+class Function;
+class GlobalValue;
+class IntrinsicInst;
+class LandingPadInst;
+class MCSymbol;
+class Value;
+
+enum ActionType { Catch, Cleanup };
+
+class ActionHandler {
+public:
+ ActionHandler(BasicBlock *BB, ActionType Type)
+ : StartBB(BB), Type(Type), EHState(-1), HandlerBlockOrFunc(nullptr) {}
+
+ ActionType getType() const { return Type; }
+ BasicBlock *getStartBlock() const { return StartBB; }
+
+ bool hasBeenProcessed() { return HandlerBlockOrFunc != nullptr; }
+
+ void setHandlerBlockOrFunc(Constant *F) { HandlerBlockOrFunc = F; }
+ Constant *getHandlerBlockOrFunc() { return HandlerBlockOrFunc; }
+
+ void setEHState(int State) { EHState = State; }
+ int getEHState() const { return EHState; }
+
+private:
+ BasicBlock *StartBB;
+ ActionType Type;
+ int EHState;
+
+ // Can be either a BlockAddress or a Function depending on the EH personality.
+ Constant *HandlerBlockOrFunc;
+};
+
+class CatchHandler : public ActionHandler {
+public:
+ CatchHandler(BasicBlock *BB, Constant *Selector, BasicBlock *NextBB)
+ : ActionHandler(BB, ActionType::Catch), Selector(Selector),
+ NextBB(NextBB), ExceptionObjectVar(nullptr),
+ ExceptionObjectIndex(-1) {}
+
+ // Method for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ActionHandler *H) {
+ return H->getType() == ActionType::Catch;
+ }
+
+ Constant *getSelector() const { return Selector; }
+ BasicBlock *getNextBB() const { return NextBB; }
+
+ const Value *getExceptionVar() { return ExceptionObjectVar; }
+ TinyPtrVector<BasicBlock *> &getReturnTargets() { return ReturnTargets; }
+
+ void setExceptionVar(const Value *Val) { ExceptionObjectVar = Val; }
+ void setExceptionVarIndex(int Index) { ExceptionObjectIndex = Index; }
+ int getExceptionVarIndex() const { return ExceptionObjectIndex; }
+ void setReturnTargets(TinyPtrVector<BasicBlock *> &Targets) {
+ ReturnTargets = Targets;
+ }
+
+private:
+ Constant *Selector;
+ BasicBlock *NextBB;
+ // While catch handlers are being outlined the ExceptionObjectVar field will
+ // be populated with the instruction in the parent frame that corresponds
+ // to the exception object (or nullptr if the catch does not use an
+ // exception object) and the ExceptionObjectIndex field will be -1.
+ // When the parseEHActions function is called to populate a vector of
+ // instances of this class, the ExceptionObjectVar field will be nullptr
+ // and the ExceptionObjectIndex will be the index of the exception object in
+ // the parent function's frameescape block.
+ const Value *ExceptionObjectVar;
+ int ExceptionObjectIndex;
+ TinyPtrVector<BasicBlock *> ReturnTargets;
+};
+
+class CleanupHandler : public ActionHandler {
+public:
+ CleanupHandler(BasicBlock *BB) : ActionHandler(BB, ActionType::Cleanup) {}
+
+ // Method for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ActionHandler *H) {
+ return H->getType() == ActionType::Cleanup;
+ }
+};
+
+void parseEHActions(const IntrinsicInst *II,
+ SmallVectorImpl<ActionHandler *> &Actions);
+
+
+// The following structs respresent the .xdata for functions using C++
+// exceptions on Windows.
+
+struct WinEHUnwindMapEntry {
+ int ToState;
+ Function *Cleanup;
+};
+
+struct WinEHHandlerType {
+ int Adjectives;
+ GlobalVariable *TypeDescriptor;
+ int CatchObjRecoverIdx;
+ Function *Handler;
+};
+
+struct WinEHTryBlockMapEntry {
+ int TryLow;
+ int TryHigh;
+ SmallVector<WinEHHandlerType, 1> HandlerArray;
+};
+
+struct WinEHFuncInfo {
+ DenseMap<const LandingPadInst *, int> LandingPadStateMap;
+ DenseMap<const Function *, int> CatchHandlerParentFrameObjIdx;
+ DenseMap<const Function *, int> CatchHandlerParentFrameObjOffset;
+ DenseMap<const Function *, int> CatchHandlerMaxState;
+ SmallVector<WinEHUnwindMapEntry, 4> UnwindMap;
+ SmallVector<WinEHTryBlockMapEntry, 4> TryBlockMap;
+ SmallVector<std::pair<MCSymbol *, int>, 4> IPToStateList;
+ int UnwindHelpFrameIdx;
+ int UnwindHelpFrameOffset;
+
+ unsigned NumIPToStateFuncsVisited;
+
+ WinEHFuncInfo()
+ : UnwindHelpFrameIdx(INT_MAX), UnwindHelpFrameOffset(-1),
+ NumIPToStateFuncsVisited(0) {}
+};
+
+}
+#endif // LLVM_CODEGEN_WINEHFUNCINFO_H
diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index 29fa4a3..2b377a9 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -46,7 +46,7 @@ protected:
const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
StringRef SOS, StringRef AOS, bool isLittleEndian) = 0;
- ~DWARFUnitSectionBase() {}
+ ~DWARFUnitSectionBase() = default;
};
/// Concrete instance of DWARFUnitSection, specialized for one Unit type.
diff --git a/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h b/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h
index 96ce12f..b5fa8c3 100644
--- a/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h
+++ b/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h
@@ -22,7 +22,7 @@ public:
ConcreteSymbolEnumerator(std::unique_ptr<IPDBEnumSymbols> SymbolEnumerator)
: Enumerator(std::move(SymbolEnumerator)) {}
- virtual ~ConcreteSymbolEnumerator() {}
+ ~ConcreteSymbolEnumerator() override {}
uint32_t getChildCount() const override {
return Enumerator->getChildCount();
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index abdaa0c..4b2add8 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -15,6 +15,7 @@
#ifndef LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
#define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
+#include "RuntimeDyld.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -42,6 +43,7 @@ class GlobalVariable;
class GlobalValue;
class JITEventListener;
class MachineCodeInfo;
+class MCJITMemoryManager;
class MutexGuard;
class ObjectCache;
class RTDyldMemoryManager;
@@ -57,46 +59,34 @@ namespace object {
/// table. Access to this class should be serialized under a mutex.
class ExecutionEngineState {
public:
- struct AddressMapConfig : public ValueMapConfig<const GlobalValue*> {
- typedef ExecutionEngineState *ExtraData;
- static sys::Mutex *getMutex(ExecutionEngineState *EES);
- static void onDelete(ExecutionEngineState *EES, const GlobalValue *Old);
- static void onRAUW(ExecutionEngineState *, const GlobalValue *,
- const GlobalValue *);
- };
-
- typedef ValueMap<const GlobalValue *, void *, AddressMapConfig>
- GlobalAddressMapTy;
+ typedef StringMap<uint64_t> GlobalAddressMapTy;
private:
- ExecutionEngine &EE;
- /// GlobalAddressMap - A mapping between LLVM global values and their
- /// actualized version...
+ /// GlobalAddressMap - A mapping between LLVM global symbol names values and
+ /// their actualized version...
GlobalAddressMapTy GlobalAddressMap;
/// GlobalAddressReverseMap - This is the reverse mapping of GlobalAddressMap,
/// used to convert raw addresses into the LLVM global value that is emitted
/// at the address. This map is not computed unless getGlobalValueAtAddress
/// is called at some point.
- std::map<void *, AssertingVH<const GlobalValue> > GlobalAddressReverseMap;
+ std::map<uint64_t, std::string> GlobalAddressReverseMap;
public:
- ExecutionEngineState(ExecutionEngine &EE);
GlobalAddressMapTy &getGlobalAddressMap() {
return GlobalAddressMap;
}
- std::map<void*, AssertingVH<const GlobalValue> > &
- getGlobalAddressReverseMap() {
+ std::map<uint64_t, std::string> &getGlobalAddressReverseMap() {
return GlobalAddressReverseMap;
}
/// \brief Erase an entry from the mapping table.
///
/// \returns The address that \p ToUnmap was happed to.
- void *RemoveMapping(const GlobalValue *ToUnmap);
+ uint64_t RemoveMapping(StringRef Name);
};
/// \brief Abstract interface for implementation execution of LLVM modules,
@@ -139,15 +129,17 @@ protected:
virtual char *getMemoryForGV(const GlobalVariable *GV);
static ExecutionEngine *(*MCJITCtor)(
- std::unique_ptr<Module> M,
- std::string *ErrorStr,
- std::unique_ptr<RTDyldMemoryManager> MCJMM,
- std::unique_ptr<TargetMachine> TM);
+ std::unique_ptr<Module> M,
+ std::string *ErrorStr,
+ std::shared_ptr<MCJITMemoryManager> MM,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> SR,
+ std::unique_ptr<TargetMachine> TM);
static ExecutionEngine *(*OrcMCJITReplacementCtor)(
- std::string *ErrorStr,
- std::unique_ptr<RTDyldMemoryManager> OrcJMM,
- std::unique_ptr<TargetMachine> TM);
+ std::string *ErrorStr,
+ std::shared_ptr<MCJITMemoryManager> MM,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> SR,
+ std::unique_ptr<TargetMachine> TM);
static ExecutionEngine *(*InterpCtor)(std::unique_ptr<Module> M,
std::string *ErrorStr);
@@ -157,6 +149,9 @@ protected:
/// abort.
void *(*LazyFunctionCreator)(const std::string &);
+ /// getMangledName - Get mangled name.
+ std::string getMangledName(const GlobalValue *GV);
+
public:
/// lock - This lock protects the ExecutionEngine and MCJIT classes. It must
/// be held while changing the internal state of any of those classes.
@@ -228,7 +223,8 @@ public:
/// Map the address of a JIT section as returned from the memory manager
/// to the address in the target process as the running code will see it.
/// This is the address which will be used for relocation resolution.
- virtual void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) {
+ virtual void mapSectionAddress(const void *LocalAddress,
+ uint64_t TargetAddress) {
llvm_unreachable("Re-mapping of section addresses not supported with this "
"EE!");
}
@@ -286,6 +282,7 @@ public:
/// existing data in memory. Mappings are automatically removed when their
/// GlobalValue is destroyed.
void addGlobalMapping(const GlobalValue *GV, void *Addr);
+ void addGlobalMapping(StringRef Name, uint64_t Addr);
/// clearAllGlobalMappings - Clear all global mappings and start over again,
/// for use in dynamic compilation scenarios to move globals.
@@ -299,14 +296,17 @@ public:
/// address. This updates both maps as required. If "Addr" is null, the
/// entry for the global is removed from the mappings. This returns the old
/// value of the pointer, or null if it was not in the map.
- void *updateGlobalMapping(const GlobalValue *GV, void *Addr);
+ uint64_t updateGlobalMapping(const GlobalValue *GV, void *Addr);
+ uint64_t updateGlobalMapping(StringRef Name, uint64_t Addr);
+
+ /// getAddressToGlobalIfAvailable - This returns the address of the specified
+ /// global symbol.
+ uint64_t getAddressToGlobalIfAvailable(StringRef S);
/// getPointerToGlobalIfAvailable - This returns the address of the specified
/// global value if it is has already been codegen'd, otherwise it returns
/// null.
- ///
- /// This function is deprecated for the MCJIT execution engine. It doesn't
- /// seem to be needed in that case, but an equivalent can be added if it is.
+ void *getPointerToGlobalIfAvailable(StringRef S);
void *getPointerToGlobalIfAvailable(const GlobalValue *GV);
/// getPointerToGlobal - This returns the address of the specified global
@@ -470,7 +470,7 @@ public:
}
protected:
- ExecutionEngine() : EEState(*this) {}
+ ExecutionEngine() {}
explicit ExecutionEngine(std::unique_ptr<Module> M);
void emitGlobals();
@@ -500,7 +500,8 @@ private:
EngineKind::Kind WhichEngine;
std::string *ErrorStr;
CodeGenOpt::Level OptLevel;
- std::unique_ptr<RTDyldMemoryManager> MCJMM;
+ std::shared_ptr<MCJITMemoryManager> MemMgr;
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver;
TargetOptions Options;
Reloc::Model RelocModel;
CodeModel::Model CMModel;
@@ -535,6 +536,12 @@ public:
/// memory manager. This option defaults to NULL.
EngineBuilder &setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager> mcjmm);
+ EngineBuilder&
+ setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM);
+
+ EngineBuilder&
+ setSymbolResolver(std::unique_ptr<RuntimeDyld::SymbolResolver> SR);
+
/// setErrorStr - Set the error string to write to on error. This option
/// defaults to NULL.
EngineBuilder &setErrorStr(std::string *e) {
diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 77b0c48..30f7f1c 100644
--- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -16,7 +16,7 @@
#define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
#include "IndirectionUtils.h"
-#include "LookasideRTDyldMM.h"
+#include "LambdaResolver.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include <list>
@@ -36,7 +36,7 @@ namespace orc {
/// compiled only when it is first called.
template <typename BaseLayerT, typename CompileCallbackMgrT>
class CompileOnDemandLayer {
-public:
+private:
/// @brief Lookup helper that provides compatibility with the classic
/// static-compilation symbol resolution process.
///
@@ -64,6 +64,8 @@ public:
/// @brief Construct a scoped lookup.
CODScopedLookup(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
+ virtual ~CODScopedLookup() {}
+
/// @brief Start a new context for a single logical module.
LMHandle createLogicalModule() {
Handles.push_back(SiblingHandlesList());
@@ -92,6 +94,10 @@ public:
return nullptr;
}
+ /// @brief Find an external symbol (via the user supplied SymbolResolver).
+ virtual RuntimeDyld::SymbolInfo
+ externalLookup(const std::string &Name) const = 0;
+
private:
JITSymbol findSymbolIn(LMHandle LMH, const std::string &Name) {
@@ -105,7 +111,29 @@ public:
PseudoDylibModuleSetHandlesList Handles;
};
-private:
+ template <typename ResolverPtrT>
+ class CODScopedLookupImpl : public CODScopedLookup {
+ public:
+ CODScopedLookupImpl(BaseLayerT &BaseLayer, ResolverPtrT Resolver)
+ : CODScopedLookup(BaseLayer), Resolver(std::move(Resolver)) {}
+
+ RuntimeDyld::SymbolInfo
+ externalLookup(const std::string &Name) const override {
+ return Resolver->findSymbol(Name);
+ }
+
+ private:
+ ResolverPtrT Resolver;
+ };
+
+ template <typename ResolverPtrT>
+ static std::shared_ptr<CODScopedLookup>
+ createCODScopedLookup(BaseLayerT &BaseLayer,
+ ResolverPtrT Resolver) {
+ typedef CODScopedLookupImpl<ResolverPtrT> Impl;
+ return std::make_shared<Impl>(BaseLayer, std::move(Resolver));
+ }
+
typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
typedef std::vector<BaseLayerModuleSetHandleT> BaseLayerModuleSetHandleListT;
@@ -138,36 +166,31 @@ public:
/// @brief Handle to a set of loaded modules.
typedef typename ModuleSetInfoListT::iterator ModuleSetHandleT;
- // @brief Fallback lookup functor.
- typedef std::function<uint64_t(const std::string &)> LookupFtor;
-
/// @brief Construct a compile-on-demand layer instance.
CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr)
: BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr) {}
/// @brief Add a module to the compile-on-demand layer.
- template <typename ModuleSetT>
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- LookupFtor FallbackLookup = nullptr) {
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
- // If the user didn't supply a fallback lookup then just use
- // getSymbolAddress.
- if (!FallbackLookup)
- FallbackLookup = [=](const std::string &Name) {
- return findSymbol(Name, true).getAddress();
- };
+ assert(MemMgr == nullptr &&
+ "User supplied memory managers not supported with COD yet.");
// Create a lookup context and ModuleSetInfo for this module set.
// For the purposes of symbol resolution the set Ms will be treated as if
// the modules it contained had been linked together as a dylib.
- auto DylibLookup = std::make_shared<CODScopedLookup>(BaseLayer);
+ auto DylibLookup = createCODScopedLookup(BaseLayer, std::move(Resolver));
ModuleSetHandleT H =
ModuleSetInfos.insert(ModuleSetInfos.end(), ModuleSetInfo(DylibLookup));
ModuleSetInfo &MSI = ModuleSetInfos.back();
// Process each of the modules in this module set.
for (auto &M : Ms)
- partitionAndAdd(*M, MSI, FallbackLookup);
+ partitionAndAdd(*M, MSI);
return H;
}
@@ -203,8 +226,7 @@ public:
private:
- void partitionAndAdd(Module &M, ModuleSetInfo &MSI,
- LookupFtor FallbackLookup) {
+ void partitionAndAdd(Module &M, ModuleSetInfo &MSI) {
const char *AddrSuffix = "$orc_addr";
const char *BodySuffix = "$orc_body";
@@ -224,8 +246,7 @@ private:
auto FunctionModules = std::move(PartitionedModule.Functions);
// Emit the commons stright away.
- auto CommonHandle = addModule(std::move(CommonsModule), MSI, LogicalModule,
- FallbackLookup);
+ auto CommonHandle = addModule(std::move(CommonsModule), MSI, LogicalModule);
BaseLayer.emitAndFinalize(CommonHandle);
// Map of definition names to callback-info data structures. We'll use
@@ -255,10 +276,12 @@ private:
Function *Proto = StubsModule->getFunction(Name);
assert(Proto && "Failed to clone function decl into stubs module.");
auto CallbackInfo =
- CompileCallbackMgr.getCompileCallback(*Proto->getFunctionType());
+ CompileCallbackMgr.getCompileCallback(Proto->getContext());
GlobalVariable *FunctionBodyPointer =
- createImplPointer(*Proto, Name + AddrSuffix,
- CallbackInfo.getAddress());
+ createImplPointer(*Proto->getType(), *Proto->getParent(),
+ Name + AddrSuffix,
+ createIRTypedAddress(*Proto->getFunctionType(),
+ CallbackInfo.getAddress()));
makeStub(*Proto, *FunctionBodyPointer);
F.setName(Name + BodySuffix);
@@ -268,7 +291,7 @@ private:
NewStubInfos.push_back(StubInfos.insert(StubInfos.begin(), KV));
}
- auto H = addModule(std::move(SubM), MSI, LogicalModule, FallbackLookup);
+ auto H = addModule(std::move(SubM), MSI, LogicalModule);
// Set the compile actions for this module:
for (auto &KVPair : NewStubInfos) {
@@ -286,7 +309,7 @@ private:
// Ok - we've processed all the partitioned modules. Now add the
// stubs/globals module and set the update actions.
auto StubsH =
- addModule(std::move(StubsModule), MSI, LogicalModule, FallbackLookup);
+ addModule(std::move(StubsModule), MSI, LogicalModule);
for (auto &KVPair : StubInfos) {
std::string AddrName = Mangle(KVPair.first + AddrSuffix,
@@ -304,8 +327,7 @@ private:
BaseLayerModuleSetHandleT addModule(
std::unique_ptr<Module> M,
ModuleSetInfo &MSI,
- typename CODScopedLookup::LMHandle LogicalModule,
- LookupFtor FallbackLookup) {
+ typename CODScopedLookup::LMHandle LogicalModule) {
// Add this module to the JIT with a memory manager that uses the
// DylibLookup to resolve symbols.
@@ -313,19 +335,25 @@ private:
MSet.push_back(std::move(M));
auto DylibLookup = MSI.Lookup;
- auto MM =
- createLookasideRTDyldMM<SectionMemoryManager>(
+ auto Resolver =
+ createLambdaResolver(
[=](const std::string &Name) {
if (auto Symbol = DylibLookup->findSymbol(LogicalModule, Name))
- return Symbol.getAddress();
- return FallbackLookup(Name);
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
+ return DylibLookup->externalLookup(Name);
},
- [=](const std::string &Name) {
- return DylibLookup->findSymbol(LogicalModule, Name).getAddress();
+ [=](const std::string &Name) -> RuntimeDyld::SymbolInfo {
+ if (auto Symbol = DylibLookup->findSymbol(LogicalModule, Name))
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
+ return nullptr;
});
BaseLayerModuleSetHandleT H =
- BaseLayer.addModuleSet(std::move(MSet), std::move(MM));
+ BaseLayer.addModuleSet(std::move(MSet),
+ make_unique<SectionMemoryManager>(),
+ std::move(Resolver));
// Add this module to the logical module lookup.
DylibLookup->addToLogicalModule(LogicalModule, H);
MSI.BaseLayerModuleSetHandles.push_back(H);
diff --git a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
new file mode 100644
index 0000000..c10508c
--- /dev/null
+++ b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -0,0 +1,182 @@
+//===-- ExecutionUtils.h - Utilities for executing code in Orc --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains utilities for executing code in Orc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
+
+#include "JITSymbol.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include <vector>
+
+namespace llvm {
+
+class ConstantArray;
+class GlobalVariable;
+class Function;
+class Module;
+class Value;
+
+namespace orc {
+
+/// @brief This iterator provides a convenient way to iterate over the elements
+/// of an llvm.global_ctors/llvm.global_dtors instance.
+///
+/// The easiest way to get hold of instances of this class is to use the
+/// getConstructors/getDestructors functions.
+class CtorDtorIterator {
+public:
+
+ /// @brief Accessor for an element of the global_ctors/global_dtors array.
+ ///
+ /// This class provides a read-only view of the element with any casts on
+ /// the function stripped away.
+ struct Element {
+ Element(unsigned Priority, const Function *Func, const Value *Data)
+ : Priority(Priority), Func(Func), Data(Data) {}
+
+ unsigned Priority;
+ const Function *Func;
+ const Value *Data;
+ };
+
+ /// @brief Construct an iterator instance. If End is true then this iterator
+ /// acts as the end of the range, otherwise it is the beginning.
+ CtorDtorIterator(const GlobalVariable *GV, bool End);
+
+ /// @brief Test iterators for equality.
+ bool operator==(const CtorDtorIterator &Other) const;
+
+ /// @brief Test iterators for inequality.
+ bool operator!=(const CtorDtorIterator &Other) const;
+
+ /// @brief Pre-increment iterator.
+ CtorDtorIterator& operator++();
+
+ /// @brief Post-increment iterator.
+ CtorDtorIterator operator++(int);
+
+ /// @brief Dereference iterator. The resulting value provides a read-only view
+ /// of this element of the global_ctors/global_dtors list.
+ Element operator*() const;
+
+private:
+ const ConstantArray *InitList;
+ unsigned I;
+};
+
+/// @brief Create an iterator range over the entries of the llvm.global_ctors
+/// array.
+iterator_range<CtorDtorIterator> getConstructors(const Module &M);
+
+/// @brief Create an iterator range over the entries of the llvm.global_ctors
+/// array.
+iterator_range<CtorDtorIterator> getDestructors(const Module &M);
+
+/// @brief Convenience class for recording constructor/destructor names for
+/// later execution.
+template <typename JITLayerT>
+class CtorDtorRunner {
+public:
+
+ /// @brief Construct a CtorDtorRunner for the given range using the given
+ /// name mangling function.
+ CtorDtorRunner(std::vector<std::string> CtorDtorNames,
+ typename JITLayerT::ModuleSetHandleT H)
+ : CtorDtorNames(std::move(CtorDtorNames)), H(H) {}
+
+ /// @brief Run the recorded constructors/destructors through the given JIT
+ /// layer.
+ bool runViaLayer(JITLayerT &JITLayer) const {
+ typedef void (*CtorDtorTy)();
+
+ bool Error = false;
+ for (const auto &CtorDtorName : CtorDtorNames)
+ if (auto CtorDtorSym = JITLayer.findSymbolIn(H, CtorDtorName, false)) {
+ CtorDtorTy CtorDtor =
+ reinterpret_cast<CtorDtorTy>(
+ static_cast<uintptr_t>(CtorDtorSym.getAddress()));
+ CtorDtor();
+ } else
+ Error = true;
+ return !Error;
+ }
+
+private:
+ std::vector<std::string> CtorDtorNames;
+ typename JITLayerT::ModuleSetHandleT H;
+};
+
+/// @brief Support class for static dtor execution. For hosted (in-process) JITs
+/// only!
+///
+/// If a __cxa_atexit function isn't found C++ programs that use static
+/// destructors will fail to link. However, we don't want to use the host
+/// process's __cxa_atexit, because it will schedule JIT'd destructors to run
+/// after the JIT has been torn down, which is no good. This class makes it easy
+/// to override __cxa_atexit (and the related __dso_handle).
+///
+/// To use, clients should manually call searchOverrides from their symbol
+/// resolver. This should generally be done after attempting symbol resolution
+/// inside the JIT, but before searching the host process's symbol table. When
+/// the client determines that destructors should be run (generally at JIT
+/// teardown or after a return from main), the runDestructors method should be
+/// called.
+class LocalCXXRuntimeOverrides {
+public:
+
+ /// Create a runtime-overrides class.
+ template <typename MangleFtorT>
+ LocalCXXRuntimeOverrides(const MangleFtorT &Mangle) {
+ addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride));
+ addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride));
+ }
+
+ /// Search overrided symbols.
+ RuntimeDyld::SymbolInfo searchOverrides(const std::string &Name) {
+ auto I = CXXRuntimeOverrides.find(Name);
+ if (I != CXXRuntimeOverrides.end())
+ return RuntimeDyld::SymbolInfo(I->second, JITSymbolFlags::Exported);
+ return nullptr;
+ }
+
+ /// Run any destructors recorded by the overriden __cxa_atexit function
+ /// (CXAAtExitOverride).
+ void runDestructors();
+
+private:
+
+ template <typename PtrTy>
+ TargetAddress toTargetAddress(PtrTy* P) {
+ return static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(P));
+ }
+
+ void addOverride(const std::string &Name, TargetAddress Addr) {
+ CXXRuntimeOverrides.insert(std::make_pair(Name, Addr));
+ }
+
+ StringMap<TargetAddress> CXXRuntimeOverrides;
+
+ typedef void (*DestructorPtr)(void*);
+ typedef std::pair<DestructorPtr, void*> CXXDestructorDataPair;
+ typedef std::vector<CXXDestructorDataPair> CXXDestructorDataPairList;
+ CXXDestructorDataPairList DSOHandleOverride;
+ static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg,
+ void *DSOHandle);
+};
+
+} // End namespace orc.
+} // End namespace llvm.
+
+#endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
diff --git a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
index 6a47622..6379022 100644
--- a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -52,14 +52,16 @@ public:
/// @brief Set an ObjectCache to query before compiling.
void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
- /// @brief Compile each module in the given module set, then then add the
- /// resulting set of objects to the base layer, along with the memory
- // manager MM.
+ /// @brief Compile each module in the given module set, then add the resulting
+ /// set of objects to the base layer along with the memory manager and
+ /// symbol resolver.
///
/// @return A handle for the added modules.
- template <typename ModuleSetT>
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- std::unique_ptr<RTDyldMemoryManager> MM) {
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
OwningObjectVec Objects;
OwningBufferVec Buffers;
@@ -81,7 +83,7 @@ public:
}
ModuleSetHandleT H =
- BaseLayer.addObjectSet(Objects, std::move(MM));
+ BaseLayer.addObjectSet(Objects, std::move(MemMgr), std::move(Resolver));
BaseLayer.takeOwnershipOfBuffers(H, std::move(Buffers));
diff --git a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
new file mode 100644
index 0000000..4dabb9a
--- /dev/null
+++ b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
@@ -0,0 +1,101 @@
+//===----- IRTransformLayer.h - Run all IR through a functor ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Run all IR passed in through a user supplied functor.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
+#define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
+
+#include "JITSymbol.h"
+
+namespace llvm {
+namespace orc {
+
+/// @brief IR mutating layer.
+///
+/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It
+/// immediately applies the user supplied functor to each module, then adds
+/// the set of transformed modules to the layer below.
+template <typename BaseLayerT, typename TransformFtor>
+class IRTransformLayer {
+public:
+ /// @brief Handle to a set of added modules.
+ typedef typename BaseLayerT::ModuleSetHandleT ModuleSetHandleT;
+
+ /// @brief Construct an IRTransformLayer with the given BaseLayer
+ IRTransformLayer(BaseLayerT &BaseLayer,
+ TransformFtor Transform = TransformFtor())
+ : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
+
+ /// @brief Apply the transform functor to each module in the module set, then
+ /// add the resulting set of modules to the base layer, along with the
+ /// memory manager and symbol resolver.
+ ///
+ /// @return A handle for the added modules.
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
+ ModuleSetHandleT addModuleSet(ModuleSetT Ms,
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
+
+ for (auto I = Ms.begin(), E = Ms.end(); I != E; ++I)
+ *I = Transform(std::move(*I));
+
+ return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
+ std::move(Resolver));
+ }
+
+ /// @brief Remove the module set associated with the handle H.
+ void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeModuleSet(H); }
+
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+ return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
+ }
+
+ /// @brief Get the address of the given symbol in the context of the set of
+ /// modules represented by the handle H. This call is forwarded to the
+ /// base layer's implementation.
+ /// @param H The handle for the module set to search in.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it is found in the
+ /// given module set.
+ JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
+ }
+
+ /// @brief Immediately emit and finalize the module set represented by the
+ /// given handle.
+ /// @param H Handle for module set to emit/finalize.
+ void emitAndFinalize(ModuleSetHandleT H) {
+ BaseLayer.emitAndFinalize(H);
+ }
+
+ /// @brief Access the transform functor directly.
+ TransformFtor& getTransform() { return Transform; }
+
+ /// @brief Access the mumate functor directly.
+ const TransformFtor& getTransform() const { return Transform; }
+
+private:
+ BaseLayerT &BaseLayer;
+ TransformFtor Transform;
+};
+
+} // End namespace orc.
+} // End namespace llvm.
+
+#endif // LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
diff --git a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index 8ce1d4d..7b4f611 100644
--- a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -16,6 +16,7 @@
#include "JITSymbol.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
@@ -37,11 +38,11 @@ public:
/// the compile and update actions for the callback.
class CompileCallbackInfo {
public:
- CompileCallbackInfo(Constant *Addr, CompileFtor &Compile,
+ CompileCallbackInfo(TargetAddress Addr, CompileFtor &Compile,
UpdateFtor &Update)
: Addr(Addr), Compile(Compile), Update(Update) {}
- Constant* getAddress() const { return Addr; }
+ TargetAddress getAddress() const { return Addr; }
void setCompileAction(CompileFtor Compile) {
this->Compile = std::move(Compile);
}
@@ -49,7 +50,7 @@ public:
this->Update = std::move(Update);
}
private:
- Constant *Addr;
+ TargetAddress Addr;
CompileFtor &Compile;
UpdateFtor &Update;
};
@@ -94,7 +95,7 @@ public:
}
/// @brief Get/create a compile callback with the given signature.
- virtual CompileCallbackInfo getCompileCallback(FunctionType &FT) = 0;
+ virtual CompileCallbackInfo getCompileCallback(LLVMContext &Context) = 0;
protected:
@@ -125,27 +126,23 @@ public:
/// there is no existing callback trampoline.
/// (Trampolines are allocated in blocks for
/// efficiency.)
- JITCompileCallbackManager(JITLayerT &JIT, LLVMContext &Context,
+ JITCompileCallbackManager(JITLayerT &JIT, RuntimeDyld::MemoryManager &MemMgr,
+ LLVMContext &Context,
TargetAddress ErrorHandlerAddress,
unsigned NumTrampolinesPerBlock)
: JITCompileCallbackManagerBase(ErrorHandlerAddress,
NumTrampolinesPerBlock),
- JIT(JIT) {
+ JIT(JIT), MemMgr(MemMgr) {
emitResolverBlock(Context);
}
/// @brief Get/create a compile callback with the given signature.
- CompileCallbackInfo getCompileCallback(FunctionType &FT) final {
- TargetAddress TrampolineAddr = getAvailableTrampolineAddr(FT.getContext());
+ CompileCallbackInfo getCompileCallback(LLVMContext &Context) final {
+ TargetAddress TrampolineAddr = getAvailableTrampolineAddr(Context);
auto &CallbackHandler =
this->ActiveTrampolines[TrampolineAddr];
- Constant *AddrIntVal =
- ConstantInt::get(Type::getInt64Ty(FT.getContext()), TrampolineAddr);
- Constant *AddrPtrVal =
- ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal,
- PointerType::get(&FT, 0));
- return CompileCallbackInfo(AddrPtrVal, CallbackHandler.Compile,
+ return CompileCallbackInfo(TrampolineAddr, CallbackHandler.Compile,
CallbackHandler.Update);
}
@@ -162,7 +159,9 @@ private:
std::unique_ptr<Module> M(new Module("resolver_block_module",
Context));
TargetT::insertResolverBlock(*M, *this);
- auto H = JIT.addModuleSet(SingletonSet(std::move(M)), nullptr);
+ auto H = JIT.addModuleSet(SingletonSet(std::move(M)), &MemMgr,
+ static_cast<RuntimeDyld::SymbolResolver*>(
+ nullptr));
JIT.emitAndFinalize(H);
auto ResolverBlockSymbol =
JIT.findSymbolIn(H, TargetT::ResolverBlockName, false);
@@ -187,7 +186,9 @@ private:
TargetT::insertCompileCallbackTrampolines(*M, ResolverBlockAddr,
this->NumTrampolinesPerBlock,
this->ActiveTrampolines.size());
- auto H = JIT.addModuleSet(SingletonSet(std::move(M)), nullptr);
+ auto H = JIT.addModuleSet(SingletonSet(std::move(M)), &MemMgr,
+ static_cast<RuntimeDyld::SymbolResolver*>(
+ nullptr));
JIT.emitAndFinalize(H);
for (unsigned I = 0; I < this->NumTrampolinesPerBlock; ++I) {
std::string Name = GetLabelName(I);
@@ -198,10 +199,11 @@ private:
}
JITLayerT &JIT;
+ RuntimeDyld::MemoryManager &MemMgr;
TargetAddress ResolverBlockAddr;
};
-/// @brief Get an update functor for updating the value of a named function
+/// @brief Get an update functor that updates the value of a named function
/// pointer.
template <typename JITLayerT>
JITCompileCallbackManagerBase::UpdateFtor
@@ -217,13 +219,26 @@ getLocalFPUpdater(JITLayerT &JIT, typename JITLayerT::ModuleSetHandleT H,
};
}
-GlobalVariable* createImplPointer(Function &F, const Twine &Name,
- Constant *Initializer);
+/// @brief Build a function pointer of FunctionType with the given constant
+/// address.
+///
+/// Usage example: Turn a trampoline address into a function pointer constant
+/// for use in a stub.
+Constant* createIRTypedAddress(FunctionType &FT, TargetAddress Addr);
+/// @brief Create a function pointer with the given type, name, and initializer
+/// in the given Module.
+GlobalVariable* createImplPointer(PointerType &PT, Module &M,
+ const Twine &Name, Constant *Initializer);
+
+/// @brief Turn a function declaration into a stub function that makes an
+/// indirect call using the given function pointer.
void makeStub(Function &F, GlobalVariable &ImplPointer);
typedef std::map<Module*, DenseSet<const GlobalValue*>> ModulePartitionMap;
+/// @brief Extract subsections of a Module into the given Module according to
+/// the given ModulePartitionMap.
void partition(Module &M, const ModulePartitionMap &PMap);
/// @brief Struct for trivial "complete" partitioning of a module.
@@ -239,6 +254,7 @@ public:
Functions(std::move(S.Functions)) {}
};
+/// @brief Extract every function in M into a separate module.
FullyPartitionedModule fullyPartition(Module &M);
} // End namespace orc.
diff --git a/include/llvm/ExecutionEngine/Orc/JITSymbol.h b/include/llvm/ExecutionEngine/Orc/JITSymbol.h
index 7c3ad56..422a376 100644
--- a/include/llvm/ExecutionEngine/Orc/JITSymbol.h
+++ b/include/llvm/ExecutionEngine/Orc/JITSymbol.h
@@ -27,7 +27,7 @@ typedef uint64_t TargetAddress;
/// @brief Represents a symbol in the JIT.
class JITSymbol : public JITSymbolBase {
-public:
+public:
typedef std::function<TargetAddress()> GetAddressFtor;
diff --git a/include/llvm/ExecutionEngine/Orc/LambdaResolver.h b/include/llvm/ExecutionEngine/Orc/LambdaResolver.h
new file mode 100644
index 0000000..faa2365
--- /dev/null
+++ b/include/llvm/ExecutionEngine/Orc/LambdaResolver.h
@@ -0,0 +1,62 @@
+//===-- LambdaResolverMM - Redirect symbol lookup via a functor -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a RuntimeDyld::SymbolResolver subclass that uses a user-supplied
+// functor for symbol resolution.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
+#define LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include <memory>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+template <typename ExternalLookupFtorT, typename DylibLookupFtorT>
+class LambdaResolver : public RuntimeDyld::SymbolResolver {
+public:
+
+ LambdaResolver(ExternalLookupFtorT ExternalLookupFtor,
+ DylibLookupFtorT DylibLookupFtor)
+ : ExternalLookupFtor(ExternalLookupFtor),
+ DylibLookupFtor(DylibLookupFtor) {}
+
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) final {
+ return ExternalLookupFtor(Name);
+ }
+
+ RuntimeDyld::SymbolInfo
+ findSymbolInLogicalDylib(const std::string &Name) final {
+ return DylibLookupFtor(Name);
+ }
+
+private:
+ ExternalLookupFtorT ExternalLookupFtor;
+ DylibLookupFtorT DylibLookupFtor;
+};
+
+template <typename ExternalLookupFtorT,
+ typename DylibLookupFtorT>
+std::unique_ptr<LambdaResolver<ExternalLookupFtorT, DylibLookupFtorT>>
+createLambdaResolver(ExternalLookupFtorT ExternalLookupFtor,
+ DylibLookupFtorT DylibLookupFtor) {
+ typedef LambdaResolver<ExternalLookupFtorT, DylibLookupFtorT> LR;
+ return make_unique<LR>(std::move(ExternalLookupFtor),
+ std::move(DylibLookupFtor));
+}
+
+} // End namespace orc.
+} // End namespace llvm.
+
+#endif // LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
index ac5fccf..71c83f7 100644
--- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
@@ -15,11 +15,11 @@
#define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
#include "JITSymbol.h"
-#include "LookasideRTDyldMM.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include <list>
@@ -94,10 +94,11 @@ private:
BaseLayer.emitAndFinalize(Handle);
}
- template <typename ModuleSetT>
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
static std::unique_ptr<EmissionDeferredSet>
- create(BaseLayerT &B, ModuleSetT Ms,
- std::unique_ptr<RTDyldMemoryManager> MM);
+ create(BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver);
protected:
virtual const GlobalValue* searchGVs(StringRef Name,
@@ -109,12 +110,15 @@ private:
BaseLayerHandleT Handle;
};
- template <typename ModuleSetT>
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
class EmissionDeferredSetImpl : public EmissionDeferredSet {
public:
EmissionDeferredSetImpl(ModuleSetT Ms,
- std::unique_ptr<RTDyldMemoryManager> MM)
- : Ms(std::move(Ms)), MM(std::move(MM)) {}
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver)
+ : Ms(std::move(Ms)), MemMgr(std::move(MemMgr)),
+ Resolver(std::move(Resolver)) {}
protected:
@@ -145,7 +149,8 @@ private:
// We don't need the mangled names set any more: Once we've emitted this
// to the base layer we'll just look for symbols there.
MangledSymbols.reset();
- return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
+ return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
+ std::move(Resolver));
}
private:
@@ -206,7 +211,8 @@ private:
}
ModuleSetT Ms;
- std::unique_ptr<RTDyldMemoryManager> MM;
+ MemoryManagerPtrT MemMgr;
+ SymbolResolverPtrT Resolver;
mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
};
@@ -223,12 +229,15 @@ public:
LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
/// @brief Add the given set of modules to the lazy emitting layer.
- template <typename ModuleSetT>
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- std::unique_ptr<RTDyldMemoryManager> MM) {
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
return ModuleSetList.insert(
ModuleSetList.end(),
- EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MM)));
+ EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MemMgr),
+ std::move(Resolver)));
}
/// @brief Remove the module set represented by the given handle.
@@ -277,12 +286,16 @@ public:
};
template <typename BaseLayerT>
-template <typename ModuleSetT>
+template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet>
LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet::create(
- BaseLayerT &B, ModuleSetT Ms, std::unique_ptr<RTDyldMemoryManager> MM) {
- return llvm::make_unique<EmissionDeferredSetImpl<ModuleSetT>>(std::move(Ms),
- std::move(MM));
+ BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
+ typedef EmissionDeferredSetImpl<ModuleSetT, MemoryManagerPtrT, SymbolResolverPtrT>
+ EDS;
+ return llvm::make_unique<EDS>(std::move(Ms), std::move(MemMgr),
+ std::move(Resolver));
}
} // End namespace orc.
diff --git a/include/llvm/ExecutionEngine/Orc/LookasideRTDyldMM.h b/include/llvm/ExecutionEngine/Orc/LookasideRTDyldMM.h
deleted file mode 100644
index 4456404..0000000
--- a/include/llvm/ExecutionEngine/Orc/LookasideRTDyldMM.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//===- LookasideRTDyldMM - Redirect symbol lookup via a functor -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines an adapter for RuntimeDyldMM that allows lookups for external
-// symbols to go via a functor.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_LOOKASIDERTDYLDMM_H
-#define LLVM_EXECUTIONENGINE_ORC_LOOKASIDERTDYLDMM_H
-
-#include "llvm/ADT/STLExtras.h"
-#include <memory>
-#include <vector>
-
-namespace llvm {
-namespace orc {
-
-/// @brief Defines an adapter for RuntimeDyldMM that allows lookups for external
-/// symbols to go via a functor, before falling back to the lookup logic
-/// provided by the underlying RuntimeDyldMM instance.
-///
-/// This class is useful for redirecting symbol lookup back to various layers
-/// of a JIT component stack, e.g. to enable lazy module emission.
-///
-template <typename BaseRTDyldMM, typename ExternalLookupFtor,
- typename DylibLookupFtor>
-class LookasideRTDyldMM : public BaseRTDyldMM {
-public:
- /// @brief Create a LookasideRTDyldMM intance.
- LookasideRTDyldMM(ExternalLookupFtor ExternalLookup,
- DylibLookupFtor DylibLookup)
- : ExternalLookup(std::move(ExternalLookup)),
- DylibLookup(std::move(DylibLookup)) {}
-
- /// @brief Look up the given symbol address, first via the functor this
- /// instance was created with, then (if the symbol isn't found)
- /// via the underlying RuntimeDyldMM.
- uint64_t getSymbolAddress(const std::string &Name) override {
- if (uint64_t Addr = ExternalLookup(Name))
- return Addr;
- return BaseRTDyldMM::getSymbolAddress(Name);
- }
-
- uint64_t getSymbolAddressInLogicalDylib(const std::string &Name) override {
- if (uint64_t Addr = DylibLookup(Name))
- return Addr;
- return BaseRTDyldMM::getSymbolAddressInLogicalDylib(Name);
- };
-
- /// @brief Get a reference to the ExternalLookup functor.
- ExternalLookupFtor &getExternalLookup() { return ExternalLookup; }
-
- /// @brief Get a const-reference to the ExternalLookup functor.
- const ExternalLookupFtor &getExternalLookup() const { return ExternalLookup; }
-
- /// @brief Get a reference to the DylibLookup functor.
- DylibLookupFtor &getDylibLookup() { return DylibLookup; }
-
- /// @brief Get a const-reference to the DylibLookup functor.
- const DylibLookupFtor &getDylibLookup() const { return DylibLookup; }
-
-private:
- ExternalLookupFtor ExternalLookup;
- DylibLookupFtor DylibLookup;
-};
-
-/// @brief Create a LookasideRTDyldMM from a base memory manager type, an
-/// external lookup functor, and a dylib lookup functor.
-template <typename BaseRTDyldMM, typename ExternalLookupFtor,
- typename DylibLookupFtor>
-std::unique_ptr<
- LookasideRTDyldMM<BaseRTDyldMM, ExternalLookupFtor, DylibLookupFtor>>
-createLookasideRTDyldMM(ExternalLookupFtor &&ExternalLookup,
- DylibLookupFtor &&DylibLookup) {
- typedef LookasideRTDyldMM<BaseRTDyldMM, ExternalLookupFtor, DylibLookupFtor>
- ThisLookasideMM;
- return llvm::make_unique<ThisLookasideMM>(
- std::forward<ExternalLookupFtor>(ExternalLookup),
- std::forward<DylibLookupFtor>(DylibLookup));
-}
-
-} // End namespace orc.
-} // End namespace llvm.
-
-#endif // LLVM_EXECUTIONENGINE_ORC_LOOKASIDERTDYLDMM_H
diff --git a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
index 9838991..f3094da 100644
--- a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
@@ -15,7 +15,7 @@
#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
#include "JITSymbol.h"
-#include "LookasideRTDyldMM.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include <list>
@@ -38,13 +38,12 @@ protected:
LinkedObjectSet(const LinkedObjectSet&) = delete;
void operator=(const LinkedObjectSet&) = delete;
public:
- LinkedObjectSet(std::unique_ptr<RTDyldMemoryManager> MM)
- : MM(std::move(MM)), RTDyld(llvm::make_unique<RuntimeDyld>(&*this->MM)),
+ LinkedObjectSet(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RTDyld(llvm::make_unique<RuntimeDyld>(MemMgr, Resolver)),
State(Raw) {}
- // MSVC 2012 cannot infer a move constructor, so write it out longhand.
- LinkedObjectSet(LinkedObjectSet &&O)
- : MM(std::move(O.MM)), RTDyld(std::move(O.RTDyld)), State(O.State) {}
+ virtual ~LinkedObjectSet() {}
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
addObject(const object::ObjectFile &Obj) {
@@ -57,14 +56,7 @@ protected:
bool NeedsFinalization() const { return (State == Raw); }
- void Finalize() {
- State = Finalizing;
- RTDyld->resolveRelocations();
- RTDyld->registerEHFrames();
- MM->finalizeMemory();
- OwnedBuffers.clear();
- State = Finalized;
- }
+ virtual void Finalize() = 0;
void mapSectionAddress(const void *LocalAddress, TargetAddress TargetAddr) {
assert((State != Finalized) &&
@@ -76,8 +68,7 @@ protected:
OwnedBuffers.push_back(std::move(B));
}
- private:
- std::unique_ptr<RTDyldMemoryManager> MM;
+ protected:
std::unique_ptr<RuntimeDyld> RTDyld;
enum { Raw, Finalizing, Finalized } State;
@@ -87,7 +78,7 @@ protected:
std::vector<std::unique_ptr<MemoryBuffer>> OwnedBuffers;
};
- typedef std::list<LinkedObjectSet> LinkedObjectSetListT;
+ typedef std::list<std::unique_ptr<LinkedObjectSet>> LinkedObjectSetListT;
public:
/// @brief Handle to a set of loaded objects.
@@ -99,7 +90,7 @@ public:
template <typename OwningMBSet>
void takeOwnershipOfBuffers(ObjSetHandleT H, OwningMBSet MBs) {
for (auto &MB : MBs)
- H->takeOwnershipOfBuffer(std::move(MB));
+ (*H)->takeOwnershipOfBuffer(std::move(MB));
}
};
@@ -120,6 +111,37 @@ public:
/// symbols.
template <typename NotifyLoadedFtor = DoNothingOnNotifyLoaded>
class ObjectLinkingLayer : public ObjectLinkingLayerBase {
+private:
+
+ template <typename MemoryManagerPtrT, typename SymbolResolverPtrT>
+ class ConcreteLinkedObjectSet : public LinkedObjectSet {
+ public:
+ ConcreteLinkedObjectSet(MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver)
+ : LinkedObjectSet(*MemMgr, *Resolver), MemMgr(std::move(MemMgr)),
+ Resolver(std::move(Resolver)) { }
+
+ void Finalize() override {
+ State = Finalizing;
+ RTDyld->resolveRelocations();
+ RTDyld->registerEHFrames();
+ MemMgr->finalizeMemory();
+ OwnedBuffers.clear();
+ State = Finalized;
+ }
+
+ private:
+ MemoryManagerPtrT MemMgr;
+ SymbolResolverPtrT Resolver;
+ };
+
+ template <typename MemoryManagerPtrT, typename SymbolResolverPtrT>
+ std::unique_ptr<LinkedObjectSet>
+ createLinkedObjectSet(MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver) {
+ typedef ConcreteLinkedObjectSet<MemoryManagerPtrT, SymbolResolverPtrT> LOS;
+ return llvm::make_unique<LOS>(std::move(MemMgr), std::move(Resolver));
+ }
+
public:
/// @brief LoadedObjectInfo list. Contains a list of owning pointers to
@@ -127,21 +149,16 @@ public:
typedef std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
LoadedObjInfoList;
- /// @brief Functor to create RTDyldMemoryManager instances.
- typedef std::function<std::unique_ptr<RTDyldMemoryManager>()> CreateRTDyldMMFtor;
-
/// @brief Functor for receiving finalization notifications.
typedef std::function<void(ObjSetHandleT)> NotifyFinalizedFtor;
/// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded,
- /// NotifyFinalized and CreateMemoryManager functors.
+ /// and NotifyFinalized functors.
ObjectLinkingLayer(
- CreateRTDyldMMFtor CreateMemoryManager = CreateRTDyldMMFtor(),
NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor())
: NotifyLoaded(std::move(NotifyLoaded)),
- NotifyFinalized(std::move(NotifyFinalized)),
- CreateMemoryManager(std::move(CreateMemoryManager)) {}
+ NotifyFinalized(std::move(NotifyFinalized)) {}
/// @brief Add a set of objects (or archives) that will be treated as a unit
/// for the purposes of symbol lookup and memory management.
@@ -154,19 +171,18 @@ public:
/// This version of this method allows the client to pass in an
/// RTDyldMemoryManager instance that will be used to allocate memory and look
/// up external symbol addresses for the given objects.
- template <typename ObjSetT>
+ template <typename ObjSetT,
+ typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
ObjSetHandleT addObjectSet(const ObjSetT &Objects,
- std::unique_ptr<RTDyldMemoryManager> MM) {
-
- if (!MM) {
- assert(CreateMemoryManager &&
- "No memory manager or memory manager creator provided.");
- MM = CreateMemoryManager();
- }
-
- ObjSetHandleT Handle = LinkedObjSetList.insert(
- LinkedObjSetList.end(), LinkedObjectSet(std::move(MM)));
- LinkedObjectSet &LOS = *Handle;
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
+ ObjSetHandleT Handle =
+ LinkedObjSetList.insert(
+ LinkedObjSetList.end(),
+ createLinkedObjectSet(std::move(MemMgr), std::move(Resolver)));
+
+ LinkedObjectSet &LOS = **Handle;
LoadedObjInfoList LoadedObjInfos;
for (auto &Obj : Objects)
@@ -212,11 +228,11 @@ public:
/// given object set.
JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
bool ExportedSymbolsOnly) {
- if (auto Sym = H->getSymbol(Name)) {
+ if (auto Sym = (*H)->getSymbol(Name)) {
if (Sym.isExported() || !ExportedSymbolsOnly) {
auto Addr = Sym.getAddress();
auto Flags = Sym.getFlags();
- if (!H->NeedsFinalization()) {
+ if (!(*H)->NeedsFinalization()) {
// If this instance has already been finalized then we can just return
// the address.
return JITSymbol(Addr, Flags);
@@ -225,10 +241,10 @@ public:
// it. The functor still needs to double-check whether finalization is
// required, in case someone else finalizes this set before the
// functor is called.
- auto GetAddress =
+ auto GetAddress =
[this, Addr, H]() {
- if (H->NeedsFinalization()) {
- H->Finalize();
+ if ((*H)->NeedsFinalization()) {
+ (*H)->Finalize();
if (NotifyFinalized)
NotifyFinalized(H);
}
@@ -244,14 +260,14 @@ public:
/// @brief Map section addresses for the objects associated with the handle H.
void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
TargetAddress TargetAddr) {
- H->mapSectionAddress(LocalAddress, TargetAddr);
+ (*H)->mapSectionAddress(LocalAddress, TargetAddr);
}
/// @brief Immediately emit and finalize the object set represented by the
/// given handle.
/// @param H Handle for object set to emit/finalize.
void emitAndFinalize(ObjSetHandleT H) {
- H->Finalize();
+ (*H)->Finalize();
if (NotifyFinalized)
NotifyFinalized(H);
}
@@ -260,7 +276,6 @@ private:
LinkedObjectSetListT LinkedObjSetList;
NotifyLoadedFtor NotifyLoaded;
NotifyFinalizedFtor NotifyFinalized;
- CreateRTDyldMMFtor CreateMemoryManager;
};
} // End namespace orc.
diff --git a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
index 792a499..207bad0 100644
--- a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
+++ b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
@@ -14,6 +14,7 @@
#ifndef LLVM_EXECUTIONENGINE_RTDYLDMEMORYMANAGER_H
#define LLVM_EXECUTIONENGINE_RTDYLDMEMORYMANAGER_H
+#include "RuntimeDyld.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CBindingWrapping.h"
@@ -27,89 +28,91 @@ class ExecutionEngine;
class ObjectFile;
}
+class MCJITMemoryManager : public RuntimeDyld::MemoryManager {
+public:
+ /// This method is called after an object has been loaded into memory but
+ /// before relocations are applied to the loaded sections. The object load
+ /// may have been initiated by MCJIT to resolve an external symbol for another
+ /// object that is being finalized. In that case, the object about which
+ /// the memory manager is being notified will be finalized immediately after
+ /// the memory manager returns from this call.
+ ///
+ /// Memory managers which are preparing code for execution in an external
+ /// address space can use this call to remap the section addresses for the
+ /// newly loaded object.
+ virtual void notifyObjectLoaded(ExecutionEngine *EE,
+ const object::ObjectFile &) {}
+};
+
// RuntimeDyld clients often want to handle the memory management of
// what gets placed where. For JIT clients, this is the subset of
// JITMemoryManager required for dynamic loading of binaries.
//
// FIXME: As the RuntimeDyld fills out, additional routines will be needed
// for the varying types of objects to be allocated.
-class RTDyldMemoryManager {
+class RTDyldMemoryManager : public MCJITMemoryManager,
+ public RuntimeDyld::SymbolResolver {
RTDyldMemoryManager(const RTDyldMemoryManager&) = delete;
void operator=(const RTDyldMemoryManager&) = delete;
public:
RTDyldMemoryManager() {}
- virtual ~RTDyldMemoryManager();
-
- /// Allocate a memory block of (at least) the given size suitable for
- /// executable code. The SectionID is a unique identifier assigned by the JIT
- /// engine, and optionally recorded by the memory manager to access a loaded
- /// section.
- virtual uint8_t *allocateCodeSection(
- uintptr_t Size, unsigned Alignment, unsigned SectionID,
- StringRef SectionName) = 0;
-
- /// Allocate a memory block of (at least) the given size suitable for data.
- /// The SectionID is a unique identifier assigned by the JIT engine, and
- /// optionally recorded by the memory manager to access a loaded section.
- virtual uint8_t *allocateDataSection(
- uintptr_t Size, unsigned Alignment, unsigned SectionID,
- StringRef SectionName, bool IsReadOnly) = 0;
-
- /// Inform the memory manager about the total amount of memory required to
- /// allocate all sections to be loaded:
- /// \p CodeSize - the total size of all code sections
- /// \p DataSizeRO - the total size of all read-only data sections
- /// \p DataSizeRW - the total size of all read-write data sections
- ///
- /// Note that by default the callback is disabled. To enable it
- /// redefine the method needsToReserveAllocationSpace to return true.
- virtual void reserveAllocationSpace(
- uintptr_t CodeSize, uintptr_t DataSizeRO, uintptr_t DataSizeRW) { }
-
- /// Override to return true to enable the reserveAllocationSpace callback.
- virtual bool needsToReserveAllocationSpace() { return false; }
-
- /// Register the EH frames with the runtime so that c++ exceptions work.
- ///
- /// \p Addr parameter provides the local address of the EH frame section
- /// data, while \p LoadAddr provides the address of the data in the target
- /// address space. If the section has not been remapped (which will usually
- /// be the case for local execution) these two values will be the same.
- virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size);
+ ~RTDyldMemoryManager() override;
- virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size);
+ void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
+ void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
/// This method returns the address of the specified function or variable in
/// the current process.
static uint64_t getSymbolAddressInProcess(const std::string &Name);
+ /// Legacy symbol lookup - DEPRECATED! Please override findSymbol instead.
+ ///
/// This method returns the address of the specified function or variable.
/// It is used to resolve symbols during module linking.
virtual uint64_t getSymbolAddress(const std::string &Name) {
return getSymbolAddressInProcess(Name);
}
- /// This method returns the address of the specified symbol if it exists
- /// within the logical dynamic library represented by this
- /// RTDyldMemoryManager. Unlike getSymbolAddress, queries through this
- /// interface should return addresses for hidden symbols.
+ /// This method returns a RuntimeDyld::SymbolInfo for the specified function
+ /// or variable. It is used to resolve symbols during module linking.
+ ///
+ /// By default this falls back on the legacy lookup method:
+ /// 'getSymbolAddress'. The address returned by getSymbolAddress is treated as
+ /// a strong, exported symbol, consistent with historical treatment by
+ /// RuntimeDyld.
///
- /// This is of particular importance for the Orc JIT APIs, which support lazy
- /// compilation by breaking up modules: Each of those broken out modules
- /// must be able to resolve hidden symbols provided by the others. Clients
- /// writing memory managers for MCJIT can usually ignore this method.
+ /// Clients writing custom RTDyldMemoryManagers are encouraged to override
+ /// this method and return a SymbolInfo with the flags set correctly. This is
+ /// necessary for RuntimeDyld to correctly handle weak and non-exported symbols.
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override {
+ return RuntimeDyld::SymbolInfo(getSymbolAddress(Name),
+ JITSymbolFlags::Exported);
+ }
+
+ /// Legacy symbol lookup -- DEPRECATED! Please override
+ /// findSymbolInLogicalDylib instead.
///
- /// This method will be queried by RuntimeDyld when checking for previous
- /// definitions of common symbols. It will *not* be queried by default when
- /// resolving external symbols (this minimises the link-time overhead for
- /// MCJIT clients who don't care about Orc features). If you are writing a
- /// RTDyldMemoryManager for Orc and want "external" symbol resolution to
- /// search the logical dylib, you should override your getSymbolAddress
- /// method call this method directly.
+ /// Default to treating all modules as separate.
virtual uint64_t getSymbolAddressInLogicalDylib(const std::string &Name) {
return 0;
}
+ /// Default to treating all modules as separate.
+ ///
+ /// By default this falls back on the legacy lookup method:
+ /// 'getSymbolAddressInLogicalDylib'. The address returned by
+ /// getSymbolAddressInLogicalDylib is treated as a strong, exported symbol,
+ /// consistent with historical treatment by RuntimeDyld.
+ ///
+ /// Clients writing custom RTDyldMemoryManagers are encouraged to override
+ /// this method and return a SymbolInfo with the flags set correctly. This is
+ /// necessary for RuntimeDyld to correctly handle weak and non-exported symbols.
+ RuntimeDyld::SymbolInfo
+ findSymbolInLogicalDylib(const std::string &Name) override {
+ return RuntimeDyld::SymbolInfo(getSymbolAddressInLogicalDylib(Name),
+ JITSymbolFlags::Exported);
+ }
+
/// This method returns the address of the specified function. As such it is
/// only useful for resolving library symbols, not code generated symbols.
///
@@ -121,30 +124,6 @@ public:
/// MCJIT or RuntimeDyld. Use getSymbolAddress instead.
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true);
-
- /// This method is called after an object has been loaded into memory but
- /// before relocations are applied to the loaded sections. The object load
- /// may have been initiated by MCJIT to resolve an external symbol for another
- /// object that is being finalized. In that case, the object about which
- /// the memory manager is being notified will be finalized immediately after
- /// the memory manager returns from this call.
- ///
- /// Memory managers which are preparing code for execution in an external
- /// address space can use this call to remap the section addresses for the
- /// newly loaded object.
- virtual void notifyObjectLoaded(ExecutionEngine *EE,
- const object::ObjectFile &) {}
-
- /// This method is called when object loading is complete and section page
- /// permissions can be applied. It is up to the memory manager implementation
- /// to decide whether or not to act on this method. The memory manager will
- /// typically allocate all sections as read-write and then apply specific
- /// permissions when this method is called. Code sections cannot be executed
- /// until this function has been called. In addition, any cache coherency
- /// operations needed to reliably use the memory are also performed.
- ///
- /// Returns true if an error occurred, false otherwise.
- virtual bool finalizeMemory(std::string *ErrMsg = nullptr) = 0;
};
// Create wrappers for C Binding types (see CBindingWrapping.h).
@@ -153,4 +132,5 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(
} // namespace llvm
+
#endif
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index fe0ccda..5723f05 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -16,7 +16,6 @@
#include "JITSymbolFlags.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/Support/Memory.h"
#include <memory>
@@ -29,19 +28,13 @@ namespace object {
class RuntimeDyldImpl;
class RuntimeDyldCheckerImpl;
-
+
class RuntimeDyld {
friend class RuntimeDyldCheckerImpl;
RuntimeDyld(const RuntimeDyld &) = delete;
void operator=(const RuntimeDyld &) = delete;
- // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
- // interface.
- std::unique_ptr<RuntimeDyldImpl> Dyld;
- RTDyldMemoryManager *MM;
- bool ProcessAllSections;
- RuntimeDyldCheckerImpl *Checker;
protected:
// Change the address associated with a section when resolving relocations.
// Any relocations already associated with the symbol will be re-resolved.
@@ -82,7 +75,101 @@ public:
unsigned BeginIdx, EndIdx;
};
- RuntimeDyld(RTDyldMemoryManager *);
+ /// \brief Memory Management.
+ class MemoryManager {
+ public:
+ virtual ~MemoryManager() {};
+
+ /// Allocate a memory block of (at least) the given size suitable for
+ /// executable code. The SectionID is a unique identifier assigned by the
+ /// RuntimeDyld instance, and optionally recorded by the memory manager to
+ /// access a loaded section.
+ virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName) = 0;
+
+ /// Allocate a memory block of (at least) the given size suitable for data.
+ /// The SectionID is a unique identifier assigned by the JIT engine, and
+ /// optionally recorded by the memory manager to access a loaded section.
+ virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName,
+ bool IsReadOnly) = 0;
+
+ /// Inform the memory manager about the total amount of memory required to
+ /// allocate all sections to be loaded:
+ /// \p CodeSize - the total size of all code sections
+ /// \p DataSizeRO - the total size of all read-only data sections
+ /// \p DataSizeRW - the total size of all read-write data sections
+ ///
+ /// Note that by default the callback is disabled. To enable it
+ /// redefine the method needsToReserveAllocationSpace to return true.
+ virtual void reserveAllocationSpace(uintptr_t CodeSize,
+ uintptr_t DataSizeRO,
+ uintptr_t DataSizeRW) {}
+
+ /// Override to return true to enable the reserveAllocationSpace callback.
+ virtual bool needsToReserveAllocationSpace() { return false; }
+
+ /// Register the EH frames with the runtime so that c++ exceptions work.
+ ///
+ /// \p Addr parameter provides the local address of the EH frame section
+ /// data, while \p LoadAddr provides the address of the data in the target
+ /// address space. If the section has not been remapped (which will usually
+ /// be the case for local execution) these two values will be the same.
+ virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
+ size_t Size) = 0;
+ virtual void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr,
+ size_t Size) = 0;
+
+ /// This method is called when object loading is complete and section page
+ /// permissions can be applied. It is up to the memory manager implementation
+ /// to decide whether or not to act on this method. The memory manager will
+ /// typically allocate all sections as read-write and then apply specific
+ /// permissions when this method is called. Code sections cannot be executed
+ /// until this function has been called. In addition, any cache coherency
+ /// operations needed to reliably use the memory are also performed.
+ ///
+ /// Returns true if an error occurred, false otherwise.
+ virtual bool finalizeMemory(std::string *ErrMsg = nullptr) = 0;
+
+ private:
+ virtual void anchor();
+ };
+
+ /// \brief Symbol resolution.
+ class SymbolResolver {
+ public:
+ virtual ~SymbolResolver() {};
+
+ /// This method returns the address of the specified function or variable.
+ /// It is used to resolve symbols during module linking.
+ virtual SymbolInfo findSymbol(const std::string &Name) = 0;
+
+ /// This method returns the address of the specified symbol if it exists
+ /// within the logical dynamic library represented by this
+ /// RTDyldMemoryManager. Unlike getSymbolAddress, queries through this
+ /// interface should return addresses for hidden symbols.
+ ///
+ /// This is of particular importance for the Orc JIT APIs, which support lazy
+ /// compilation by breaking up modules: Each of those broken out modules
+ /// must be able to resolve hidden symbols provided by the others. Clients
+ /// writing memory managers for MCJIT can usually ignore this method.
+ ///
+ /// This method will be queried by RuntimeDyld when checking for previous
+ /// definitions of common symbols. It will *not* be queried by default when
+ /// resolving external symbols (this minimises the link-time overhead for
+ /// MCJIT clients who don't care about Orc features). If you are writing a
+ /// RTDyldMemoryManager for Orc and want "external" symbol resolution to
+ /// search the logical dylib, you should override your getSymbolAddress
+ /// method call this method directly.
+ virtual SymbolInfo findSymbolInLogicalDylib(const std::string &Name) = 0;
+ private:
+ virtual void anchor();
+ };
+
+ /// \brief Construct a RuntimeDyld instance.
+ RuntimeDyld(MemoryManager &MemMgr, SymbolResolver &Resolver);
~RuntimeDyld();
/// Add the referenced object file to the list of objects to be loaded and
@@ -131,6 +218,15 @@ public:
assert(!Dyld && "setProcessAllSections must be called before loadObject.");
this->ProcessAllSections = ProcessAllSections;
}
+
+private:
+ // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
+ // interface.
+ std::unique_ptr<RuntimeDyldImpl> Dyld;
+ MemoryManager &MemMgr;
+ SymbolResolver &Resolver;
+ bool ProcessAllSections;
+ RuntimeDyldCheckerImpl *Checker;
};
} // end namespace llvm
diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h
index b825aff..0b0dcb0 100644
--- a/include/llvm/ExecutionEngine/SectionMemoryManager.h
+++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h
@@ -16,7 +16,7 @@
#define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Memory.h"
@@ -40,7 +40,7 @@ class SectionMemoryManager : public RTDyldMemoryManager {
public:
SectionMemoryManager() { }
- virtual ~SectionMemoryManager();
+ ~SectionMemoryManager() override;
/// \brief Allocates a memory block of (at least) the given size suitable for
/// executable code.
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index 443892b..d0d1b5e 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -89,6 +89,7 @@ public:
///< often, so lazy binding isn't worthwhile
NonNull, ///< Pointer is known to be not null
Dereferenceable, ///< Pointer is known to be dereferenceable
+ DereferenceableOrNull, ///< Pointer is either null or dereferenceable
NoRedZone, ///< Disable redzone
NoReturn, ///< Mark the function as not returning
NoUnwind, ///< Function doesn't unwind stack
@@ -136,6 +137,8 @@ public:
static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align);
static Attribute getWithDereferenceableBytes(LLVMContext &Context,
uint64_t Bytes);
+ static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context,
+ uint64_t Bytes);
//===--------------------------------------------------------------------===//
// Attribute Accessors
@@ -185,6 +188,10 @@ public:
/// dereferenceable attribute (or zero if unknown).
uint64_t getDereferenceableBytes() const;
+ /// \brief Returns the number of dereferenceable_or_null bytes from the
+ /// dereferenceable_or_null attribute (or zero if unknown).
+ uint64_t getDereferenceableOrNullBytes() const;
+
/// \brief The Attribute is converted to a string of equivalent mnemonic. This
/// is, presumably, for writing out the mnemonics for the assembly writer.
std::string getAsString(bool InAttrGrp = false) const;
@@ -287,6 +294,12 @@ public:
AttributeSet addDereferenceableAttr(LLVMContext &C, unsigned Index,
uint64_t Bytes) const;
+ /// \brief Add the dereferenceable_or_null attribute to the attribute set at
+ /// the given index. Since attribute sets are immutable, this returns a new
+ /// set.
+ AttributeSet addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
+ uint64_t Bytes) const;
+
//===--------------------------------------------------------------------===//
// AttributeSet Accessors
//===--------------------------------------------------------------------===//
@@ -331,6 +344,10 @@ public:
/// \brief Get the number of dereferenceable bytes (or zero if unknown).
uint64_t getDereferenceableBytes(unsigned Index) const;
+ /// \brief Get the number of dereferenceable_or_null bytes (or zero if
+ /// unknown).
+ uint64_t getDereferenceableOrNullBytes(unsigned Index) const;
+
/// \brief Return the attributes at the index as a string.
std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
@@ -411,6 +428,7 @@ class AttrBuilder {
uint64_t Alignment;
uint64_t StackAlignment;
uint64_t DerefBytes;
+ uint64_t DerefOrNullBytes;
public:
AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {}
explicit AttrBuilder(uint64_t Val)
@@ -476,6 +494,10 @@ public:
/// attribute exists (zero is returned otherwise).
uint64_t getDereferenceableBytes() const { return DerefBytes; }
+ /// \brief Retrieve the number of dereferenceable_or_null bytes, if the
+ /// dereferenceable_or_null attribute exists (zero is returned otherwise).
+ uint64_t getDereferenceableOrNullBytes() const { return DerefOrNullBytes; }
+
/// \brief This turns an int alignment (which must be a power of 2) into the
/// form used internally in Attribute.
AttrBuilder &addAlignmentAttr(unsigned Align);
@@ -488,6 +510,10 @@ public:
/// internally in Attribute.
AttrBuilder &addDereferenceableAttr(uint64_t Bytes);
+ /// \brief This turns the number of dereferenceable_or_null bytes into the
+ /// form used internally in Attribute.
+ AttrBuilder &addDereferenceableOrNullAttr(uint64_t Bytes);
+
/// \brief Return true if the builder contains no target-independent
/// attributes.
bool empty() const { return Attrs.none(); }
diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h
index 8f5cdeb..a71946e 100644
--- a/include/llvm/IR/BasicBlock.h
+++ b/include/llvm/IR/BasicBlock.h
@@ -28,33 +28,25 @@ class LandingPadInst;
class TerminatorInst;
class LLVMContext;
class BlockAddress;
+class Function;
-template<> struct ilist_traits<Instruction>
- : public SymbolTableListTraits<Instruction, BasicBlock> {
+// Traits for intrusive list of basic blocks...
+template<> struct ilist_traits<BasicBlock>
+ : public SymbolTableListTraits<BasicBlock, Function> {
- /// \brief Return a node that marks the end of a list.
- ///
- /// The sentinel is relative to this instance, so we use a non-static
- /// method.
- Instruction *createSentinel() const {
- // Since i(p)lists always publicly derive from their corresponding traits,
- // placing a data member in this class will augment the i(p)list. But since
- // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
- // there is a legal viable downcast from it to NodeTy. We use this trick to
- // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
- // sentinel. Dereferencing the sentinel is forbidden (save the
- // ilist_node<NodeTy>), so no one will ever notice the superposition.
- return static_cast<Instruction*>(&Sentinel);
- }
- static void destroySentinel(Instruction*) {}
+ BasicBlock *createSentinel() const;
+ static void destroySentinel(BasicBlock*) {}
+
+ BasicBlock *provideInitialHead() const { return createSentinel(); }
+ BasicBlock *ensureHead(BasicBlock*) const { return createSentinel(); }
+ static void noteHead(BasicBlock*, BasicBlock*) {}
- Instruction *provideInitialHead() const { return createSentinel(); }
- Instruction *ensureHead(Instruction*) const { return createSentinel(); }
- static void noteHead(Instruction*, Instruction*) {}
+ static ValueSymbolTable *getSymTab(Function *ItemParent);
private:
- mutable ilist_half_node<Instruction> Sentinel;
+ mutable ilist_half_node<BasicBlock> Sentinel;
};
+
/// \brief LLVM Basic Block Representation
///
/// This represents a single basic block in LLVM. A basic block is simply a
@@ -113,7 +105,7 @@ public:
BasicBlock *InsertBefore = nullptr) {
return new BasicBlock(Context, Name, Parent, InsertBefore);
}
- ~BasicBlock();
+ ~BasicBlock() override;
/// \brief Return the enclosing method, or null if none.
const Function *getParent() const { return Parent; }
@@ -176,7 +168,9 @@ public:
void removeFromParent();
/// \brief Unlink 'this' from the containing function and delete it.
- void eraseFromParent();
+ ///
+ // \returns an iterator pointing to the element after the erased one.
+ iplist<BasicBlock>::iterator eraseFromParent();
/// \brief Unlink this basic block from its current function and insert it
/// into the function that \p MovePos lives in, right before \p MovePos.
@@ -332,6 +326,12 @@ private:
}
};
+// createSentinel is used to get hold of the node that marks the end of the
+// list... (same trick used here as in ilist_traits<Instruction>)
+inline BasicBlock *ilist_traits<BasicBlock>::createSentinel() const {
+ return static_cast<BasicBlock*>(&Sentinel);
+}
+
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef)
diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h
index 9c87936..ebace33 100644
--- a/include/llvm/IR/CallSite.h
+++ b/include/llvm/IR/CallSite.h
@@ -46,12 +46,13 @@ template <typename FunTy = const Function,
class CallSiteBase {
protected:
PointerIntPair<InstrTy*, 1, bool> I;
-public:
+
CallSiteBase() : I(nullptr, false) {}
CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); }
CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); }
- CallSiteBase(ValTy *II) { *this = get(II); }
-protected:
+ explicit CallSiteBase(ValTy *II) { *this = get(II); }
+
+private:
/// CallSiteBase::get - This static method is sort of like a constructor. It
/// will create an appropriate call site for a Call or Invoke instruction, but
/// it can also create a null initialized CallSiteBase object for something
@@ -349,15 +350,13 @@ private:
class CallSite : public CallSiteBase<Function, Value, User, Instruction,
CallInst, InvokeInst, User::op_iterator> {
- typedef CallSiteBase<Function, Value, User, Instruction,
- CallInst, InvokeInst, User::op_iterator> Base;
public:
CallSite() {}
- CallSite(Base B) : Base(B) {}
- CallSite(Value* V) : Base(V) {}
- CallSite(CallInst *CI) : Base(CI) {}
- CallSite(InvokeInst *II) : Base(II) {}
- CallSite(Instruction *II) : Base(II) {}
+ CallSite(CallSiteBase B) : CallSiteBase(B) {}
+ CallSite(CallInst *CI) : CallSiteBase(CI) {}
+ CallSite(InvokeInst *II) : CallSiteBase(II) {}
+ explicit CallSite(Instruction *II) : CallSiteBase(II) {}
+ explicit CallSite(Value *V) : CallSiteBase(V) {}
bool operator==(const CallSite &CS) const { return I == CS.I; }
bool operator!=(const CallSite &CS) const { return I != CS.I; }
@@ -371,13 +370,13 @@ private:
/// ImmutableCallSite - establish a view to a call site for examination
class ImmutableCallSite : public CallSiteBase<> {
- typedef CallSiteBase<> Base;
public:
- ImmutableCallSite(const Value* V) : Base(V) {}
- ImmutableCallSite(const CallInst *CI) : Base(CI) {}
- ImmutableCallSite(const InvokeInst *II) : Base(II) {}
- ImmutableCallSite(const Instruction *II) : Base(II) {}
- ImmutableCallSite(CallSite CS) : Base(CS.getInstruction()) {}
+ ImmutableCallSite() {}
+ ImmutableCallSite(const CallInst *CI) : CallSiteBase(CI) {}
+ ImmutableCallSite(const InvokeInst *II) : CallSiteBase(II) {}
+ explicit ImmutableCallSite(const Instruction *II) : CallSiteBase(II) {}
+ explicit ImmutableCallSite(const Value *V) : CallSiteBase(V) {}
+ ImmutableCallSite(CallSite CS) : CallSiteBase(CS.getInstruction()) {}
};
} // End llvm namespace
diff --git a/include/llvm/IR/ConstantFolder.h b/include/llvm/IR/ConstantFolder.h
index e271a14..fb6ca3b 100644
--- a/include/llvm/IR/ConstantFolder.h
+++ b/include/llvm/IR/ConstantFolder.h
@@ -118,34 +118,35 @@ public:
// Memory Instructions
//===--------------------------------------------------------------------===//
- Constant *CreateGetElementPtr(Constant *C,
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getGetElementPtr(C, IdxList);
+ return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return ConstantExpr::getGetElementPtr(C, Idx);
+ return ConstantExpr::getGetElementPtr(Ty, C, Idx);
}
- Constant *CreateGetElementPtr(Constant *C,
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
- return ConstantExpr::getGetElementPtr(C, IdxList);
+ return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateInBoundsGetElementPtr(Constant *C,
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
+ Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
}
- Constant *CreateInBoundsGetElementPtr(Constant *C,
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
- return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h
index 59be653..70437e6 100644
--- a/include/llvm/IR/Constants.h
+++ b/include/llvm/IR/Constants.h
@@ -547,7 +547,7 @@ class ConstantDataSequential : public Constant {
protected:
explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
: Constant(ty, VT, nullptr, 0), DataElements(Data), Next(nullptr) {}
- ~ConstantDataSequential() { delete Next; }
+ ~ConstantDataSequential() override { delete Next; }
static Constant *getImpl(StringRef Bytes, Type *Ty);
@@ -1057,41 +1057,43 @@ public:
/// all elements must be Constant's.
///
/// \param OnlyIfReducedTy see \a getWithOperands() docs.
- static Constant *getGetElementPtr(Constant *C, ArrayRef<Constant *> IdxList,
+ static Constant *getGetElementPtr(Type *Ty, Constant *C,
+ ArrayRef<Constant *> IdxList,
bool InBounds = false,
Type *OnlyIfReducedTy = nullptr) {
return getGetElementPtr(
- C, makeArrayRef((Value * const *)IdxList.data(), IdxList.size()),
+ Ty, C, makeArrayRef((Value * const *)IdxList.data(), IdxList.size()),
InBounds, OnlyIfReducedTy);
}
- static Constant *getGetElementPtr(Constant *C, Constant *Idx,
+ static Constant *getGetElementPtr(Type *Ty, Constant *C, Constant *Idx,
bool InBounds = false,
Type *OnlyIfReducedTy = nullptr) {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return getGetElementPtr(C, cast<Value>(Idx), InBounds, OnlyIfReducedTy);
+ return getGetElementPtr(Ty, C, cast<Value>(Idx), InBounds, OnlyIfReducedTy);
}
- static Constant *getGetElementPtr(Constant *C, ArrayRef<Value *> IdxList,
+ static Constant *getGetElementPtr(Type *Ty, Constant *C,
+ ArrayRef<Value *> IdxList,
bool InBounds = false,
Type *OnlyIfReducedTy = nullptr);
/// Create an "inbounds" getelementptr. See the documentation for the
/// "inbounds" flag in LangRef.html for details.
- static Constant *getInBoundsGetElementPtr(Constant *C,
+ static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) {
- return getGetElementPtr(C, IdxList, true);
+ return getGetElementPtr(Ty, C, IdxList, true);
}
- static Constant *getInBoundsGetElementPtr(Constant *C,
+ static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return getGetElementPtr(C, Idx, true);
+ return getGetElementPtr(Ty, C, Idx, true);
}
- static Constant *getInBoundsGetElementPtr(Constant *C,
+ static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) {
- return getGetElementPtr(C, IdxList, true);
+ return getGetElementPtr(Ty, C, IdxList, true);
}
static Constant *getExtractElement(Constant *Vec, Constant *Idx,
diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h
index 97a7b83..db87654 100644
--- a/include/llvm/IR/DIBuilder.h
+++ b/include/llvm/IR/DIBuilder.h
@@ -30,38 +30,17 @@ namespace llvm {
class Value;
class Constant;
class LLVMContext;
- class MDNode;
class StringRef;
- class DIBasicType;
- class DICompileUnit;
- class DICompositeType;
- class DIDerivedType;
- class DIDescriptor;
- class DIFile;
- class DIEnumerator;
- class DIType;
- class DIGlobalVariable;
- class DIImportedEntity;
- class DINameSpace;
- class DIVariable;
- class DISubrange;
- class DILexicalBlockFile;
- class DILexicalBlock;
- class DIScope;
- class DISubprogram;
- class DITemplateTypeParameter;
- class DITemplateValueParameter;
- class DIObjCProperty;
class DIBuilder {
Module &M;
LLVMContext &VMContext;
- MDNode *TempEnumTypes;
- MDNode *TempRetainTypes;
- MDNode *TempSubprograms;
- MDNode *TempGVs;
- MDNode *TempImportedModules;
+ TempMDTuple TempEnumTypes;
+ TempMDTuple TempRetainTypes;
+ TempMDTuple TempSubprograms;
+ TempMDTuple TempGVs;
+ TempMDTuple TempImportedModules;
Function *DeclareFn; // llvm.dbg.declare
Function *ValueFn; // llvm.dbg.value
@@ -125,26 +104,25 @@ namespace llvm {
/// 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,
- bool EmitDebugInfo = true);
+ MDCompileUnit *createCompileUnit(unsigned Lang, StringRef File,
+ StringRef Dir, StringRef Producer,
+ bool isOptimized, StringRef Flags,
+ unsigned RV, StringRef SplitName = "",
+ DebugEmissionKind Kind = FullDebug,
+ bool EmitDebugInfo = true);
/// createFile - Create a file descriptor to hold debugging information
/// for a file.
- DIFile createFile(StringRef Filename, StringRef Directory);
+ MDFile *createFile(StringRef Filename, StringRef Directory);
/// createEnumerator - Create a single enumerator value.
- DIEnumerator createEnumerator(StringRef Name, int64_t Val);
+ MDEnumerator *createEnumerator(StringRef Name, int64_t Val);
/// \brief Create a DWARF unspecified type.
- DIBasicType createUnspecifiedType(StringRef Name);
+ MDBasicType *createUnspecifiedType(StringRef Name);
/// \brief Create C++11 nullptr type.
- DIBasicType createNullPtrType();
+ MDBasicType *createNullPtrType();
/// createBasicType - Create debugging information entry for a basic
/// type.
@@ -152,36 +130,36 @@ namespace llvm {
/// @param SizeInBits Size of the type.
/// @param AlignInBits Type alignment.
/// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
- DIBasicType createBasicType(StringRef Name, uint64_t SizeInBits,
- uint64_t AlignInBits, unsigned Encoding);
+ MDBasicType *createBasicType(StringRef Name, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Encoding);
/// createQualifiedType - Create debugging information entry for a qualified
/// type, e.g. 'const int'.
/// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
/// @param FromTy Base Type.
- DIDerivedType createQualifiedType(unsigned Tag, DIType FromTy);
+ MDDerivedType *createQualifiedType(unsigned Tag, MDType *FromTy);
/// createPointerType - Create debugging information entry for a pointer.
/// @param PointeeTy Type pointed by this pointer.
/// @param SizeInBits Size.
/// @param AlignInBits Alignment. (optional)
/// @param Name Pointer type name. (optional)
- DIDerivedType
- createPointerType(DIType PointeeTy, uint64_t SizeInBits,
- uint64_t AlignInBits = 0, StringRef Name = StringRef());
+ MDDerivedType *createPointerType(MDType *PointeeTy, uint64_t SizeInBits,
+ uint64_t AlignInBits = 0,
+ StringRef Name = "");
/// \brief Create debugging information entry for a pointer to member.
/// @param PointeeTy Type pointed to by this pointer.
/// @param SizeInBits Size.
/// @param AlignInBits Alignment. (optional)
/// @param Class Type for which this pointer points to members of.
- DIDerivedType createMemberPointerType(DIType PointeeTy, DIType Class,
- uint64_t SizeInBits,
- uint64_t AlignInBits = 0);
+ MDDerivedType *createMemberPointerType(MDType *PointeeTy, MDType *Class,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits = 0);
/// createReferenceType - Create debugging information entry for a c++
/// style reference or rvalue reference type.
- DIDerivedType createReferenceType(unsigned Tag, DIType RTy);
+ MDDerivedType *createReferenceType(unsigned Tag, MDType *RTy);
/// createTypedef - Create debugging information entry for a typedef.
/// @param Ty Original type.
@@ -189,11 +167,11 @@ namespace llvm {
/// @param File File where this type is defined.
/// @param LineNo Line number.
/// @param Context The surrounding context for the typedef.
- DIDerivedType createTypedef(DIType Ty, StringRef Name, DIFile File,
- unsigned LineNo, DIDescriptor Context);
+ MDDerivedType *createTypedef(MDType *Ty, StringRef Name, MDFile *File,
+ unsigned LineNo, MDScope *Context);
/// createFriend - Create debugging information entry for a 'friend'.
- DIDerivedType createFriend(DIType Ty, DIType FriendTy);
+ MDDerivedType *createFriend(MDType *Ty, MDType *FriendTy);
/// createInheritance - Create debugging information entry to establish
/// inheritance relationship between two types.
@@ -202,8 +180,8 @@ namespace llvm {
/// @param BaseOffset Base offset.
/// @param Flags Flags to describe inheritance attribute,
/// e.g. private
- DIDerivedType createInheritance(DIType Ty, DIType BaseTy,
- uint64_t BaseOffset, unsigned Flags);
+ MDDerivedType *createInheritance(MDType *Ty, MDType *BaseTy,
+ uint64_t BaseOffset, unsigned Flags);
/// createMemberType - Create debugging information entry for a member.
/// @param Scope Member scope.
@@ -215,10 +193,11 @@ namespace llvm {
/// @param OffsetInBits Member offset.
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Ty Parent type.
- DIDerivedType
- createMemberType(DIDescriptor Scope, StringRef Name, DIFile File,
- unsigned LineNo, uint64_t SizeInBits, uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags, DIType Ty);
+ MDDerivedType *createMemberType(MDScope *Scope, StringRef Name,
+ MDFile *File, unsigned LineNo,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ MDType *Ty);
/// createStaticMemberType - Create debugging information entry for a
/// C++ static data member.
@@ -229,10 +208,10 @@ namespace llvm {
/// @param Ty Type of the static member.
/// @param Flags Flags to encode member attribute, e.g. private.
/// @param Val Const initializer of the member.
- DIDerivedType createStaticMemberType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNo,
- DIType Ty, unsigned Flags,
- llvm::Constant *Val);
+ MDDerivedType *createStaticMemberType(MDScope *Scope, StringRef Name,
+ MDFile *File, unsigned LineNo,
+ MDType *Ty, unsigned Flags,
+ llvm::Constant *Val);
/// createObjCIVar - Create debugging information entry for Objective-C
/// instance variable.
@@ -245,11 +224,10 @@ namespace llvm {
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Ty Parent type.
/// @param PropertyNode Property associated with this ivar.
- DIDerivedType createObjCIVar(StringRef Name, DIFile File,
- unsigned LineNo, uint64_t SizeInBits,
- uint64_t AlignInBits, uint64_t OffsetInBits,
- unsigned Flags, DIType Ty,
- MDNode *PropertyNode);
+ MDDerivedType *createObjCIVar(StringRef Name, MDFile *File, unsigned LineNo,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ MDType *Ty, MDNode *PropertyNode);
/// createObjCProperty - Create debugging information entry for Objective-C
/// property.
@@ -260,12 +238,11 @@ namespace llvm {
/// @param SetterName Name of the Objective C property setter selector.
/// @param PropertyAttributes Objective C property attributes.
/// @param Ty Type.
- DIObjCProperty createObjCProperty(StringRef Name,
- DIFile File, unsigned LineNumber,
- StringRef GetterName,
- StringRef SetterName,
- unsigned PropertyAttributes,
- DIType Ty);
+ MDObjCProperty *createObjCProperty(StringRef Name, MDFile *File,
+ unsigned LineNumber,
+ StringRef GetterName,
+ StringRef SetterName,
+ unsigned PropertyAttributes, MDType *Ty);
/// createClassType - Create debugging information entry for a class.
/// @param Scope Scope in which this class is defined.
@@ -283,14 +260,14 @@ namespace llvm {
/// for more info.
/// @param TemplateParms Template type parameters.
/// @param UniqueIdentifier A unique identifier for the class.
- DICompositeType createClassType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- DIType DerivedFrom, DIArray Elements,
- DIType VTableHolder = DIType(),
- MDNode *TemplateParms = nullptr,
- StringRef UniqueIdentifier = StringRef());
+ MDCompositeType *createClassType(MDScope *Scope, StringRef Name,
+ MDFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ MDType *DerivedFrom, DIArray Elements,
+ MDType *VTableHolder = nullptr,
+ MDNode *TemplateParms = nullptr,
+ StringRef UniqueIdentifier = "");
/// createStructType - Create debugging information entry for a struct.
/// @param Scope Scope in which this struct is defined.
@@ -303,13 +280,11 @@ namespace llvm {
/// @param Elements Struct elements.
/// @param RunTimeLang Optional parameter, Objective-C runtime version.
/// @param UniqueIdentifier A unique identifier for the struct.
- DICompositeType createStructType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits,
- unsigned Flags, DIType DerivedFrom,
- DIArray Elements, unsigned RunTimeLang = 0,
- DIType VTableHolder = DIType(),
- StringRef UniqueIdentifier = StringRef());
+ MDCompositeType *createStructType(
+ MDScope *Scope, StringRef Name, MDFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
+ MDType *DerivedFrom, DIArray Elements, unsigned RunTimeLang = 0,
+ MDType *VTableHolder = nullptr, StringRef UniqueIdentifier = "");
/// createUnionType - Create debugging information entry for an union.
/// @param Scope Scope in which this union is defined.
@@ -322,19 +297,20 @@ namespace llvm {
/// @param Elements Union elements.
/// @param RunTimeLang Optional parameter, Objective-C runtime version.
/// @param UniqueIdentifier A unique identifier for the union.
- DICompositeType createUnionType(
- DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
- DIArray Elements, unsigned RunTimeLang = 0,
- StringRef UniqueIdentifier = StringRef());
+ MDCompositeType *createUnionType(MDScope *Scope, StringRef Name,
+ MDFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ unsigned Flags, DIArray Elements,
+ unsigned RunTimeLang = 0,
+ StringRef UniqueIdentifier = "");
/// createTemplateTypeParameter - Create debugging information for template
/// type parameter.
/// @param Scope Scope in which this type is defined.
/// @param Name Type parameter name.
/// @param Ty Parameter type.
- DITemplateTypeParameter
- createTemplateTypeParameter(DIDescriptor Scope, StringRef Name, DIType Ty);
+ MDTemplateTypeParameter *
+ createTemplateTypeParameter(MDScope *Scope, StringRef Name, MDType *Ty);
/// createTemplateValueParameter - Create debugging information for template
/// value parameter.
@@ -342,46 +318,46 @@ namespace llvm {
/// @param Name Value parameter name.
/// @param Ty Parameter type.
/// @param Val Constant parameter value.
- DITemplateValueParameter createTemplateValueParameter(DIDescriptor Scope,
- StringRef Name,
- DIType Ty,
- Constant *Val);
+ MDTemplateValueParameter *createTemplateValueParameter(MDScope *Scope,
+ StringRef Name,
+ MDType *Ty,
+ Constant *Val);
/// \brief Create debugging information for a template template parameter.
/// @param Scope Scope in which this type is defined.
/// @param Name Value parameter name.
/// @param Ty Parameter type.
/// @param Val The fully qualified name of the template.
- DITemplateValueParameter createTemplateTemplateParameter(DIDescriptor Scope,
- StringRef Name,
- DIType Ty,
- StringRef Val);
+ MDTemplateValueParameter *createTemplateTemplateParameter(MDScope *Scope,
+ StringRef Name,
+ MDType *Ty,
+ StringRef Val);
/// \brief Create debugging information for a template parameter pack.
/// @param Scope Scope in which this type is defined.
/// @param Name Value parameter name.
/// @param Ty Parameter type.
/// @param Val An array of types in the pack.
- DITemplateValueParameter createTemplateParameterPack(DIDescriptor Scope,
- StringRef Name,
- DIType Ty,
- DIArray Val);
+ MDTemplateValueParameter *createTemplateParameterPack(MDScope *Scope,
+ StringRef Name,
+ MDType *Ty,
+ DIArray Val);
/// createArrayType - Create debugging information entry for an array.
/// @param Size Array size.
/// @param AlignInBits Alignment.
/// @param Ty Element type.
/// @param Subscripts Subscripts.
- DICompositeType createArrayType(uint64_t Size, uint64_t AlignInBits,
- DIType Ty, DIArray Subscripts);
+ MDCompositeType *createArrayType(uint64_t Size, uint64_t AlignInBits,
+ MDType *Ty, DIArray Subscripts);
/// createVectorType - Create debugging information entry for a vector type.
/// @param Size Array size.
/// @param AlignInBits Alignment.
/// @param Ty Element type.
/// @param Subscripts Subscripts.
- DICompositeType createVectorType(uint64_t Size, uint64_t AlignInBits,
- DIType Ty, DIArray Subscripts);
+ MDCompositeType *createVectorType(uint64_t Size, uint64_t AlignInBits,
+ MDType *Ty, DIArray Subscripts);
/// createEnumerationType - Create debugging information entry for an
/// enumeration.
@@ -394,10 +370,10 @@ namespace llvm {
/// @param Elements Enumeration elements.
/// @param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
/// @param UniqueIdentifier A unique identifier for the enum.
- DICompositeType createEnumerationType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNumber, uint64_t SizeInBits,
- uint64_t AlignInBits, DIArray Elements, DIType UnderlyingType,
- StringRef UniqueIdentifier = StringRef());
+ MDCompositeType *createEnumerationType(
+ MDScope *Scope, StringRef Name, MDFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements,
+ MDType *UnderlyingType, StringRef UniqueIdentifier = "");
/// createSubroutineType - Create subroutine type.
/// @param File File in which this subroutine is defined.
@@ -405,39 +381,39 @@ namespace llvm {
/// includes return type at 0th index.
/// @param Flags E.g.: LValueReference.
/// These flags are used to emit dwarf attributes.
- DISubroutineType createSubroutineType(DIFile File,
- DITypeArray ParameterTypes,
- unsigned Flags = 0);
+ MDSubroutineType *createSubroutineType(MDFile *File,
+ DITypeArray ParameterTypes,
+ unsigned Flags = 0);
- /// createArtificialType - Create a new DIType with "artificial" flag set.
- DIType createArtificialType(DIType Ty);
+ /// createArtificialType - Create a new MDType* with "artificial" flag set.
+ MDType *createArtificialType(MDType *Ty);
- /// createObjectPointerType - Create a new DIType with the "object pointer"
+ /// createObjectPointerType - Create a new MDType* with the "object pointer"
/// flag set.
- DIType createObjectPointerType(DIType Ty);
+ MDType *createObjectPointerType(MDType *Ty);
/// \brief Create a permanent forward-declared type.
- DICompositeType createForwardDecl(unsigned Tag, StringRef Name,
- DIDescriptor Scope, DIFile F,
- unsigned Line, unsigned RuntimeLang = 0,
- uint64_t SizeInBits = 0,
- uint64_t AlignInBits = 0,
- StringRef UniqueIdentifier = StringRef());
+ MDCompositeType *createForwardDecl(unsigned Tag, StringRef Name,
+ MDScope *Scope, MDFile *F, unsigned Line,
+ unsigned RuntimeLang = 0,
+ uint64_t SizeInBits = 0,
+ uint64_t AlignInBits = 0,
+ StringRef UniqueIdentifier = "");
/// \brief Create a temporary forward-declared type.
- DICompositeType createReplaceableCompositeType(
- unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F,
- unsigned Line, unsigned RuntimeLang = 0, uint64_t SizeInBits = 0,
- uint64_t AlignInBits = 0, unsigned Flags = DIDescriptor::FlagFwdDecl,
- StringRef UniqueIdentifier = StringRef());
+ MDCompositeType *createReplaceableCompositeType(
+ unsigned Tag, StringRef Name, MDScope *Scope, MDFile *F, unsigned Line,
+ unsigned RuntimeLang = 0, uint64_t SizeInBits = 0,
+ uint64_t AlignInBits = 0, unsigned Flags = DebugNode::FlagFwdDecl,
+ StringRef UniqueIdentifier = "");
- /// retainType - Retain DIType in a module even if it is not referenced
+ /// retainType - Retain MDType* in a module even if it is not referenced
/// through debug info anchors.
- void retainType(DIType T);
+ void retainType(MDType *T);
/// createUnspecifiedParameter - Create unspecified parameter type
/// for a subroutine type.
- DIBasicType createUnspecifiedParameter();
+ MDBasicType *createUnspecifiedParameter();
/// getOrCreateArray - Get a DIArray, create one if required.
DIArray getOrCreateArray(ArrayRef<Metadata *> Elements);
@@ -447,8 +423,7 @@ namespace llvm {
/// getOrCreateSubrange - Create a descriptor for a value range. This
/// implicitly uniques the values returned.
- DISubrange getOrCreateSubrange(int64_t Lo, int64_t Count);
-
+ MDSubrange *getOrCreateSubrange(int64_t Lo, int64_t Count);
/// createGlobalVariable - Create a new descriptor for the specified
/// variable.
@@ -462,19 +437,19 @@ namespace llvm {
/// externally visible or not.
/// @param Val llvm::Value of the variable.
/// @param Decl Reference to the corresponding declaration.
- DIGlobalVariable createGlobalVariable(DIDescriptor Context, StringRef Name,
- StringRef LinkageName, DIFile File,
- unsigned LineNo, DITypeRef Ty,
- bool isLocalToUnit,
- llvm::Constant *Val,
- MDNode *Decl = nullptr);
+ MDGlobalVariable *createGlobalVariable(MDScope *Context, StringRef Name,
+ StringRef LinkageName, MDFile *File,
+ unsigned LineNo, MDType *Ty,
+ bool isLocalToUnit,
+ llvm::Constant *Val,
+ MDNode *Decl = nullptr);
/// createTempGlobalVariableFwdDecl - Identical to createGlobalVariable
/// except that the resulting DbgNode is temporary and meant to be RAUWed.
- DIGlobalVariable createTempGlobalVariableFwdDecl(
- DIDescriptor Context, StringRef Name, StringRef LinkageName,
- DIFile File, unsigned LineNo, DITypeRef Ty, bool isLocalToUnit,
- llvm::Constant *Val, MDNode *Decl = nullptr);
+ MDGlobalVariable *createTempGlobalVariableFwdDecl(
+ MDScope *Context, StringRef Name, StringRef LinkageName, MDFile *File,
+ unsigned LineNo, MDType *Ty, bool isLocalToUnit, llvm::Constant *Val,
+ MDNode *Decl = nullptr);
/// createLocalVariable - Create a new descriptor for the specified
/// local variable.
@@ -490,29 +465,29 @@ namespace llvm {
/// @param Flags Flags, e.g. artificial variable.
/// @param ArgNo If this variable is an argument then this argument's
/// number. 1 indicates 1st argument.
- DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope,
- StringRef Name,
- DIFile File, unsigned LineNo,
- DITypeRef Ty, bool AlwaysPreserve = false,
- unsigned Flags = 0,
- unsigned ArgNo = 0);
+ MDLocalVariable *createLocalVariable(unsigned Tag, MDScope *Scope,
+ StringRef Name, MDFile *File,
+ unsigned LineNo, MDType *Ty,
+ bool AlwaysPreserve = false,
+ unsigned Flags = 0,
+ unsigned ArgNo = 0);
/// createExpression - Create a new descriptor for the specified
/// variable which has a complex address expression for its address.
/// @param Addr An array of complex address operations.
- DIExpression createExpression(ArrayRef<uint64_t> Addr = None);
- DIExpression createExpression(ArrayRef<int64_t> Addr);
+ MDExpression *createExpression(ArrayRef<uint64_t> Addr = None);
+ MDExpression *createExpression(ArrayRef<int64_t> Addr);
/// createBitPieceExpression - Create a descriptor to describe one part
/// of aggregate variable that is fragmented across multiple Values.
///
/// @param OffsetInBits Offset of the piece in bits.
/// @param SizeInBits Size of the piece in bits.
- DIExpression createBitPieceExpression(unsigned OffsetInBits,
- unsigned SizeInBits);
+ MDExpression *createBitPieceExpression(unsigned OffsetInBits,
+ unsigned SizeInBits);
/// createFunction - Create a new descriptor for the specified subprogram.
- /// See comments in DISubprogram for descriptions of these fields.
+ /// See comments in MDSubprogram* for descriptions of these fields.
/// @param Scope Function scope.
/// @param Name Function name.
/// @param LinkageName Mangled function name.
@@ -527,49 +502,35 @@ namespace llvm {
/// @param isOptimized True if optimization is ON.
/// @param Fn llvm::Function pointer.
/// @param TParam Function template parameters.
- DISubprogram createFunction(DIDescriptor Scope, StringRef Name,
- StringRef LinkageName,
- DIFile File, unsigned LineNo,
- DICompositeType Ty, bool isLocalToUnit,
- bool isDefinition,
- unsigned ScopeLine,
- unsigned Flags = 0,
- bool isOptimized = false,
- Function *Fn = nullptr,
- MDNode *TParam = nullptr,
- MDNode *Decl = nullptr);
+ MDSubprogram *
+ createFunction(MDScope *Scope, StringRef Name, StringRef LinkageName,
+ MDFile *File, unsigned LineNo, MDSubroutineType *Ty,
+ bool isLocalToUnit, bool isDefinition, unsigned ScopeLine,
+ unsigned Flags = 0, bool isOptimized = false,
+ Function *Fn = nullptr, MDNode *TParam = nullptr,
+ MDNode *Decl = nullptr);
/// createTempFunctionFwdDecl - Identical to createFunction,
/// except that the resulting DbgNode is meant to be RAUWed.
- DISubprogram createTempFunctionFwdDecl(DIDescriptor Scope, StringRef Name,
- StringRef LinkageName,
- DIFile File, unsigned LineNo,
- DICompositeType Ty, bool isLocalToUnit,
- bool isDefinition,
- unsigned ScopeLine,
- unsigned Flags = 0,
- bool isOptimized = false,
- Function *Fn = nullptr,
- MDNode *TParam = nullptr,
- MDNode *Decl = nullptr);
-
+ MDSubprogram *createTempFunctionFwdDecl(
+ MDScope *Scope, StringRef Name, StringRef LinkageName, MDFile *File,
+ unsigned LineNo, MDSubroutineType *Ty, bool isLocalToUnit,
+ bool isDefinition, unsigned ScopeLine, unsigned Flags = 0,
+ bool isOptimized = false, Function *Fn = nullptr,
+ MDNode *TParam = nullptr, MDNode *Decl = nullptr);
/// FIXME: this is added for dragonegg. Once we update dragonegg
/// to call resolve function, this will be removed.
- DISubprogram createFunction(DIScopeRef Scope, StringRef Name,
- StringRef LinkageName,
- DIFile File, unsigned LineNo,
- DICompositeType Ty, bool isLocalToUnit,
- bool isDefinition,
- unsigned ScopeLine,
- unsigned Flags = 0,
- bool isOptimized = false,
- Function *Fn = nullptr,
- MDNode *TParam = nullptr,
- MDNode *Decl = nullptr);
+ MDSubprogram *
+ createFunction(DIScopeRef Scope, StringRef Name, StringRef LinkageName,
+ MDFile *File, unsigned LineNo, MDSubroutineType *Ty,
+ bool isLocalToUnit, bool isDefinition, unsigned ScopeLine,
+ unsigned Flags = 0, bool isOptimized = false,
+ Function *Fn = nullptr, MDNode *TParam = nullptr,
+ MDNode *Decl = nullptr);
/// createMethod - Create a new descriptor for the specified C++ method.
- /// See comments in DISubprogram for descriptions of these fields.
+ /// See comments in MDSubprogram* for descriptions of these fields.
/// @param Scope Function scope.
/// @param Name Function name.
/// @param LinkageName Mangled function name.
@@ -587,17 +548,13 @@ namespace llvm {
/// @param isOptimized True if optimization is ON.
/// @param Fn llvm::Function pointer.
/// @param TParam Function template parameters.
- DISubprogram createMethod(DIDescriptor Scope, StringRef Name,
- StringRef LinkageName,
- DIFile File, unsigned LineNo,
- DICompositeType Ty, bool isLocalToUnit,
- bool isDefinition,
- unsigned Virtuality = 0, unsigned VTableIndex = 0,
- DIType VTableHolder = DIType(),
- unsigned Flags = 0,
- bool isOptimized = false,
- Function *Fn = nullptr,
- MDNode *TParam = nullptr);
+ MDSubprogram *
+ createMethod(MDScope *Scope, StringRef Name, StringRef LinkageName,
+ MDFile *File, unsigned LineNo, MDSubroutineType *Ty,
+ bool isLocalToUnit, bool isDefinition, unsigned Virtuality = 0,
+ unsigned VTableIndex = 0, MDType *VTableHolder = nullptr,
+ unsigned Flags = 0, bool isOptimized = false,
+ Function *Fn = nullptr, MDNode *TParam = nullptr);
/// createNameSpace - This creates new descriptor for a namespace
/// with the specified parent scope.
@@ -605,9 +562,8 @@ namespace llvm {
/// @param Name Name of this namespace
/// @param File Source file
/// @param LineNo Line number
- DINameSpace createNameSpace(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNo);
-
+ MDNamespace *createNameSpace(MDScope *Scope, StringRef Name, MDFile *File,
+ unsigned LineNo);
/// createLexicalBlockFile - This creates a descriptor for a lexical
/// block with a new file attached. This merely extends the existing
@@ -615,8 +571,8 @@ namespace llvm {
/// @param Scope Lexical block.
/// @param File Source file.
/// @param Discriminator DWARF path discriminator value.
- DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope, DIFile File,
- unsigned Discriminator = 0);
+ MDLexicalBlockFile *createLexicalBlockFile(MDScope *Scope, MDFile *File,
+ unsigned Discriminator = 0);
/// createLexicalBlock - This creates a descriptor for a lexical block
/// with the specified parent context.
@@ -624,60 +580,63 @@ namespace llvm {
/// @param File Source file.
/// @param Line Line number.
/// @param Col Column number.
- DILexicalBlock createLexicalBlock(DIDescriptor Scope, DIFile File,
- unsigned Line, unsigned Col);
+ MDLexicalBlock *createLexicalBlock(MDScope *Scope, MDFile *File,
+ unsigned Line, unsigned Col);
/// \brief Create a descriptor for an imported module.
/// @param Context The scope this module is imported into
/// @param NS The namespace being imported here
/// @param Line Line number
- DIImportedEntity createImportedModule(DIScope Context, DINameSpace NS,
- unsigned Line);
+ MDImportedEntity *createImportedModule(MDScope *Context, MDNamespace *NS,
+ unsigned Line);
/// \brief Create a descriptor for an imported module.
/// @param Context The scope this module is imported into
/// @param NS An aliased namespace
/// @param Line Line number
- DIImportedEntity createImportedModule(DIScope Context, DIImportedEntity NS,
- unsigned Line);
+ MDImportedEntity *createImportedModule(MDScope *Context,
+ MDImportedEntity *NS, unsigned Line);
/// \brief Create a descriptor for an imported function.
/// @param Context The scope this module is imported into
/// @param Decl The declaration (or definition) of a function, type, or
/// variable
/// @param Line Line number
- DIImportedEntity createImportedDeclaration(DIScope Context, DIDescriptor Decl,
- unsigned Line,
- StringRef Name = StringRef());
- DIImportedEntity createImportedDeclaration(DIScope Context,
- DIImportedEntity NS,
- unsigned Line,
- StringRef Name = StringRef());
+ MDImportedEntity *createImportedDeclaration(MDScope *Context,
+ DebugNode *Decl, unsigned Line,
+ StringRef Name = "");
/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
/// @param Storage llvm::Value of the variable
/// @param VarInfo Variable's debug info descriptor.
/// @param Expr A complex location expression.
+ /// @param DL Debug info location.
/// @param InsertAtEnd Location for the new intrinsic.
- Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo,
- DIExpression Expr, BasicBlock *InsertAtEnd);
+ Instruction *insertDeclare(llvm::Value *Storage, MDLocalVariable *VarInfo,
+ MDExpression *Expr, const MDLocation *DL,
+ BasicBlock *InsertAtEnd);
/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
/// @param Storage llvm::Value of the variable
/// @param VarInfo Variable's debug info descriptor.
/// @param Expr A complex location expression.
+ /// @param DL Debug info location.
/// @param InsertBefore Location for the new intrinsic.
- Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo,
- DIExpression Expr, Instruction *InsertBefore);
+ Instruction *insertDeclare(llvm::Value *Storage, MDLocalVariable *VarInfo,
+ MDExpression *Expr, const MDLocation *DL,
+ Instruction *InsertBefore);
/// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
/// @param Val llvm::Value of the variable
/// @param Offset Offset
/// @param VarInfo Variable's debug info descriptor.
/// @param Expr A complex location expression.
+ /// @param DL Debug info location.
/// @param InsertAtEnd Location for the new intrinsic.
Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
- DIVariable VarInfo, DIExpression Expr,
+ MDLocalVariable *VarInfo,
+ MDExpression *Expr,
+ const MDLocation *DL,
BasicBlock *InsertAtEnd);
/// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
@@ -685,24 +644,45 @@ namespace llvm {
/// @param Offset Offset
/// @param VarInfo Variable's debug info descriptor.
/// @param Expr A complex location expression.
+ /// @param DL Debug info location.
/// @param InsertBefore Location for the new intrinsic.
Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
- DIVariable VarInfo, DIExpression Expr,
+ MDLocalVariable *VarInfo,
+ MDExpression *Expr,
+ const MDLocation *DL,
Instruction *InsertBefore);
/// \brief Replace the vtable holder in the given composite type.
///
/// If this creates a self reference, it may orphan some unresolved cycles
/// in the operands of \c T, so \a DIBuilder needs to track that.
- void replaceVTableHolder(DICompositeType &T, DICompositeType VTableHolder);
+ void replaceVTableHolder(MDCompositeType *&T,
+ MDCompositeType *VTableHolder);
/// \brief Replace arrays on a composite type.
///
/// If \c T is resolved, but the arrays aren't -- which can happen if \c T
/// has a self-reference -- \a DIBuilder needs to track the array to
/// resolve cycles.
- void replaceArrays(DICompositeType &T, DIArray Elements,
+ void replaceArrays(MDCompositeType *&T, DIArray Elements,
DIArray TParems = DIArray());
+
+ /// \brief Replace a temporary node.
+ ///
+ /// Call \a MDNode::replaceAllUsesWith() on \c N, replacing it with \c
+ /// Replacement.
+ ///
+ /// If \c Replacement is the same as \c N.get(), instead call \a
+ /// MDNode::replaceWithUniqued(). In this case, the uniqued node could
+ /// have a different address, so we return the final address.
+ template <class NodeTy>
+ NodeTy *replaceTemporary(TempMDNode &&N, NodeTy *Replacement) {
+ if (N.get() == Replacement)
+ return cast<NodeTy>(MDNode::replaceWithUniqued(std::move(N)));
+
+ N->replaceAllUsesWith(Replacement);
+ return Replacement;
+ }
};
} // end namespace llvm
diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h
index 0163c05..18b0c72 100644
--- a/include/llvm/IR/DebugInfo.h
+++ b/include/llvm/IR/DebugInfo.h
@@ -58,1292 +58,365 @@ class DIObjCProperty;
/// \brief Maps from type identifier to the actual MDNode.
typedef DenseMap<const MDString *, MDNode *> DITypeIdentifierMap;
-class DIHeaderFieldIterator
- : public std::iterator<std::input_iterator_tag, StringRef, std::ptrdiff_t,
- const StringRef *, StringRef> {
- StringRef Header;
- StringRef Current;
+class DIDescriptor {
+ MDNode *N;
public:
- DIHeaderFieldIterator() {}
- explicit DIHeaderFieldIterator(StringRef Header)
- : Header(Header), Current(Header.slice(0, Header.find('\0'))) {}
- StringRef operator*() const { return Current; }
- const StringRef *operator->() const { return &Current; }
- DIHeaderFieldIterator &operator++() {
- increment();
- return *this;
- }
- DIHeaderFieldIterator operator++(int) {
- DIHeaderFieldIterator X(*this);
- increment();
- return X;
- }
- bool operator==(const DIHeaderFieldIterator &X) const {
- return Current.data() == X.Current.data();
- }
- bool operator!=(const DIHeaderFieldIterator &X) const {
- return !(*this == X);
- }
+ DIDescriptor(const MDNode *N = nullptr) : N(const_cast<MDNode *>(N)) {}
- StringRef getHeader() const { return Header; }
- StringRef getCurrent() const { return Current; }
- StringRef getPrefix() const {
- if (Current.begin() == Header.begin())
- return StringRef();
- return Header.slice(0, Current.begin() - Header.begin() - 1);
- }
- StringRef getSuffix() const {
- if (Current.end() == Header.end())
- return StringRef();
- return Header.slice(Current.end() - Header.begin() + 1, StringRef::npos);
- }
-
- /// \brief Get the current field as a number.
- ///
- /// Convert the current field into a number. Return \c 0 on error.
- template <class T> T getNumber() const {
- T Int;
- if (getCurrent().getAsInteger(0, Int))
- return 0;
- return Int;
- }
-
-private:
- void increment() {
- assert(Current.data() != nullptr && "Cannot increment past the end");
- StringRef Suffix = getSuffix();
- Current = Suffix.slice(0, Suffix.find('\0'));
- }
+ operator MDNode *() const { return N; }
+ MDNode *operator->() const { return N; }
+ MDNode &operator*() const { return *N; }
};
-/// \brief A thin wraper around MDNode to access encoded debug info.
-///
-/// This should not be stored in a container, because the underlying MDNode may
-/// change in certain situations.
-class DIDescriptor {
- // Befriends DIRef so DIRef can befriend the protected member
- // function: getFieldAs<DIRef>.
- template <typename T> friend class DIRef;
+#define DECLARE_SIMPLIFY_DESCRIPTOR(DESC) \
+ class DESC; \
+ template <> struct simplify_type<const DESC>; \
+ template <> struct simplify_type<DESC>;
+DECLARE_SIMPLIFY_DESCRIPTOR(DIDescriptor)
+DECLARE_SIMPLIFY_DESCRIPTOR(DISubrange)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIEnumerator)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIScope)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIType)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIBasicType)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIDerivedType)
+DECLARE_SIMPLIFY_DESCRIPTOR(DICompositeType)
+DECLARE_SIMPLIFY_DESCRIPTOR(DISubroutineType)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIFile)
+DECLARE_SIMPLIFY_DESCRIPTOR(DICompileUnit)
+DECLARE_SIMPLIFY_DESCRIPTOR(DISubprogram)
+DECLARE_SIMPLIFY_DESCRIPTOR(DILexicalBlock)
+DECLARE_SIMPLIFY_DESCRIPTOR(DILexicalBlockFile)
+DECLARE_SIMPLIFY_DESCRIPTOR(DINameSpace)
+DECLARE_SIMPLIFY_DESCRIPTOR(DITemplateTypeParameter)
+DECLARE_SIMPLIFY_DESCRIPTOR(DITemplateValueParameter)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIGlobalVariable)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIVariable)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIExpression)
+DECLARE_SIMPLIFY_DESCRIPTOR(DILocation)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIObjCProperty)
+DECLARE_SIMPLIFY_DESCRIPTOR(DIImportedEntity)
+#undef DECLARE_SIMPLIFY_DESCRIPTOR
+
+typedef DebugNodeArray DIArray;
+typedef MDTypeRefArray DITypeArray;
+typedef DebugNodeRef DIDescriptorRef;
+typedef MDScopeRef DIScopeRef;
+typedef MDTypeRef DITypeRef;
+
+class DISubrange {
+ MDSubrange *N;
public:
- /// \brief Accessibility flags.
- ///
- /// The three accessibility flags are mutually exclusive and rolled together
- /// in the first two bits.
- enum {
-#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
-#include "llvm/IR/DebugInfoFlags.def"
- FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic
- };
-
- static unsigned getFlag(StringRef Flag);
- static const char *getFlagString(unsigned Flag);
-
- /// \brief Split up a flags bitfield.
- ///
- /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
- /// any remaining (unrecognized) bits.
- static unsigned splitFlags(unsigned Flags,
- SmallVectorImpl<unsigned> &SplitFlags);
-
-protected:
- const MDNode *DbgNode;
-
- StringRef getStringField(unsigned Elt) const;
- unsigned getUnsignedField(unsigned Elt) const {
- return (unsigned)getUInt64Field(Elt);
- }
- uint64_t getUInt64Field(unsigned Elt) const;
- int64_t getInt64Field(unsigned Elt) const;
- DIDescriptor getDescriptorField(unsigned Elt) const;
+ DISubrange(const MDSubrange *N = nullptr) : N(const_cast<MDSubrange *>(N)) {}
- template <typename DescTy> DescTy getFieldAs(unsigned Elt) const {
- return DescTy(getDescriptorField(Elt));
- }
+ operator MDSubrange *() const { return N; }
+ MDSubrange *operator->() const { return N; }
+ MDSubrange &operator*() const { return *N; }
+};
- GlobalVariable *getGlobalVariableField(unsigned Elt) const;
- Constant *getConstantField(unsigned Elt) const;
- Function *getFunctionField(unsigned Elt) const;
+class DIEnumerator {
+ MDEnumerator *N;
public:
- explicit DIDescriptor(const MDNode *N = nullptr) : DbgNode(N) {}
-
- bool Verify() const;
-
- MDNode *get() const { return const_cast<MDNode *>(DbgNode); }
- operator MDNode *() const { return get(); }
- MDNode *operator->() const { return get(); }
- MDNode &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- // An explicit operator bool so that we can do testing of DI values
- // easily.
- // FIXME: This operator bool isn't actually protecting anything at the
- // moment due to the conversion operator above making DIDescriptor nodes
- // implicitly convertable to bool.
- explicit operator bool() const { return DbgNode != nullptr; }
-
- bool operator==(DIDescriptor Other) const { return DbgNode == Other.DbgNode; }
- bool operator!=(DIDescriptor Other) const { return !operator==(Other); }
-
- StringRef getHeader() const { return getStringField(0); }
-
- size_t getNumHeaderFields() const {
- return std::distance(DIHeaderFieldIterator(getHeader()),
- DIHeaderFieldIterator());
- }
-
- DIHeaderFieldIterator header_begin() const {
- return DIHeaderFieldIterator(getHeader());
- }
- DIHeaderFieldIterator header_end() const { return DIHeaderFieldIterator(); }
-
- DIHeaderFieldIterator getHeaderIterator(unsigned Index) const {
- // Since callers expect an empty string for out-of-range accesses, we can't
- // use std::advance() here.
- for (auto I = header_begin(), E = header_end(); I != E; ++I, --Index)
- if (!Index)
- return I;
- return header_end();
- }
-
- StringRef getHeaderField(unsigned Index) const {
- return *getHeaderIterator(Index);
- }
-
- template <class T> T getHeaderFieldAs(unsigned Index) const {
- return getHeaderIterator(Index).getNumber<T>();
- }
-
- uint16_t getTag() const {
- if (auto *N = dyn_cast_or_null<DebugNode>(get()))
- return N->getTag();
- return 0;
- }
+ DIEnumerator(const MDEnumerator *N = nullptr)
+ : N(const_cast<MDEnumerator *>(N)) {}
- bool isDerivedType() const { return get() && isa<MDDerivedTypeBase>(get()); }
- bool isCompositeType() const {
- return get() && isa<MDCompositeTypeBase>(get());
- }
- bool isSubroutineType() const {
- return get() && isa<MDSubroutineType>(get());
- }
- bool isBasicType() const { return get() && isa<MDBasicType>(get()); }
- bool isVariable() const { return get() && isa<MDLocalVariable>(get()); }
- bool isSubprogram() const { return get() && isa<MDSubprogram>(get()); }
- bool isGlobalVariable() const {
- return get() && isa<MDGlobalVariable>(get());
- }
- bool isScope() const { return get() && isa<MDScope>(get()); }
- bool isFile() const { return get() && isa<MDFile>(get()); }
- bool isCompileUnit() const { return get() && isa<MDCompileUnit>(get()); }
- bool isNameSpace() const{ return get() && isa<MDNamespace>(get()); }
- bool isLexicalBlockFile() const {
- return get() && isa<MDLexicalBlockFile>(get());
- }
- bool isLexicalBlock() const {
- return get() && isa<MDLexicalBlockBase>(get());
- }
- bool isSubrange() const { return get() && isa<MDSubrange>(get()); }
- bool isEnumerator() const { return get() && isa<MDEnumerator>(get()); }
- bool isType() const { return get() && isa<MDType>(get()); }
- bool isTemplateTypeParameter() const {
- return get() && isa<MDTemplateTypeParameter>(get());
- }
- bool isTemplateValueParameter() const {
- return get() && isa<MDTemplateValueParameter>(get());
- }
- bool isObjCProperty() const { return get() && isa<MDObjCProperty>(get()); }
- bool isImportedEntity() const {
- return get() && isa<MDImportedEntity>(get());
- }
- bool isExpression() const { return get() && isa<MDExpression>(get()); }
-
- void print(raw_ostream &OS) const;
- void dump() const;
-
- /// \brief Replace all uses of debug info referenced by this descriptor.
- void replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D);
- void replaceAllUsesWith(MDNode *D);
+ operator MDEnumerator *() const { return N; }
+ MDEnumerator *operator->() const { return N; }
+ MDEnumerator &operator*() const { return *N; }
};
-#define RETURN_FROM_RAW(VALID, UNUSED) \
- do { \
- auto *N = get(); \
- assert(N && "Expected non-null in accessor"); \
- return VALID; \
- } while (false)
-#define RETURN_DESCRIPTOR_FROM_RAW(DESC, VALID) \
- do { \
- auto *N = get(); \
- assert(N && "Expected non-null in accessor"); \
- return DESC(dyn_cast_or_null<MDNode>(VALID)); \
- } while (false)
-#define RETURN_REF_FROM_RAW(REF, VALID) \
- do { \
- auto *N = get(); \
- assert(N && "Expected non-null in accessor"); \
- return REF::get(VALID); \
- } while (false)
-
-/// \brief This is used to represent ranges, for array bounds.
-class DISubrange : public DIDescriptor {
-public:
- explicit DISubrange(const MDNode *N = nullptr) : DIDescriptor(N) {}
- DISubrange(const MDSubrange *N) : DIDescriptor(N) {}
-
- MDSubrange *get() const {
- return cast_or_null<MDSubrange>(DIDescriptor::get());
- }
- operator MDSubrange *() const { return get(); }
- MDSubrange *operator->() const { return get(); }
- MDSubrange &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- int64_t getLo() const { RETURN_FROM_RAW(N->getLo(), 0); }
- int64_t getCount() const { RETURN_FROM_RAW(N->getCount(), 0); }
- bool Verify() const;
-};
+class DIScope {
+ MDScope *N;
-/// \brief This descriptor holds an array of nodes with type T.
-template <typename T> class DITypedArray : public DIDescriptor {
public:
- explicit DITypedArray(const MDNode *N = nullptr) : DIDescriptor(N) {}
- unsigned getNumElements() const {
- return DbgNode ? DbgNode->getNumOperands() : 0;
- }
- T getElement(unsigned Idx) const { return getFieldAs<T>(Idx); }
+ DIScope(const MDScope *N = nullptr) : N(const_cast<MDScope *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator MDScope *() const { return N; }
+ MDScope *operator->() const { return N; }
+ MDScope &operator*() const { return *N; }
};
-typedef DITypedArray<DIDescriptor> DIArray;
+class DIType {
+ MDType *N;
-/// \brief A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
-///
-/// FIXME: it seems strange that this doesn't have either a reference to the
-/// type/precision or a file/line pair for location info.
-class DIEnumerator : public DIDescriptor {
public:
- explicit DIEnumerator(const MDNode *N = nullptr) : DIDescriptor(N) {}
- DIEnumerator(const MDEnumerator *N) : DIDescriptor(N) {}
-
- MDEnumerator *get() const {
- return cast_or_null<MDEnumerator>(DIDescriptor::get());
- }
- operator MDEnumerator *() const { return get(); }
- MDEnumerator *operator->() const { return get(); }
- MDEnumerator &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ DIType(const MDType *N = nullptr) : N(const_cast<MDType *>(N)) {}
- StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
- int64_t getEnumValue() const { RETURN_FROM_RAW(N->getValue(), 0); }
- bool Verify() const;
+ operator DIDescriptor() const { return N; }
+ operator DIScope() const { return N; }
+ operator MDType *() const { return N; }
+ MDType *operator->() const { return N; }
+ MDType &operator*() const { return *N; }
};
-template <typename T> class DIRef;
-typedef DIRef<DIDescriptor> DIDescriptorRef;
-typedef DIRef<DIScope> DIScopeRef;
-typedef DIRef<DIType> DITypeRef;
-typedef DITypedArray<DITypeRef> DITypeArray;
+class DIBasicType {
+ MDBasicType *N;
-/// \brief A base class for various scopes.
-///
-/// Although, implementation-wise, DIScope is the parent class of most
-/// other DIxxx classes, including DIType and its descendants, most of
-/// DIScope's descendants are not a substitutable subtype of
-/// DIScope. The DIDescriptor::isScope() method only is true for
-/// DIScopes that are scopes in the strict lexical scope sense
-/// (DICompileUnit, DISubprogram, etc.), but not for, e.g., a DIType.
-class DIScope : public DIDescriptor {
public:
- explicit DIScope(const MDNode *N = nullptr) : DIDescriptor(N) {}
- DIScope(const MDScope *N) : DIDescriptor(N) {}
-
- MDScope *get() const { return cast_or_null<MDScope>(DIDescriptor::get()); }
- operator MDScope *() const { return get(); }
- MDScope *operator->() const { return get(); }
- MDScope &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- /// \brief Get the parent scope.
- ///
- /// Gets the parent scope for this scope node or returns a default
- /// constructed scope.
- DIScopeRef getContext() const;
- /// \brief Get the scope name.
- ///
- /// If the scope node has a name, return that, else return an empty string.
- StringRef getName() const;
- StringRef getFilename() const;
- StringRef getDirectory() const;
-
- /// \brief Generate a reference to this DIScope.
- ///
- /// Uses the type identifier instead of the actual MDNode if possible, to
- /// help type uniquing.
- DIScopeRef getRef() const;
+ DIBasicType(const MDBasicType *N = nullptr)
+ : N(const_cast<MDBasicType *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator DIType() const { return N; }
+ operator MDBasicType *() const { return N; }
+ MDBasicType *operator->() const { return N; }
+ MDBasicType &operator*() const { return *N; }
};
-/// \brief Represents reference to a DIDescriptor.
-///
-/// Abstracts over direct and identifier-based metadata references.
-template <typename T> class DIRef {
- template <typename DescTy>
- friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
- friend DIScopeRef DIScope::getContext() const;
- friend DIScopeRef DIScope::getRef() const;
- friend class DIType;
-
- /// \brief Val can be either a MDNode or a MDString.
- ///
- /// In the latter, MDString specifies the type identifier.
- const Metadata *Val;
- explicit DIRef(const Metadata *V);
+class DIDerivedType {
+ MDDerivedTypeBase *N;
public:
- T resolve(const DITypeIdentifierMap &Map) const;
- StringRef getName() const;
- operator Metadata *() const { return const_cast<Metadata *>(Val); }
-
- static DIRef get(const Metadata *MD) { return DIRef(MD); }
+ DIDerivedType(const MDDerivedTypeBase *N = nullptr)
+ : N(const_cast<MDDerivedTypeBase *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator DIType() const { return N; }
+ operator MDDerivedTypeBase *() const { return N; }
+ MDDerivedTypeBase *operator->() const { return N; }
+ MDDerivedTypeBase &operator*() const { return *N; }
};
-template <typename T>
-T DIRef<T>::resolve(const DITypeIdentifierMap &Map) const {
- if (!Val)
- return T();
-
- if (const MDNode *MD = dyn_cast<MDNode>(Val))
- return T(MD);
-
- const MDString *MS = cast<MDString>(Val);
- // Find the corresponding MDNode.
- DITypeIdentifierMap::const_iterator Iter = Map.find(MS);
- assert(Iter != Map.end() && "Identifier not in the type map?");
- assert(DIDescriptor(Iter->second).isType() &&
- "MDNode in DITypeIdentifierMap should be a DIType.");
- return T(Iter->second);
-}
-
-template <typename T> StringRef DIRef<T>::getName() const {
- if (!Val)
- return StringRef();
-
- if (const MDNode *MD = dyn_cast<MDNode>(Val))
- return T(MD).getName();
-
- const MDString *MS = cast<MDString>(Val);
- return MS->getString();
-}
-
-/// \brief Handle fields that are references to DIDescriptors.
-template <>
-DIDescriptorRef DIDescriptor::getFieldAs<DIDescriptorRef>(unsigned Elt) const;
-/// \brief Specialize DIRef constructor for DIDescriptorRef.
-template <> DIRef<DIDescriptor>::DIRef(const Metadata *V);
-
-/// \brief Handle fields that are references to DIScopes.
-template <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;
-/// \brief Specialize DIRef constructor for DIScopeRef.
-template <> DIRef<DIScope>::DIRef(const Metadata *V);
-
-/// \brief Handle fields that are references to DITypes.
-template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;
-/// \brief Specialize DIRef constructor for DITypeRef.
-template <> DIRef<DIType>::DIRef(const Metadata *V);
-
-/// \brief This is a wrapper for a type.
-///
-/// FIXME: Types should be factored much better so that CV qualifiers and
-/// others do not require a huge and empty descriptor full of zeros.
-class DIType : public DIScope {
-public:
- explicit DIType(const MDNode *N = nullptr) : DIScope(N) {}
- DIType(const MDType *N) : DIScope(N) {}
-
- MDType *get() const { return cast_or_null<MDType>(DIDescriptor::get()); }
- operator MDType *() const { return get(); }
- MDType *operator->() const { return get(); }
- MDType &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- operator DITypeRef() const {
- assert(isType() &&
- "constructing DITypeRef from an MDNode that is not a type");
- return DITypeRef(&*getRef());
- }
-
- bool Verify() const;
+class DICompositeType {
+ MDCompositeTypeBase *N;
- DIScopeRef getContext() const {
- RETURN_REF_FROM_RAW(DIScopeRef, N->getScope());
- }
- StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
- unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
- uint64_t getSizeInBits() const { RETURN_FROM_RAW(N->getSizeInBits(), 0); }
- uint64_t getAlignInBits() const { RETURN_FROM_RAW(N->getAlignInBits(), 0); }
- // FIXME: Offset is only used for DW_TAG_member nodes. Making every type
- // carry this is just plain insane.
- uint64_t getOffsetInBits() const { RETURN_FROM_RAW(N->getOffsetInBits(), 0); }
- unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); }
- bool isPrivate() const {
- return (getFlags() & FlagAccessibility) == FlagPrivate;
- }
- bool isProtected() const {
- return (getFlags() & FlagAccessibility) == FlagProtected;
- }
- bool isPublic() const {
- return (getFlags() & FlagAccessibility) == FlagPublic;
- }
- bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; }
- bool isAppleBlockExtension() const {
- return (getFlags() & FlagAppleBlock) != 0;
- }
- bool isBlockByrefStruct() const {
- return (getFlags() & FlagBlockByrefStruct) != 0;
- }
- bool isVirtual() const { return (getFlags() & FlagVirtual) != 0; }
- bool isArtificial() const { return (getFlags() & FlagArtificial) != 0; }
- bool isObjectPointer() const { return (getFlags() & FlagObjectPointer) != 0; }
- bool isObjcClassComplete() const {
- return (getFlags() & FlagObjcClassComplete) != 0;
- }
- bool isVector() const { return (getFlags() & FlagVector) != 0; }
- bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; }
- bool isLValueReference() const {
- return (getFlags() & FlagLValueReference) != 0;
- }
- bool isRValueReference() const {
- return (getFlags() & FlagRValueReference) != 0;
- }
- bool isValid() const { return DbgNode && isType(); }
-};
-
-/// \brief A basic type, like 'int' or 'float'.
-class DIBasicType : public DIType {
public:
- explicit DIBasicType(const MDNode *N = nullptr) : DIType(N) {}
- DIBasicType(const MDBasicType *N) : DIType(N) {}
-
- MDBasicType *get() const {
- return cast_or_null<MDBasicType>(DIDescriptor::get());
- }
- operator MDBasicType *() const { return get(); }
- MDBasicType *operator->() const { return get(); }
- MDBasicType &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- unsigned getEncoding() const { RETURN_FROM_RAW(N->getEncoding(), 0); }
-
- bool Verify() const;
+ DICompositeType(const MDCompositeTypeBase *N = nullptr)
+ : N(const_cast<MDCompositeTypeBase *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator DIType() const { return N; }
+ operator MDCompositeTypeBase *() const { return N; }
+ MDCompositeTypeBase *operator->() const { return N; }
+ MDCompositeTypeBase &operator*() const { return *N; }
};
-/// \brief A simple derived type
-///
-/// Like a const qualified type, a typedef, a pointer or reference, et cetera.
-/// Or, a data member of a class/struct/union.
-class DIDerivedType : public DIType {
-public:
- explicit DIDerivedType(const MDNode *N = nullptr) : DIType(N) {}
- DIDerivedType(const MDDerivedTypeBase *N) : DIType(N) {}
-
- MDDerivedTypeBase *get() const {
- return cast_or_null<MDDerivedTypeBase>(DIDescriptor::get());
- }
- operator MDDerivedTypeBase *() const { return get(); }
- MDDerivedTypeBase *operator->() const { return get(); }
- MDDerivedTypeBase &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- DITypeRef getTypeDerivedFrom() const {
- RETURN_REF_FROM_RAW(DITypeRef, N->getBaseType());
- }
-
- /// \brief Return property node, if this ivar is associated with one.
- MDNode *getObjCProperty() const {
- if (auto *N = dyn_cast<MDDerivedType>(get()))
- return dyn_cast_or_null<MDNode>(N->getExtraData());
- return nullptr;
- }
+class DISubroutineType {
+ MDSubroutineType *N;
- DITypeRef getClassType() const {
- assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
- if (auto *N = dyn_cast<MDDerivedType>(get()))
- return DITypeRef::get(N->getExtraData());
- return DITypeRef::get(nullptr);
- }
-
- Constant *getConstant() const {
- assert((getTag() == dwarf::DW_TAG_member) && isStaticMember());
- if (auto *N = dyn_cast<MDDerivedType>(get()))
- if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getExtraData()))
- return C->getValue();
-
- return nullptr;
- }
-
- bool Verify() const;
+public:
+ DISubroutineType(const MDSubroutineType *N = nullptr)
+ : N(const_cast<MDSubroutineType *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator DIType() const { return N; }
+ operator DICompositeType() const { return N; }
+ operator MDSubroutineType *() const { return N; }
+ MDSubroutineType *operator->() const { return N; }
+ MDSubroutineType &operator*() const { return *N; }
};
-/// \brief Types that refer to multiple other types.
-///
-/// This descriptor holds a type that can refer to multiple other types, like a
-/// function or struct.
-///
-/// DICompositeType is derived from DIDerivedType because some
-/// composite types (such as enums) can be derived from basic types
-// FIXME: Make this derive from DIType directly & just store the
-// base type in a single DIType field.
-class DICompositeType : public DIDerivedType {
- friend class DIBuilder;
-
- /// \brief Set the array of member DITypes.
- void setArraysHelper(MDNode *Elements, MDNode *TParams);
+class DIFile {
+ MDFile *N;
public:
- explicit DICompositeType(const MDNode *N = nullptr) : DIDerivedType(N) {}
- DICompositeType(const MDCompositeTypeBase *N) : DIDerivedType(N) {}
+ DIFile(const MDFile *N = nullptr) : N(const_cast<MDFile *>(N)) {}
- MDCompositeTypeBase *get() const {
- return cast_or_null<MDCompositeTypeBase>(DIDescriptor::get());
- }
- operator MDCompositeTypeBase *() const { return get(); }
- MDCompositeTypeBase *operator->() const { return get(); }
- MDCompositeTypeBase &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- DIArray getElements() const {
- assert(!isSubroutineType() && "no elements for DISubroutineType");
- RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getElements());
- }
+ operator DIDescriptor() const { return N; }
+ operator DIScope() const { return N; }
+ operator MDFile *() const { return N; }
+ MDFile *operator->() const { return N; }
+ MDFile &operator*() const { return *N; }
+};
-private:
- template <typename T>
- void setArrays(DITypedArray<T> Elements, DIArray TParams = DIArray()) {
- assert(
- (!TParams || DbgNode->getNumOperands() == 8) &&
- "If you're setting the template parameters this should include a slot "
- "for that!");
- setArraysHelper(Elements, TParams);
- }
+class DICompileUnit {
+ MDCompileUnit *N;
public:
- unsigned getRunTimeLang() const { RETURN_FROM_RAW(N->getRuntimeLang(), 0); }
- DITypeRef getContainingType() const {
- RETURN_REF_FROM_RAW(DITypeRef, N->getVTableHolder());
- }
+ DICompileUnit(const MDCompileUnit *N = nullptr)
+ : N(const_cast<MDCompileUnit *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator DIScope() const { return N; }
+ operator MDCompileUnit *() const { return N; }
+ MDCompileUnit *operator->() const { return N; }
+ MDCompileUnit &operator*() const { return *N; }
+};
-private:
- /// \brief Set the containing type.
- void setContainingType(DICompositeType ContainingType);
+class DISubprogram {
+ MDSubprogram *N;
public:
- DIArray getTemplateParams() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getTemplateParams());
- }
- MDString *getIdentifier() const {
- RETURN_FROM_RAW(N->getRawIdentifier(), nullptr);
- }
-
- bool Verify() const;
+ DISubprogram(const MDSubprogram *N = nullptr)
+ : N(const_cast<MDSubprogram *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator DIScope() const { return N; }
+ operator MDSubprogram *() const { return N; }
+ MDSubprogram *operator->() const { return N; }
+ MDSubprogram &operator*() const { return *N; }
};
-class DISubroutineType : public DICompositeType {
-public:
- explicit DISubroutineType(const MDNode *N = nullptr) : DICompositeType(N) {}
- DISubroutineType(const MDSubroutineType *N) : DICompositeType(N) {}
+class DILexicalBlock {
+ MDLexicalBlockBase *N;
- MDSubroutineType *get() const {
- return cast_or_null<MDSubroutineType>(DIDescriptor::get());
- }
- operator MDSubroutineType *() const { return get(); }
- MDSubroutineType *operator->() const { return get(); }
- MDSubroutineType &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- DITypedArray<DITypeRef> getTypeArray() const {
- RETURN_DESCRIPTOR_FROM_RAW(DITypedArray<DITypeRef>, N->getTypeArray());
- }
-};
-
-/// \brief This is a wrapper for a file.
-class DIFile : public DIScope {
public:
- explicit DIFile(const MDNode *N = nullptr) : DIScope(N) {}
- DIFile(const MDFile *N) : DIScope(N) {}
-
- MDFile *get() const { return cast_or_null<MDFile>(DIDescriptor::get()); }
- operator MDFile *() const { return get(); }
- MDFile *operator->() const { return get(); }
- MDFile &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ DILexicalBlock(const MDLexicalBlockBase *N = nullptr)
+ : N(const_cast<MDLexicalBlockBase *>(N)) {}
- /// \brief Retrieve the MDNode for the directory/file pair.
- MDNode *getFileNode() const { return get(); }
- bool Verify() const;
+ operator DIDescriptor() const { return N; }
+ operator MDLexicalBlockBase *() const { return N; }
+ MDLexicalBlockBase *operator->() const { return N; }
+ MDLexicalBlockBase &operator*() const { return *N; }
};
-/// \brief A wrapper for a compile unit.
-class DICompileUnit : public DIScope {
-public:
- explicit DICompileUnit(const MDNode *N = nullptr) : DIScope(N) {}
- DICompileUnit(const MDCompileUnit *N) : DIScope(N) {}
-
- MDCompileUnit *get() const {
- return cast_or_null<MDCompileUnit>(DIDescriptor::get());
- }
- operator MDCompileUnit *() const { return get(); }
- MDCompileUnit *operator->() const { return get(); }
- MDCompileUnit &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- dwarf::SourceLanguage getLanguage() const {
- RETURN_FROM_RAW(static_cast<dwarf::SourceLanguage>(N->getSourceLanguage()),
- static_cast<dwarf::SourceLanguage>(0));
- }
- StringRef getProducer() const { RETURN_FROM_RAW(N->getProducer(), ""); }
- bool isOptimized() const { RETURN_FROM_RAW(N->isOptimized(), false); }
- StringRef getFlags() const { RETURN_FROM_RAW(N->getFlags(), ""); }
- unsigned getRunTimeVersion() const {
- RETURN_FROM_RAW(N->getRuntimeVersion(), 0);
- }
+class DILexicalBlockFile {
+ MDLexicalBlockFile *N;
- DIArray getEnumTypes() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getEnumTypes());
- }
- DIArray getRetainedTypes() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getRetainedTypes());
- }
- DIArray getSubprograms() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getSubprograms());
- }
- DIArray getGlobalVariables() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getGlobalVariables());
- }
- DIArray getImportedEntities() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getImportedEntities());
- }
-
- void replaceSubprograms(DIArray Subprograms);
- void replaceGlobalVariables(DIArray GlobalVariables);
-
- StringRef getSplitDebugFilename() const {
- RETURN_FROM_RAW(N->getSplitDebugFilename(), "");
- }
- unsigned getEmissionKind() const { RETURN_FROM_RAW(N->getEmissionKind(), 0); }
-
- bool Verify() const;
-};
-
-/// \brief This is a wrapper for a subprogram (e.g. a function).
-class DISubprogram : public DIScope {
public:
- explicit DISubprogram(const MDNode *N = nullptr) : DIScope(N) {}
- DISubprogram(const MDSubprogram *N) : DIScope(N) {}
-
- MDSubprogram *get() const {
- return cast_or_null<MDSubprogram>(DIDescriptor::get());
- }
- operator MDSubprogram *() const { return get(); }
- MDSubprogram *operator->() const { return get(); }
- MDSubprogram &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
- StringRef getDisplayName() const { RETURN_FROM_RAW(N->getDisplayName(), ""); }
- StringRef getLinkageName() const { RETURN_FROM_RAW(N->getLinkageName(), ""); }
- unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
-
- /// \brief Check if this is local (like 'static' in C).
- unsigned isLocalToUnit() const { RETURN_FROM_RAW(N->isLocalToUnit(), 0); }
- unsigned isDefinition() const { RETURN_FROM_RAW(N->isDefinition(), 0); }
-
- unsigned getVirtuality() const { RETURN_FROM_RAW(N->getVirtuality(), 0); }
- unsigned getVirtualIndex() const { RETURN_FROM_RAW(N->getVirtualIndex(), 0); }
-
- unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); }
-
- unsigned isOptimized() const { RETURN_FROM_RAW(N->isOptimized(), 0); }
-
- /// \brief Get the beginning of the scope of the function (not the name).
- unsigned getScopeLineNumber() const { RETURN_FROM_RAW(N->getScopeLine(), 0); }
-
- DIScopeRef getContext() const {
- RETURN_REF_FROM_RAW(DIScopeRef, N->getScope());
- }
- DISubroutineType getType() const {
- RETURN_DESCRIPTOR_FROM_RAW(DISubroutineType, N->getType());
- }
-
- DITypeRef getContainingType() const {
- RETURN_REF_FROM_RAW(DITypeRef, N->getContainingType());
- }
-
- bool Verify() const;
-
- /// \brief Check if this provides debugging information for the function F.
- bool describes(const Function *F);
-
- Function *getFunction() const;
-
- void replaceFunction(Function *F) {
- if (auto *N = get())
- N->replaceFunction(F);
- }
- DIArray getTemplateParams() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getTemplateParams());
- }
- DISubprogram getFunctionDeclaration() const {
- RETURN_DESCRIPTOR_FROM_RAW(DISubprogram, N->getDeclaration());
- }
- MDNode *getVariablesNodes() const { return getVariables(); }
- DIArray getVariables() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getVariables());
- }
-
- unsigned isArtificial() const { return (getFlags() & FlagArtificial) != 0; }
- /// \brief Check for the "private" access specifier.
- bool isPrivate() const {
- return (getFlags() & FlagAccessibility) == FlagPrivate;
- }
- /// \brief Check for the "protected" access specifier.
- bool isProtected() const {
- return (getFlags() & FlagAccessibility) == FlagProtected;
- }
- /// \brief Check for the "public" access specifier.
- bool isPublic() const {
- return (getFlags() & FlagAccessibility) == FlagPublic;
- }
- /// \brief Check for "explicit".
- bool isExplicit() const { return (getFlags() & FlagExplicit) != 0; }
- /// \brief Check if this is prototyped.
- bool isPrototyped() const { return (getFlags() & FlagPrototyped) != 0; }
-
- /// \brief Check if this is reference-qualified.
- ///
- /// Return true if this subprogram is a C++11 reference-qualified non-static
- /// member function (void foo() &).
- unsigned isLValueReference() const {
- return (getFlags() & FlagLValueReference) != 0;
- }
+ DILexicalBlockFile(const MDLexicalBlockFile *N = nullptr)
+ : N(const_cast<MDLexicalBlockFile *>(N)) {}
- /// \brief Check if this is rvalue-reference-qualified.
- ///
- /// Return true if this subprogram is a C++11 rvalue-reference-qualified
- /// non-static member function (void foo() &&).
- unsigned isRValueReference() const {
- return (getFlags() & FlagRValueReference) != 0;
- }
+ operator DIDescriptor() const { return N; }
+ operator MDLexicalBlockFile *() const { return N; }
+ MDLexicalBlockFile *operator->() const { return N; }
+ MDLexicalBlockFile &operator*() const { return *N; }
};
-/// \brief This is a wrapper for a lexical block.
-class DILexicalBlock : public DIScope {
-public:
- explicit DILexicalBlock(const MDNode *N = nullptr) : DIScope(N) {}
- DILexicalBlock(const MDLexicalBlock *N) : DIScope(N) {}
+class DINameSpace {
+ MDNamespace *N;
- MDLexicalBlockBase *get() const {
- return cast_or_null<MDLexicalBlockBase>(DIDescriptor::get());
- }
- operator MDLexicalBlockBase *() const { return get(); }
- MDLexicalBlockBase *operator->() const { return get(); }
- MDLexicalBlockBase &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- DIScope getContext() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
- }
- unsigned getLineNumber() const {
- if (auto *N = dyn_cast<MDLexicalBlock>(get()))
- return N->getLine();
- return 0;
- }
- unsigned getColumnNumber() const {
- if (auto *N = dyn_cast<MDLexicalBlock>(get()))
- return N->getColumn();
- return 0;
- }
- bool Verify() const;
-};
-
-/// \brief This is a wrapper for a lexical block with a filename change.
-class DILexicalBlockFile : public DIScope {
public:
- explicit DILexicalBlockFile(const MDNode *N = nullptr) : DIScope(N) {}
- DILexicalBlockFile(const MDLexicalBlockFile *N) : DIScope(N) {}
-
- MDLexicalBlockFile *get() const {
- return cast_or_null<MDLexicalBlockFile>(DIDescriptor::get());
- }
- operator MDLexicalBlockFile *() const { return get(); }
- MDLexicalBlockFile *operator->() const { return get(); }
- MDLexicalBlockFile &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- DIScope getContext() const {
- // FIXME: This logic is horrible. getScope() returns a DILexicalBlock, but
- // then we check if it's a subprogram? WHAT?!?
- if (getScope().isSubprogram())
- return getScope();
- return getScope().getContext();
- }
- unsigned getLineNumber() const { return getScope().getLineNumber(); }
- unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
- DILexicalBlock getScope() const {
- RETURN_DESCRIPTOR_FROM_RAW(DILexicalBlock, N->getScope());
- }
- unsigned getDiscriminator() const {
- RETURN_FROM_RAW(N->getDiscriminator(), 0);
- }
- bool Verify() const;
+ DINameSpace(const MDNamespace *N = nullptr)
+ : N(const_cast<MDNamespace *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator DIScope() const { return N; }
+ operator MDNamespace *() const { return N; }
+ MDNamespace *operator->() const { return N; }
+ MDNamespace &operator*() const { return *N; }
};
-/// \brief A wrapper for a C++ style name space.
-class DINameSpace : public DIScope {
-public:
- explicit DINameSpace(const MDNode *N = nullptr) : DIScope(N) {}
- DINameSpace(const MDNamespace *N) : DIScope(N) {}
-
- MDNamespace *get() const {
- return cast_or_null<MDNamespace>(DIDescriptor::get());
- }
- operator MDNamespace *() const { return get(); }
- MDNamespace *operator->() const { return get(); }
- MDNamespace &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
- unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
- DIScope getContext() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
- }
- bool Verify() const;
-};
+class DITemplateTypeParameter {
+ MDTemplateTypeParameter *N;
-/// \brief This is a wrapper for template type parameter.
-class DITemplateTypeParameter : public DIDescriptor {
public:
- explicit DITemplateTypeParameter(const MDNode *N = nullptr)
- : DIDescriptor(N) {}
- DITemplateTypeParameter(const MDTemplateTypeParameter *N) : DIDescriptor(N) {}
+ DITemplateTypeParameter(const MDTemplateTypeParameter *N = nullptr)
+ : N(const_cast<MDTemplateTypeParameter *>(N)) {}
- MDTemplateTypeParameter *get() const {
- return cast_or_null<MDTemplateTypeParameter>(DIDescriptor::get());
- }
- operator MDTemplateTypeParameter *() const { return get(); }
- MDTemplateTypeParameter *operator->() const { return get(); }
- MDTemplateTypeParameter &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
-
- DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
- bool Verify() const;
+ operator MDTemplateTypeParameter *() const { return N; }
+ MDTemplateTypeParameter *operator->() const { return N; }
+ MDTemplateTypeParameter &operator*() const { return *N; }
};
-/// \brief This is a wrapper for template value parameter.
-class DITemplateValueParameter : public DIDescriptor {
-public:
- explicit DITemplateValueParameter(const MDNode *N = nullptr)
- : DIDescriptor(N) {}
- DITemplateValueParameter(const MDTemplateValueParameter *N)
- : DIDescriptor(N) {}
+class DITemplateValueParameter {
+ MDTemplateValueParameter *N;
- MDTemplateValueParameter *get() const {
- return cast_or_null<MDTemplateValueParameter>(DIDescriptor::get());
- }
- operator MDTemplateValueParameter *() const { return get(); }
- MDTemplateValueParameter *operator->() const { return get(); }
- MDTemplateValueParameter &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+public:
+ DITemplateValueParameter(const MDTemplateValueParameter *N = nullptr)
+ : N(const_cast<MDTemplateValueParameter *>(N)) {}
- StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
- DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
- Metadata *getValue() const { RETURN_FROM_RAW(N->getValue(), nullptr); }
- bool Verify() const;
+ operator MDTemplateValueParameter *() const { return N; }
+ MDTemplateValueParameter *operator->() const { return N; }
+ MDTemplateValueParameter &operator*() const { return *N; }
};
-/// \brief This is a wrapper for a global variable.
-class DIGlobalVariable : public DIDescriptor {
- DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); }
+class DIGlobalVariable {
+ MDGlobalVariable *N;
public:
- explicit DIGlobalVariable(const MDNode *N = nullptr) : DIDescriptor(N) {}
- DIGlobalVariable(const MDGlobalVariable *N) : DIDescriptor(N) {}
+ DIGlobalVariable(const MDGlobalVariable *N = nullptr)
+ : N(const_cast<MDGlobalVariable *>(N)) {}
- MDGlobalVariable *get() const {
- return cast_or_null<MDGlobalVariable>(DIDescriptor::get());
- }
- operator MDGlobalVariable *() const { return get(); }
- MDGlobalVariable *operator->() const { return get(); }
- MDGlobalVariable &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
- StringRef getDisplayName() const { RETURN_FROM_RAW(N->getDisplayName(), ""); }
- StringRef getLinkageName() const { RETURN_FROM_RAW(N->getLinkageName(), ""); }
- unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
- unsigned isLocalToUnit() const { RETURN_FROM_RAW(N->isLocalToUnit(), 0); }
- unsigned isDefinition() const { RETURN_FROM_RAW(N->isDefinition(), 0); }
-
- DIScope getContext() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
- }
- StringRef getFilename() const { return getFile().getFilename(); }
- StringRef getDirectory() const { return getFile().getDirectory(); }
- DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
-
- GlobalVariable *getGlobal() const;
- Constant *getConstant() const {
- if (auto *N = get())
- if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getVariable()))
- return C->getValue();
- return nullptr;
- }
- DIDerivedType getStaticDataMemberDeclaration() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIDerivedType,
- N->getStaticDataMemberDeclaration());
- }
-
- bool Verify() const;
+ operator DIDescriptor() const { return N; }
+ operator MDGlobalVariable *() const { return N; }
+ MDGlobalVariable *operator->() const { return N; }
+ MDGlobalVariable &operator*() const { return *N; }
};
-/// \brief This is a wrapper for a variable (e.g. parameter, local, global etc).
-class DIVariable : public DIDescriptor {
- unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); }
+class DIVariable {
+ MDLocalVariable *N;
public:
- explicit DIVariable(const MDNode *N = nullptr) : DIDescriptor(N) {}
- DIVariable(const MDLocalVariable *N) : DIDescriptor(N) {}
+ DIVariable(const MDLocalVariable *N = nullptr)
+ : N(const_cast<MDLocalVariable *>(N)) {}
- MDLocalVariable *get() const {
- return cast_or_null<MDLocalVariable>(DIDescriptor::get());
- }
- operator MDLocalVariable *() const { return get(); }
- MDLocalVariable *operator->() const { return get(); }
- MDLocalVariable &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
- unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
- unsigned getArgNumber() const { RETURN_FROM_RAW(N->getArg(), 0); }
-
- DIScope getContext() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
- }
- DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); }
- DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
-
- /// \brief Return true if this variable is marked as "artificial".
- bool isArtificial() const {
- return (getFlags() & FlagArtificial) != 0;
- }
-
- bool isObjectPointer() const {
- return (getFlags() & FlagObjectPointer) != 0;
- }
-
- /// \brief If this variable is inlined then return inline location.
- MDNode *getInlinedAt() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIDescriptor, N->getInlinedAt());
- }
-
- bool Verify() const;
-
- /// \brief Check if this is a "__block" variable (Apple Blocks).
- bool isBlockByrefVariable(const DITypeIdentifierMap &Map) const {
- return (getType().resolve(Map)).isBlockByrefStruct();
- }
-
- /// \brief Check if this is an inlined function argument.
- bool isInlinedFnArgument(const Function *CurFn);
-
- /// \brief Return the size reported by the variable's type.
- unsigned getSizeInBits(const DITypeIdentifierMap &Map);
-
- void printExtendedName(raw_ostream &OS) const;
+ operator MDLocalVariable *() const { return N; }
+ MDLocalVariable *operator->() const { return N; }
+ MDLocalVariable &operator*() const { return *N; }
};
-/// \brief A complex location expression in postfix notation.
-///
-/// This is (almost) a DWARF expression that modifies the location of a
-/// variable or (or the location of a single piece of a variable).
-///
-/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
-/// and have DW_OP_plus consume the topmost elements on the stack.
-class DIExpression : public DIDescriptor {
-public:
- explicit DIExpression(const MDNode *N = nullptr) : DIDescriptor(N) {}
- DIExpression(const MDExpression *N) : DIDescriptor(N) {}
-
- MDExpression *get() const {
- return cast_or_null<MDExpression>(DIDescriptor::get());
- }
- operator MDExpression *() const { return get(); }
- MDExpression *operator->() const { return get(); }
- MDExpression &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- // Don't call this. Call isValid() directly.
- bool Verify() const = delete;
-
- /// \brief Return the number of elements in the complex expression.
- unsigned getNumElements() const { return get()->getNumElements(); }
-
- /// \brief return the Idx'th complex address element.
- uint64_t getElement(unsigned I) const { return get()->getElement(I); }
-
- /// \brief Return whether this is a piece of an aggregate variable.
- bool isBitPiece() const;
- /// \brief Return the offset of this piece in bits.
- uint64_t getBitPieceOffset() const;
- /// \brief Return the size of this piece in bits.
- uint64_t getBitPieceSize() const;
-
- class iterator;
- /// \brief A lightweight wrapper around an element of a DIExpression.
- class Operand {
- friend class iterator;
- MDExpression::element_iterator I;
- Operand() {}
- Operand(MDExpression::element_iterator I) : I(I) {}
- public:
- /// \brief Operands such as DW_OP_piece have explicit (non-stack) arguments.
- /// Argument 0 is the operand itself.
- uint64_t getArg(unsigned N) const {
- MDExpression::element_iterator In = I;
- std::advance(In, N);
- return *In;
- }
- operator uint64_t () const { return *I; }
- /// \brief Returns underlying MDExpression::element_iterator.
- const MDExpression::element_iterator &getBase() const { return I; }
- /// \brief Returns the next operand.
- iterator getNext() const;
- };
-
- /// \brief An iterator for DIExpression elements.
- class iterator : public std::iterator<std::input_iterator_tag, StringRef,
- unsigned, const Operand*, Operand> {
- friend class Operand;
- MDExpression::element_iterator I;
- Operand Tmp;
-
- public:
- iterator(MDExpression::element_iterator I) : I(I) {}
- const Operand &operator*() { return Tmp = Operand(I); }
- const Operand *operator->() { return &(Tmp = Operand(I)); }
- iterator &operator++() {
- increment();
- return *this;
- }
- iterator operator++(int) {
- iterator X(*this);
- increment();
- return X;
- }
- bool operator==(const iterator &X) const { return I == X.I; }
- bool operator!=(const iterator &X) const { return !(*this == X); }
-
- private:
- void increment() {
- switch (**this) {
- case dwarf::DW_OP_bit_piece: std::advance(I, 3); break;
- case dwarf::DW_OP_plus: std::advance(I, 2); break;
- case dwarf::DW_OP_deref: std::advance(I, 1); break;
- default:
- llvm_unreachable("unsupported operand");
- }
- }
- };
-
- iterator begin() const { return get()->elements_begin(); }
- iterator end() const { return get()->elements_end(); }
-};
+class DIExpression {
+ MDExpression *N;
-/// \brief This object holds location information.
-///
-/// This object is not associated with any DWARF tag.
-class DILocation : public DIDescriptor {
public:
- explicit DILocation(const MDNode *N) : DIDescriptor(N) {}
-
- MDLocation *get() const {
- return cast_or_null<MDLocation>(DIDescriptor::get());
- }
- operator MDLocation *() const { return get(); }
- MDLocation *operator->() const { return get(); }
- MDLocation &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
- unsigned getColumnNumber() const { RETURN_FROM_RAW(N->getColumn(), 0); }
- DIScope getScope() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
- }
- DILocation getOrigLocation() const {
- RETURN_DESCRIPTOR_FROM_RAW(DILocation, N->getInlinedAt());
- }
- StringRef getFilename() const { return getScope().getFilename(); }
- StringRef getDirectory() const { return getScope().getDirectory(); }
- bool Verify() const;
- bool atSameLineAs(const DILocation &Other) const {
- return (getLineNumber() == Other.getLineNumber() &&
- getFilename() == Other.getFilename());
- }
- /// \brief Get the DWAF discriminator.
- ///
- /// DWARF discriminators are used to distinguish identical file locations for
- /// instructions that are on different basic blocks. If two instructions are
- /// inside the same lexical block and are in different basic blocks, we
- /// create a new lexical block with identical location as the original but
- /// with a different discriminator value
- /// (lib/Transforms/Util/AddDiscriminators.cpp for details).
- unsigned getDiscriminator() const {
- // Since discriminators are associated with lexical blocks, make
- // sure this location is a lexical block before retrieving its
- // value.
- return getScope().isLexicalBlockFile()
- ? DILexicalBlockFile(
- cast<MDNode>(cast<MDLocation>(DbgNode)->getScope()))
- .getDiscriminator()
- : 0;
- }
+ DIExpression(const MDExpression *N = nullptr)
+ : N(const_cast<MDExpression *>(N)) {}
- /// \brief Generate a new discriminator value for this location.
- unsigned computeNewDiscriminator(LLVMContext &Ctx);
-
- /// \brief Return a copy of this location with a different scope.
- DILocation copyWithNewScope(LLVMContext &Ctx, DILexicalBlockFile NewScope);
+ operator MDExpression *() const { return N; }
+ MDExpression *operator->() const { return N; }
+ MDExpression &operator*() const { return *N; }
};
-class DIObjCProperty : public DIDescriptor {
+class DILocation {
+ MDLocation *N;
+
public:
- explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {}
- DIObjCProperty(const MDObjCProperty *N) : DIDescriptor(N) {}
+ DILocation(const MDLocation *N = nullptr) : N(const_cast<MDLocation *>(N)) {}
- MDObjCProperty *get() const {
- return cast_or_null<MDObjCProperty>(DIDescriptor::get());
- }
- operator MDObjCProperty *() const { return get(); }
- MDObjCProperty *operator->() const { return get(); }
- MDObjCProperty &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ operator MDLocation *() const { return N; }
+ MDLocation *operator->() const { return N; }
+ MDLocation &operator*() const { return *N; }
+};
- StringRef getObjCPropertyName() const { RETURN_FROM_RAW(N->getName(), ""); }
- DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); }
- unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+class DIObjCProperty {
+ MDObjCProperty *N;
- StringRef getObjCPropertyGetterName() const {
- RETURN_FROM_RAW(N->getGetterName(), "");
- }
- StringRef getObjCPropertySetterName() const {
- RETURN_FROM_RAW(N->getSetterName(), "");
- }
- unsigned getAttributes() const { RETURN_FROM_RAW(N->getAttributes(), 0); }
- bool isReadOnlyObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
- }
- bool isReadWriteObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
- }
- bool isAssignObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_assign) != 0;
- }
- bool isRetainObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_retain) != 0;
- }
- bool isCopyObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_copy) != 0;
- }
- bool isNonAtomicObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
- }
-
- /// \brief Get the type.
- ///
- /// \note Objective-C doesn't have an ODR, so there is no benefit in storing
- /// the type as a DITypeRef here.
- DIType getType() const { RETURN_DESCRIPTOR_FROM_RAW(DIType, N->getType()); }
+public:
+ DIObjCProperty(const MDObjCProperty *N = nullptr)
+ : N(const_cast<MDObjCProperty *>(N)) {}
- bool Verify() const;
+ operator MDObjCProperty *() const { return N; }
+ MDObjCProperty *operator->() const { return N; }
+ MDObjCProperty &operator*() const { return *N; }
};
-/// \brief An imported module (C++ using directive or similar).
-class DIImportedEntity : public DIDescriptor {
-public:
- DIImportedEntity() = default;
- explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {}
- DIImportedEntity(const MDImportedEntity *N) : DIDescriptor(N) {}
+class DIImportedEntity {
+ MDImportedEntity *N;
- MDImportedEntity *get() const {
- return cast_or_null<MDImportedEntity>(DIDescriptor::get());
- }
- operator MDImportedEntity *() const { return get(); }
- MDImportedEntity *operator->() const { return get(); }
- MDImportedEntity &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+public:
+ DIImportedEntity(const MDImportedEntity *N = nullptr)
+ : N(const_cast<MDImportedEntity *>(N)) {}
- DIScope getContext() const {
- RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
- }
- DIDescriptorRef getEntity() const {
- RETURN_REF_FROM_RAW(DIDescriptorRef, N->getEntity());
- }
- unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
- StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
- bool Verify() const;
+ operator DIDescriptor() const { return N; }
+ operator MDImportedEntity *() const { return N; }
+ MDImportedEntity *operator->() const { return N; }
+ MDImportedEntity &operator*() const { return *N; }
};
-#undef RETURN_FROM_RAW
-#undef RETURN_DESCRIPTOR_FROM_RAW
-#undef RETURN_REF_FROM_RAW
+#define SIMPLIFY_DESCRIPTOR(DESC) \
+ template <> struct simplify_type<const DESC> { \
+ typedef Metadata *SimpleType; \
+ static SimpleType getSimplifiedValue(const DESC &DI) { return DI; } \
+ }; \
+ template <> struct simplify_type<DESC> : simplify_type<const DESC> {};
+SIMPLIFY_DESCRIPTOR(DIDescriptor)
+SIMPLIFY_DESCRIPTOR(DISubrange)
+SIMPLIFY_DESCRIPTOR(DIEnumerator)
+SIMPLIFY_DESCRIPTOR(DIScope)
+SIMPLIFY_DESCRIPTOR(DIType)
+SIMPLIFY_DESCRIPTOR(DIBasicType)
+SIMPLIFY_DESCRIPTOR(DIDerivedType)
+SIMPLIFY_DESCRIPTOR(DICompositeType)
+SIMPLIFY_DESCRIPTOR(DISubroutineType)
+SIMPLIFY_DESCRIPTOR(DIFile)
+SIMPLIFY_DESCRIPTOR(DICompileUnit)
+SIMPLIFY_DESCRIPTOR(DISubprogram)
+SIMPLIFY_DESCRIPTOR(DILexicalBlock)
+SIMPLIFY_DESCRIPTOR(DILexicalBlockFile)
+SIMPLIFY_DESCRIPTOR(DINameSpace)
+SIMPLIFY_DESCRIPTOR(DITemplateTypeParameter)
+SIMPLIFY_DESCRIPTOR(DITemplateValueParameter)
+SIMPLIFY_DESCRIPTOR(DIGlobalVariable)
+SIMPLIFY_DESCRIPTOR(DIVariable)
+SIMPLIFY_DESCRIPTOR(DIExpression)
+SIMPLIFY_DESCRIPTOR(DILocation)
+SIMPLIFY_DESCRIPTOR(DIObjCProperty)
+SIMPLIFY_DESCRIPTOR(DIImportedEntity)
+#undef SIMPLIFY_DESCRIPTOR
/// \brief Find subprogram that is enclosing this scope.
DISubprogram getDISubprogram(const MDNode *Scope);
@@ -1356,16 +429,6 @@ DISubprogram getDISubprogram(const Function *F);
/// \brief Find underlying composite type.
DICompositeType getDICompositeType(DIType T);
-/// \brief Create a new inlined variable based on current variable.
-///
-/// @param DV Current Variable.
-/// @param InlinedScope Location at current variable is inlined.
-DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
- LLVMContext &VMContext);
-
-/// \brief Remove inlined scope from the variable.
-DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
-
/// \brief Generate map by visiting all retained types.
DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
@@ -1375,6 +438,7 @@ DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
/// metadata for debugging. We also remove debug locations for instructions.
/// Return true if module is modified.
bool StripDebugInfo(Module &M);
+bool stripDebugInfo(Function &F);
/// \brief Return Debug Info Metadata Version by checking module flags.
unsigned getDebugMetadataVersionFromModule(const Module &M);
diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h
index d7563fc..62373c4 100644
--- a/include/llvm/IR/DebugInfoMetadata.h
+++ b/include/llvm/IR/DebugInfoMetadata.h
@@ -41,6 +41,101 @@
namespace llvm {
+/// \brief Pointer union between a subclass of DebugNode and MDString.
+///
+/// \a MDCompositeType can be referenced via an \a MDString unique identifier.
+/// This class allows some type safety in the face of that, requiring either a
+/// node of a particular type or an \a MDString.
+template <class T> class TypedDebugNodeRef {
+ const Metadata *MD = nullptr;
+
+public:
+ TypedDebugNodeRef() = default;
+ TypedDebugNodeRef(std::nullptr_t) {}
+
+ /// \brief Construct from a raw pointer.
+ explicit TypedDebugNodeRef(const Metadata *MD) : MD(MD) {
+ assert((!MD || isa<MDString>(MD) || isa<T>(MD)) && "Expected valid ref");
+ }
+
+ template <class U>
+ TypedDebugNodeRef(
+ const TypedDebugNodeRef<U> &X,
+ typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
+ nullptr)
+ : MD(X) {}
+
+ operator Metadata *() const { return const_cast<Metadata *>(MD); }
+
+ bool operator==(const TypedDebugNodeRef<T> &X) const { return MD == X.MD; };
+ bool operator!=(const TypedDebugNodeRef<T> &X) const { return MD != X.MD; };
+
+ /// \brief Create a reference.
+ ///
+ /// Get a reference to \c N, using an \a MDString reference if available.
+ static TypedDebugNodeRef get(const T *N);
+
+ template <class MapTy> T *resolve(const MapTy &Map) const {
+ if (!MD)
+ return nullptr;
+
+ if (auto *Typed = dyn_cast<T>(MD))
+ return const_cast<T *>(Typed);
+
+ auto *S = cast<MDString>(MD);
+ auto I = Map.find(S);
+ assert(I != Map.end() && "Missing identifier in type map");
+ return cast<T>(I->second);
+ }
+};
+
+typedef TypedDebugNodeRef<DebugNode> DebugNodeRef;
+typedef TypedDebugNodeRef<MDScope> MDScopeRef;
+typedef TypedDebugNodeRef<MDType> MDTypeRef;
+
+class MDTypeRefArray {
+ const MDTuple *N = nullptr;
+
+public:
+ MDTypeRefArray(const MDTuple *N) : N(N) {}
+
+ explicit operator bool() const { return get(); }
+ explicit operator MDTuple *() const { return get(); }
+
+ MDTuple *get() const { return const_cast<MDTuple *>(N); }
+ MDTuple *operator->() const { return get(); }
+ MDTuple &operator*() const { return *get(); }
+
+ // FIXME: Fix callers and remove condition on N.
+ unsigned size() const { return N ? N->getNumOperands() : 0u; }
+ MDTypeRef operator[](unsigned I) const { return MDTypeRef(N->getOperand(I)); }
+
+ class iterator : std::iterator<std::input_iterator_tag, MDTypeRef,
+ std::ptrdiff_t, void, MDTypeRef> {
+ MDNode::op_iterator I = nullptr;
+
+ public:
+ iterator() = default;
+ explicit iterator(MDNode::op_iterator I) : I(I) {}
+ MDTypeRef operator*() const { return MDTypeRef(*I); }
+ iterator &operator++() {
+ ++I;
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator Temp(*this);
+ ++I;
+ return Temp;
+ }
+ bool operator==(const iterator &X) const { return I == X.I; }
+ bool operator!=(const iterator &X) const { return I != X.I; }
+ };
+
+ // FIXME: Fix callers and remove condition on N.
+ iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
+ iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
+};
+
/// \brief Tagged DWARF-like metadata node.
///
/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
@@ -57,7 +152,7 @@ protected:
assert(Tag < 1u << 16);
SubclassData16 = Tag;
}
- ~DebugNode() {}
+ ~DebugNode() = default;
template <class Ty> Ty *getOperandAs(unsigned I) const {
return cast_or_null<Ty>(getOperand(I));
@@ -78,6 +173,28 @@ protected:
public:
unsigned getTag() const { return SubclassData16; }
+ /// \brief Debug info flags.
+ ///
+ /// The three accessibility flags are mutually exclusive and rolled together
+ /// in the first two bits.
+ enum DIFlags {
+#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
+#include "llvm/IR/DebugInfoFlags.def"
+ FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic
+ };
+
+ static unsigned getFlag(StringRef Flag);
+ static const char *getFlagString(unsigned Flag);
+
+ /// \brief Split up a flags bitfield.
+ ///
+ /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
+ /// any remaining (unrecognized) bits.
+ static unsigned splitFlags(unsigned Flags,
+ SmallVectorImpl<unsigned> &SplitFlags);
+
+ DebugNodeRef getRef() const { return DebugNodeRef::get(this); }
+
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
@@ -106,6 +223,18 @@ public:
}
};
+template <class T>
+struct simplify_type<const TypedDebugNodeRef<T>> {
+ typedef Metadata *SimpleType;
+ static SimpleType getSimplifiedValue(const TypedDebugNodeRef<T> &MD) {
+ return MD;
+ }
+};
+
+template <class T>
+struct simplify_type<TypedDebugNodeRef<T>>
+ : simplify_type<const TypedDebugNodeRef<T>> {};
+
/// \brief Generic tagged DWARF-like metadata node.
///
/// An un-specialized DWARF-like metadata node. The first operand is a
@@ -192,27 +321,30 @@ class MDSubrange : public DebugNode {
friend class MDNode;
int64_t Count;
- int64_t Lo;
+ int64_t LowerBound;
- MDSubrange(LLVMContext &C, StorageType Storage, int64_t Count, int64_t Lo)
+ MDSubrange(LLVMContext &C, StorageType Storage, int64_t Count,
+ int64_t LowerBound)
: DebugNode(C, MDSubrangeKind, Storage, dwarf::DW_TAG_subrange_type,
None),
- Count(Count), Lo(Lo) {}
- ~MDSubrange() {}
+ Count(Count), LowerBound(LowerBound) {}
+ ~MDSubrange() = default;
- static MDSubrange *getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
- StorageType Storage, bool ShouldCreate = true);
+ static MDSubrange *getImpl(LLVMContext &Context, int64_t Count,
+ int64_t LowerBound, StorageType Storage,
+ bool ShouldCreate = true);
TempMDSubrange cloneImpl() const {
- return getTemporary(getContext(), getCount(), getLo());
+ return getTemporary(getContext(), getCount(), getLowerBound());
}
public:
- DEFINE_MDNODE_GET(MDSubrange, (int64_t Count, int64_t Lo = 0), (Count, Lo))
+ DEFINE_MDNODE_GET(MDSubrange, (int64_t Count, int64_t LowerBound = 0),
+ (Count, LowerBound))
TempMDSubrange clone() const { return cloneImpl(); }
- int64_t getLo() const { return Lo; }
+ int64_t getLowerBound() const { return LowerBound; }
int64_t getCount() const { return Count; }
static bool classof(const Metadata *MD) {
@@ -234,7 +366,7 @@ class MDEnumerator : public DebugNode {
ArrayRef<Metadata *> Ops)
: DebugNode(C, MDEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
Value(Value) {}
- ~MDEnumerator() {}
+ ~MDEnumerator() = default;
static MDEnumerator *getImpl(LLVMContext &Context, int64_t Value,
StringRef Name, StorageType Storage,
@@ -279,20 +411,30 @@ protected:
MDScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
ArrayRef<Metadata *> Ops)
: DebugNode(C, ID, Storage, Tag, Ops) {}
- ~MDScope() {}
+ ~MDScope() = default;
public:
- /// \brief Return the underlying file.
+ MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
+
+ inline StringRef getFilename() const;
+ inline StringRef getDirectory() const;
+
+ StringRef getName() const;
+ MDScopeRef getScope() const;
+
+ /// \brief Return the raw underlying file.
///
/// An \a MDFile is an \a MDScope, but it doesn't point at a separate file
/// (it\em is the file). If \c this is an \a MDFile, we need to return \c
/// this. Otherwise, return the first operand, which is where all other
/// subclasses store their file pointer.
- Metadata *getFile() const {
+ Metadata *getRawFile() const {
return isa<MDFile>(this) ? const_cast<MDScope *>(this)
: static_cast<Metadata *>(getOperand(0));
}
+ MDScopeRef getRef() const { return MDScopeRef::get(this); }
+
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
@@ -322,7 +464,7 @@ class MDFile : public MDScope {
MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
: MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
- ~MDFile() {}
+ ~MDFile() = default;
static MDFile *getImpl(LLVMContext &Context, StringRef Filename,
StringRef Directory, StorageType Storage,
@@ -358,6 +500,18 @@ public:
}
};
+StringRef MDScope::getFilename() const {
+ if (auto *F = getFile())
+ return F->getFilename();
+ return "";
+}
+
+StringRef MDScope::getDirectory() const {
+ if (auto *F = getFile())
+ return F->getDirectory();
+ return "";
+}
+
/// \brief Base class for types.
///
/// TODO: Remove the hardcoded name and context, since many types don't use
@@ -377,7 +531,7 @@ protected:
: MDScope(C, ID, Storage, Tag, Ops), Line(Line), Flags(Flags),
SizeInBits(SizeInBits), AlignInBits(AlignInBits),
OffsetInBits(OffsetInBits) {}
- ~MDType() {}
+ ~MDType() = default;
public:
TempMDType clone() const {
@@ -390,9 +544,11 @@ public:
uint64_t getOffsetInBits() const { return OffsetInBits; }
unsigned getFlags() const { return Flags; }
- Metadata *getScope() const { return getOperand(1); }
+ MDScopeRef getScope() const { return MDScopeRef(getRawScope()); }
StringRef getName() const { return getStringOperand(2); }
+
+ Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
void setFlags(unsigned NewFlags) {
@@ -400,6 +556,31 @@ public:
Flags = NewFlags;
}
+ bool isPrivate() const {
+ return (getFlags() & FlagAccessibility) == FlagPrivate;
+ }
+ bool isProtected() const {
+ return (getFlags() & FlagAccessibility) == FlagProtected;
+ }
+ bool isPublic() const {
+ return (getFlags() & FlagAccessibility) == FlagPublic;
+ }
+ bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
+ bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
+ bool isBlockByrefStruct() const { return getFlags() & FlagBlockByrefStruct; }
+ bool isVirtual() const { return getFlags() & FlagVirtual; }
+ bool isArtificial() const { return getFlags() & FlagArtificial; }
+ bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
+ bool isObjcClassComplete() const {
+ return getFlags() & FlagObjcClassComplete;
+ }
+ bool isVector() const { return getFlags() & FlagVector; }
+ bool isStaticMember() const { return getFlags() & FlagStaticMember; }
+ bool isLValueReference() const { return getFlags() & FlagLValueReference; }
+ bool isRValueReference() const { return getFlags() & FlagRValueReference; }
+
+ MDTypeRef getRef() const { return MDTypeRef::get(this); }
+
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
@@ -413,7 +594,7 @@ public:
}
};
-/// \brief Basic type.
+/// \brief Basic type, like 'int' or 'float'.
///
/// TODO: Split out DW_TAG_unspecified_type.
/// TODO: Drop unused accessors.
@@ -429,7 +610,7 @@ class MDBasicType : public MDType {
: MDType(C, MDBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
0, Ops),
Encoding(Encoding) {}
- ~MDBasicType() {}
+ ~MDBasicType() = default;
static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Name, uint64_t SizeInBits,
@@ -480,10 +661,11 @@ protected:
ArrayRef<Metadata *> Ops)
: MDType(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
Flags, Ops) {}
- ~MDDerivedTypeBase() {}
+ ~MDDerivedTypeBase() = default;
public:
- Metadata *getBaseType() const { return getOperand(3); }
+ MDTypeRef getBaseType() const { return MDTypeRef(getRawBaseType()); }
+ Metadata *getRawBaseType() const { return getOperand(3); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDDerivedTypeKind ||
@@ -507,11 +689,11 @@ class MDDerivedType : public MDDerivedTypeBase {
uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
: MDDerivedTypeBase(C, MDDerivedTypeKind, Storage, Tag, Line, SizeInBits,
AlignInBits, OffsetInBits, Flags, Ops) {}
- ~MDDerivedType() {}
+ ~MDDerivedType() = default;
static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
- StringRef Name, Metadata *File, unsigned Line,
- Metadata *Scope, Metadata *BaseType,
+ StringRef Name, MDFile *File, unsigned Line,
+ MDScopeRef Scope, MDTypeRef BaseType,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
Metadata *ExtraData, StorageType Storage,
@@ -545,11 +727,10 @@ public:
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, ExtraData))
DEFINE_MDNODE_GET(MDDerivedType,
- (unsigned Tag, StringRef Name, Metadata *File,
- unsigned Line, Metadata *Scope, Metadata *BaseType,
- uint64_t SizeInBits, uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- Metadata *ExtraData = nullptr),
+ (unsigned Tag, StringRef Name, MDFile *File, unsigned Line,
+ MDScopeRef Scope, MDTypeRef BaseType, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, Metadata *ExtraData = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, ExtraData))
@@ -562,7 +743,25 @@ public:
///
/// TODO: Separate out types that need this extra operand: pointer-to-member
/// types and member fields (static members and ivars).
- Metadata *getExtraData() const { return getOperand(4); }
+ Metadata *getExtraData() const { return getRawExtraData(); }
+ Metadata *getRawExtraData() const { return getOperand(4); }
+
+ /// \brief Get casted version of extra data.
+ /// @{
+ MDTypeRef getClassType() const {
+ assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
+ return MDTypeRef(getExtraData());
+ }
+ MDObjCProperty *getObjCProperty() const {
+ return dyn_cast_or_null<MDObjCProperty>(getExtraData());
+ }
+ Constant *getConstant() const {
+ assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
+ if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
+ return C->getValue();
+ return nullptr;
+ }
+ /// @}
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDDerivedTypeKind;
@@ -584,15 +783,28 @@ protected:
: MDDerivedTypeBase(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits,
OffsetInBits, Flags, Ops),
RuntimeLang(RuntimeLang) {}
- ~MDCompositeTypeBase() {}
+ ~MDCompositeTypeBase() = default;
public:
- Metadata *getElements() const { return getOperand(4); }
- Metadata *getVTableHolder() const { return getOperand(5); }
- Metadata *getTemplateParams() const { return getOperand(6); }
+ /// \brief Get the elements of the composite type.
+ ///
+ /// \note Calling this is only valid for \a MDCompositeType. This assertion
+ /// can be removed once \a MDSubroutineType has been separated from
+ /// "composite types".
+ DebugNodeArray getElements() const {
+ assert(!isa<MDSubroutineType>(this) && "no elements for DISubroutineType");
+ return cast_or_null<MDTuple>(getRawElements());
+ }
+ MDTypeRef getVTableHolder() const { return MDTypeRef(getRawVTableHolder()); }
+ MDTemplateParameterArray getTemplateParams() const {
+ return cast_or_null<MDTuple>(getRawTemplateParams());
+ }
StringRef getIdentifier() const { return getStringOperand(7); }
unsigned getRuntimeLang() const { return RuntimeLang; }
+ Metadata *getRawElements() const { return getOperand(4); }
+ Metadata *getRawVTableHolder() const { return getOperand(5); }
+ Metadata *getRawTemplateParams() const { return getOperand(6); }
MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
/// \brief Replace operands.
@@ -601,20 +813,19 @@ public:
/// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
/// of its movement if necessary.
/// @{
- void replaceElements(MDTuple *Elements) {
+ void replaceElements(DebugNodeArray Elements) {
#ifndef NDEBUG
- if (auto *Old = cast_or_null<MDTuple>(getElements()))
- for (const auto &Op : Old->operands())
- assert(std::find(Elements->op_begin(), Elements->op_end(), Op) &&
- "Lost a member during member list replacement");
+ for (DebugNode *Op : getElements())
+ assert(std::find(Elements->op_begin(), Elements->op_end(), Op) &&
+ "Lost a member during member list replacement");
#endif
- replaceOperandWith(4, Elements);
+ replaceOperandWith(4, Elements.get());
}
- void replaceVTableHolder(Metadata *VTableHolder) {
+ void replaceVTableHolder(MDTypeRef VTableHolder) {
replaceOperandWith(5, VTableHolder);
}
- void replaceTemplateParams(MDTuple *TemplateParams) {
- replaceOperandWith(6, TemplateParams);
+ void replaceTemplateParams(MDTemplateParameterArray TemplateParams) {
+ replaceOperandWith(6, TemplateParams.get());
}
/// @}
@@ -639,20 +850,20 @@ class MDCompositeType : public MDCompositeTypeBase {
: MDCompositeTypeBase(C, MDCompositeTypeKind, Storage, Tag, Line,
RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
Flags, Ops) {}
- ~MDCompositeType() {}
+ ~MDCompositeType() = default;
static MDCompositeType *
getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
- unsigned Line, Metadata *Scope, Metadata *BaseType,
+ unsigned Line, MDScopeRef Scope, MDTypeRef BaseType,
uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
- uint64_t Flags, Metadata *Elements, unsigned RuntimeLang,
- Metadata *VTableHolder, Metadata *TemplateParams,
+ uint64_t Flags, DebugNodeArray Elements, unsigned RuntimeLang,
+ MDTypeRef VTableHolder, MDTemplateParameterArray TemplateParams,
StringRef Identifier, StorageType Storage, bool ShouldCreate = true) {
- return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
- Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
- Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
- getCanonicalMDString(Context, Identifier), Storage,
- ShouldCreate);
+ return getImpl(
+ Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
+ RuntimeLang, VTableHolder, TemplateParams.get(),
+ getCanonicalMDString(Context, Identifier), Storage, ShouldCreate);
}
static MDCompositeType *
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
@@ -672,12 +883,12 @@ class MDCompositeType : public MDCompositeTypeBase {
public:
DEFINE_MDNODE_GET(MDCompositeType,
- (unsigned Tag, StringRef Name, Metadata *File,
- unsigned Line, Metadata *Scope, Metadata *BaseType,
- uint64_t SizeInBits, uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags, Metadata *Elements,
- unsigned RuntimeLang, Metadata *VTableHolder,
- Metadata *TemplateParams = nullptr,
+ (unsigned Tag, StringRef Name, MDFile *File, unsigned Line,
+ MDScopeRef Scope, MDTypeRef BaseType, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, DebugNodeArray Elements,
+ unsigned RuntimeLang, MDTypeRef VTableHolder,
+ MDTemplateParameterArray TemplateParams = nullptr,
StringRef Identifier = ""),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
@@ -701,6 +912,14 @@ public:
}
};
+template <class T> TypedDebugNodeRef<T> TypedDebugNodeRef<T>::get(const T *N) {
+ if (N)
+ if (auto *Composite = dyn_cast<MDCompositeType>(N))
+ if (auto *S = Composite->getRawIdentifier())
+ return TypedDebugNodeRef<T>(S);
+ return TypedDebugNodeRef<T>(N);
+}
+
/// \brief Type array for a subprogram.
///
/// TODO: Detach from CompositeType, and fold the array of types in directly
@@ -714,9 +933,15 @@ class MDSubroutineType : public MDCompositeTypeBase {
: MDCompositeTypeBase(C, MDSubroutineTypeKind, Storage,
dwarf::DW_TAG_subroutine_type, 0, 0, 0, 0, 0, Flags,
Ops) {}
- ~MDSubroutineType() {}
+ ~MDSubroutineType() = default;
static MDSubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
+ MDTypeRefArray TypeArray,
+ StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Flags, TypeArray.get(), Storage, ShouldCreate);
+ }
+ static MDSubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
Metadata *TypeArray, StorageType Storage,
bool ShouldCreate = true);
@@ -725,12 +950,18 @@ class MDSubroutineType : public MDCompositeTypeBase {
}
public:
+ DEFINE_MDNODE_GET(MDSubroutineType,
+ (unsigned Flags, MDTypeRefArray TypeArray),
+ (Flags, TypeArray))
DEFINE_MDNODE_GET(MDSubroutineType, (unsigned Flags, Metadata *TypeArray),
(Flags, TypeArray))
TempMDSubroutineType clone() const { return cloneImpl(); }
- Metadata *getTypeArray() const { return getElements(); }
+ MDTypeRefArray getTypeArray() const {
+ return cast_or_null<MDTuple>(getRawTypeArray());
+ }
+ Metadata *getRawTypeArray() const { return getRawElements(); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDSubroutineTypeKind;
@@ -753,22 +984,23 @@ class MDCompileUnit : public MDScope {
: MDScope(C, MDCompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind) {}
- ~MDCompileUnit() {}
+ ~MDCompileUnit() = default;
static MDCompileUnit *
- getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
+ getImpl(LLVMContext &Context, unsigned SourceLanguage, MDFile *File,
StringRef Producer, bool IsOptimized, StringRef Flags,
unsigned RuntimeVersion, StringRef SplitDebugFilename,
- unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
- Metadata *Subprograms, Metadata *GlobalVariables,
- Metadata *ImportedEntities, StorageType Storage,
+ unsigned EmissionKind, MDCompositeTypeArray EnumTypes,
+ MDTypeArray RetainedTypes, MDSubprogramArray Subprograms,
+ MDGlobalVariableArray GlobalVariables,
+ MDImportedEntityArray ImportedEntities, StorageType Storage,
bool ShouldCreate = true) {
- return getImpl(Context, SourceLanguage, File,
- getCanonicalMDString(Context, Producer), IsOptimized,
- getCanonicalMDString(Context, Flags), RuntimeVersion,
- getCanonicalMDString(Context, SplitDebugFilename),
- EmissionKind, EnumTypes, RetainedTypes, Subprograms,
- GlobalVariables, ImportedEntities, Storage, ShouldCreate);
+ return getImpl(
+ Context, SourceLanguage, File, getCanonicalMDString(Context, Producer),
+ IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion,
+ getCanonicalMDString(Context, SplitDebugFilename), EmissionKind,
+ EnumTypes.get(), RetainedTypes.get(), Subprograms.get(),
+ GlobalVariables.get(), ImportedEntities.get(), Storage, ShouldCreate);
}
static MDCompileUnit *
getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
@@ -789,12 +1021,13 @@ class MDCompileUnit : public MDScope {
public:
DEFINE_MDNODE_GET(MDCompileUnit,
- (unsigned SourceLanguage, Metadata *File,
- StringRef Producer, bool IsOptimized, StringRef Flags,
- unsigned RuntimeVersion, StringRef SplitDebugFilename,
- unsigned EmissionKind, Metadata *EnumTypes,
- Metadata *RetainedTypes, Metadata *Subprograms,
- Metadata *GlobalVariables, Metadata *ImportedEntities),
+ (unsigned SourceLanguage, MDFile *File, StringRef Producer,
+ bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
+ StringRef SplitDebugFilename, unsigned EmissionKind,
+ MDCompositeTypeArray EnumTypes, MDTypeArray RetainedTypes,
+ MDSubprogramArray Subprograms,
+ MDGlobalVariableArray GlobalVariables,
+ MDImportedEntityArray ImportedEntities),
(SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind,
EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
@@ -820,17 +1053,32 @@ public:
StringRef getProducer() const { return getStringOperand(1); }
StringRef getFlags() const { return getStringOperand(2); }
StringRef getSplitDebugFilename() const { return getStringOperand(3); }
- Metadata *getEnumTypes() const { return getOperand(4); }
- Metadata *getRetainedTypes() const { return getOperand(5); }
- Metadata *getSubprograms() const { return getOperand(6); }
- Metadata *getGlobalVariables() const { return getOperand(7); }
- Metadata *getImportedEntities() const { return getOperand(8); }
+ MDCompositeTypeArray getEnumTypes() const {
+ return cast_or_null<MDTuple>(getRawEnumTypes());
+ }
+ MDTypeArray getRetainedTypes() const {
+ return cast_or_null<MDTuple>(getRawRetainedTypes());
+ }
+ MDSubprogramArray getSubprograms() const {
+ return cast_or_null<MDTuple>(getRawSubprograms());
+ }
+ MDGlobalVariableArray getGlobalVariables() const {
+ return cast_or_null<MDTuple>(getRawGlobalVariables());
+ }
+ MDImportedEntityArray getImportedEntities() const {
+ return cast_or_null<MDTuple>(getRawImportedEntities());
+ }
MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
MDString *getRawSplitDebugFilename() const {
return getOperandAs<MDString>(3);
}
+ Metadata *getRawEnumTypes() const { return getOperand(4); }
+ Metadata *getRawRetainedTypes() const { return getOperand(5); }
+ Metadata *getRawSubprograms() const { return getOperand(6); }
+ Metadata *getRawGlobalVariables() const { return getOperand(7); }
+ Metadata *getRawImportedEntities() const { return getOperand(8); }
/// \brief Replace arrays.
///
@@ -838,8 +1086,12 @@ public:
/// deleted on a uniquing collision. In practice, uniquing collisions on \a
/// MDCompileUnit should be fairly rare.
/// @{
- void replaceSubprograms(MDTuple *N) { replaceOperandWith(6, N); }
- void replaceGlobalVariables(MDTuple *N) { replaceOperandWith(7, N); }
+ void replaceSubprograms(MDSubprogramArray N) {
+ replaceOperandWith(6, N.get());
+ }
+ void replaceGlobalVariables(MDGlobalVariableArray N) {
+ replaceOperandWith(7, N.get());
+ }
/// @}
static bool classof(const Metadata *MD) {
@@ -857,9 +1109,15 @@ protected:
MDLocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
ArrayRef<Metadata *> Ops)
: MDScope(C, ID, Storage, Tag, Ops) {}
- ~MDLocalScope() {}
+ ~MDLocalScope() = default;
public:
+ /// \brief Get the subprogram for this scope.
+ ///
+ /// Return this if it's an \a MDSubprogram; otherwise, look up the scope
+ /// chain.
+ MDSubprogram *getSubprogram() const;
+
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDSubprogramKind ||
MD->getMetadataID() == MDLexicalBlockKind ||
@@ -914,12 +1172,58 @@ public:
unsigned getLine() const { return SubclassData32; }
unsigned getColumn() const { return SubclassData16; }
MDLocalScope *getScope() const {
- return cast_or_null<MDLocalScope>(getRawScope());
+ return cast<MDLocalScope>(getRawScope());
}
MDLocation *getInlinedAt() const {
return cast_or_null<MDLocation>(getRawInlinedAt());
}
+ MDFile *getFile() const { return getScope()->getFile(); }
+ StringRef getFilename() const { return getScope()->getFilename(); }
+ StringRef getDirectory() const { return getScope()->getDirectory(); }
+
+ /// \brief Get the scope where this is inlined.
+ ///
+ /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
+ /// location.
+ MDLocalScope *getInlinedAtScope() const {
+ if (auto *IA = getInlinedAt())
+ return IA->getInlinedAtScope();
+ return getScope();
+ }
+
+ /// \brief Check whether this can be discriminated from another location.
+ ///
+ /// Check \c this can be discriminated from \c RHS in a linetable entry.
+ /// Scope and inlined-at chains are not recorded in the linetable, so they
+ /// cannot be used to distinguish basic blocks.
+ ///
+ /// The current implementation is weaker than it should be, since it just
+ /// checks filename and line.
+ ///
+ /// FIXME: Add a check for getDiscriminator().
+ /// FIXME: Add a check for getColumn().
+ /// FIXME: Change the getFilename() check to getFile() (or add one for
+ /// getDirectory()).
+ bool canDiscriminate(const MDLocation &RHS) const {
+ return getFilename() != RHS.getFilename() || getLine() != RHS.getLine();
+ }
+
+ /// \brief Get the DWARF discriminator.
+ ///
+ /// DWARF discriminators distinguish identical file locations between
+ /// instructions that are on different basic blocks.
+ inline unsigned getDiscriminator() const;
+
+ /// \brief Compute new discriminator in the given context.
+ ///
+ /// This modifies the \a LLVMContext that \c this is in to increment the next
+ /// discriminator for \c this's line/filename combination.
+ ///
+ /// FIXME: Delete this. See comments in implementation and at the only call
+ /// site in \a AddDiscriminators::runOnFunction().
+ unsigned computeNewDiscriminator() const;
+
Metadata *getRawScope() const { return getOperand(0); }
Metadata *getRawInlinedAt() const {
if (getNumOperands() == 2)
@@ -958,21 +1262,23 @@ class MDSubprogram : public MDLocalScope {
Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality),
VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit),
IsDefinition(IsDefinition), IsOptimized(IsOptimized) {}
- ~MDSubprogram() {}
+ ~MDSubprogram() = default;
static MDSubprogram *
- getImpl(LLVMContext &Context, Metadata *Scope, StringRef Name,
- StringRef LinkageName, Metadata *File, unsigned Line, Metadata *Type,
- bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
- Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
- unsigned Flags, bool IsOptimized, Metadata *Function,
- Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
+ getImpl(LLVMContext &Context, MDScopeRef Scope, StringRef Name,
+ StringRef LinkageName, MDFile *File, unsigned Line,
+ MDSubroutineType *Type, bool IsLocalToUnit, bool IsDefinition,
+ unsigned ScopeLine, MDTypeRef ContainingType, unsigned Virtuality,
+ unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
+ Constant *Function, MDTemplateParameterArray TemplateParams,
+ MDSubprogram *Declaration, MDLocalVariableArray Variables,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, LinkageName), File, Line, Type,
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
- Virtuality, VirtualIndex, Flags, IsOptimized, Function,
- TemplateParams, Declaration, Variables, Storage,
+ Virtuality, VirtualIndex, Flags, IsOptimized,
+ Function ? ConstantAsMetadata::get(Function) : nullptr,
+ TemplateParams.get(), Declaration, Variables.get(), Storage,
ShouldCreate);
}
static MDSubprogram *
@@ -989,22 +1295,25 @@ class MDSubprogram : public MDLocalScope {
getFile(), getLine(), getType(), isLocalToUnit(),
isDefinition(), getScopeLine(), getContainingType(),
getVirtuality(), getVirtualIndex(), getFlags(),
- isOptimized(), getFunction(), getTemplateParams(),
- getDeclaration(), getVariables());
+ isOptimized(), getFunctionConstant(),
+ getTemplateParams(), getDeclaration(), getVariables());
}
public:
- DEFINE_MDNODE_GET(
- MDSubprogram,
- (Metadata * Scope, StringRef Name, StringRef LinkageName, Metadata *File,
- unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
- unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality,
- unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
- Metadata *Function = nullptr, Metadata *TemplateParams = nullptr,
- Metadata *Declaration = nullptr, Metadata *Variables = nullptr),
- (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
- ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized,
- Function, TemplateParams, Declaration, Variables))
+ DEFINE_MDNODE_GET(MDSubprogram,
+ (MDScopeRef Scope, StringRef Name, StringRef LinkageName,
+ MDFile *File, unsigned Line, MDSubroutineType *Type,
+ bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
+ MDTypeRef ContainingType, unsigned Virtuality,
+ unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
+ Constant *Function = nullptr,
+ MDTemplateParameterArray TemplateParams = nullptr,
+ MDSubprogram *Declaration = nullptr,
+ MDLocalVariableArray Variables = nullptr),
+ (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
+ IsDefinition, ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables))
DEFINE_MDNODE_GET(
MDSubprogram,
(Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
@@ -1029,7 +1338,36 @@ public:
bool isDefinition() const { return IsDefinition; }
bool isOptimized() const { return IsOptimized; }
- Metadata *getScope() const { return getOperand(1); }
+ unsigned isArtificial() const { return getFlags() & FlagArtificial; }
+ bool isPrivate() const {
+ return (getFlags() & FlagAccessibility) == FlagPrivate;
+ }
+ bool isProtected() const {
+ return (getFlags() & FlagAccessibility) == FlagProtected;
+ }
+ bool isPublic() const {
+ return (getFlags() & FlagAccessibility) == FlagPublic;
+ }
+ bool isExplicit() const { return getFlags() & FlagExplicit; }
+ bool isPrototyped() const { return getFlags() & FlagPrototyped; }
+
+ /// \brief Check if this is reference-qualified.
+ ///
+ /// Return true if this subprogram is a C++11 reference-qualified non-static
+ /// member function (void foo() &).
+ unsigned isLValueReference() const {
+ return getFlags() & FlagLValueReference;
+ }
+
+ /// \brief Check if this is rvalue-reference-qualified.
+ ///
+ /// Return true if this subprogram is a C++11 rvalue-reference-qualified
+ /// non-static member function (void foo() &&).
+ unsigned isRValueReference() const {
+ return getFlags() & FlagRValueReference;
+ }
+
+ MDScopeRef getScope() const { return MDScopeRef(getRawScope()); }
StringRef getName() const { return getStringOperand(2); }
StringRef getDisplayName() const { return getStringOperand(3); }
@@ -1038,13 +1376,42 @@ public:
MDString *getRawName() const { return getOperandAs<MDString>(2); }
MDString *getRawLinkageName() const { return getOperandAs<MDString>(4); }
- Metadata *getType() const { return getOperand(5); }
- Metadata *getContainingType() const { return getOperand(6); }
+ MDSubroutineType *getType() const {
+ return cast_or_null<MDSubroutineType>(getRawType());
+ }
+ MDTypeRef getContainingType() const {
+ return MDTypeRef(getRawContainingType());
+ }
- Metadata *getFunction() const { return getOperand(7); }
- Metadata *getTemplateParams() const { return getOperand(8); }
- Metadata *getDeclaration() const { return getOperand(9); }
- Metadata *getVariables() const { return getOperand(10); }
+ Constant *getFunctionConstant() const {
+ if (auto *C = cast_or_null<ConstantAsMetadata>(getRawFunction()))
+ return C->getValue();
+ return nullptr;
+ }
+ MDTemplateParameterArray getTemplateParams() const {
+ return cast_or_null<MDTuple>(getRawTemplateParams());
+ }
+ MDSubprogram *getDeclaration() const {
+ return cast_or_null<MDSubprogram>(getRawDeclaration());
+ }
+ MDLocalVariableArray getVariables() const {
+ return cast_or_null<MDTuple>(getRawVariables());
+ }
+
+ Metadata *getRawScope() const { return getOperand(1); }
+ Metadata *getRawType() const { return getOperand(5); }
+ Metadata *getRawContainingType() const { return getOperand(6); }
+ Metadata *getRawFunction() const { return getOperand(7); }
+ Metadata *getRawTemplateParams() const { return getOperand(8); }
+ Metadata *getRawDeclaration() const { return getOperand(9); }
+ Metadata *getRawVariables() const { return getOperand(10); }
+
+ /// \brief Get a pointer to the function this subprogram describes.
+ ///
+ /// This dyn_casts \a getFunctionConstant() to \a Function.
+ ///
+ /// FIXME: Should this be looking through bitcasts?
+ Function *getFunction() const;
/// \brief Replace the function.
///
@@ -1057,6 +1424,11 @@ public:
void replaceFunction(std::nullptr_t) { replaceOperandWith(7, nullptr); }
/// @}
+ /// \brief Check if this subprogram decribes the given function.
+ ///
+ /// FIXME: Should this be looking through bitcasts?
+ bool describes(const Function *F) const;
+
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDSubprogramKind;
}
@@ -1067,11 +1439,20 @@ protected:
MDLexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
ArrayRef<Metadata *> Ops)
: MDLocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
- ~MDLexicalBlockBase() {}
+ ~MDLexicalBlockBase() = default;
public:
- Metadata *getScope() const { return getOperand(1); }
+ MDLocalScope *getScope() const { return cast<MDLocalScope>(getRawScope()); }
+ Metadata *getRawScope() const { return getOperand(1); }
+
+ /// \brief Forwarding accessors to LexicalBlock.
+ ///
+ /// TODO: Remove these and update code to use \a MDLexicalBlock directly.
+ /// @{
+ inline unsigned getLine() const;
+ inline unsigned getColumn() const;
+ /// @}
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDLexicalBlockKind ||
MD->getMetadataID() == MDLexicalBlockFileKind;
@@ -1089,7 +1470,16 @@ class MDLexicalBlock : public MDLexicalBlockBase {
unsigned Column, ArrayRef<Metadata *> Ops)
: MDLexicalBlockBase(C, MDLexicalBlockKind, Storage, Ops), Line(Line),
Column(Column) {}
- ~MDLexicalBlock() {}
+ ~MDLexicalBlock() = default;
+
+ static MDLexicalBlock *getImpl(LLVMContext &Context, MDLocalScope *Scope,
+ MDFile *File, unsigned Line, unsigned Column,
+ StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, static_cast<Metadata *>(Scope),
+ static_cast<Metadata *>(File), Line, Column, Storage,
+ ShouldCreate);
+ }
static MDLexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Line, unsigned Column,
@@ -1101,6 +1491,9 @@ class MDLexicalBlock : public MDLexicalBlockBase {
}
public:
+ DEFINE_MDNODE_GET(MDLexicalBlock, (MDLocalScope * Scope, MDFile *File,
+ unsigned Line, unsigned Column),
+ (Scope, File, Line, Column))
DEFINE_MDNODE_GET(MDLexicalBlock, (Metadata * Scope, Metadata *File,
unsigned Line, unsigned Column),
(Scope, File, Line, Column))
@@ -1115,6 +1508,18 @@ public:
}
};
+unsigned MDLexicalBlockBase::getLine() const {
+ if (auto *N = dyn_cast<MDLexicalBlock>(this))
+ return N->getLine();
+ return 0;
+}
+
+unsigned MDLexicalBlockBase::getColumn() const {
+ if (auto *N = dyn_cast<MDLexicalBlock>(this))
+ return N->getColumn();
+ return 0;
+}
+
class MDLexicalBlockFile : public MDLexicalBlockBase {
friend class LLVMContextImpl;
friend class MDNode;
@@ -1125,7 +1530,16 @@ class MDLexicalBlockFile : public MDLexicalBlockBase {
unsigned Discriminator, ArrayRef<Metadata *> Ops)
: MDLexicalBlockBase(C, MDLexicalBlockFileKind, Storage, Ops),
Discriminator(Discriminator) {}
- ~MDLexicalBlockFile() {}
+ ~MDLexicalBlockFile() = default;
+
+ static MDLexicalBlockFile *getImpl(LLVMContext &Context, MDLocalScope *Scope,
+ MDFile *File, unsigned Discriminator,
+ StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, static_cast<Metadata *>(Scope),
+ static_cast<Metadata *>(File), Discriminator, Storage,
+ ShouldCreate);
+ }
static MDLexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Discriminator,
@@ -1138,12 +1552,19 @@ class MDLexicalBlockFile : public MDLexicalBlockBase {
}
public:
+ DEFINE_MDNODE_GET(MDLexicalBlockFile, (MDLocalScope * Scope, MDFile *File,
+ unsigned Discriminator),
+ (Scope, File, Discriminator))
DEFINE_MDNODE_GET(MDLexicalBlockFile,
(Metadata * Scope, Metadata *File, unsigned Discriminator),
(Scope, File, Discriminator))
TempMDLexicalBlockFile clone() const { return cloneImpl(); }
+ // TODO: Remove these once they're gone from MDLexicalBlockBase.
+ unsigned getLine() const = delete;
+ unsigned getColumn() const = delete;
+
unsigned getDiscriminator() const { return Discriminator; }
static bool classof(const Metadata *MD) {
@@ -1151,6 +1572,12 @@ public:
}
};
+unsigned MDLocation::getDiscriminator() const {
+ if (auto *F = dyn_cast<MDLexicalBlockFile>(getScope()))
+ return F->getDiscriminator();
+ return 0;
+}
+
class MDNamespace : public MDScope {
friend class LLVMContextImpl;
friend class MDNode;
@@ -1162,10 +1589,10 @@ class MDNamespace : public MDScope {
: MDScope(Context, MDNamespaceKind, Storage, dwarf::DW_TAG_namespace,
Ops),
Line(Line) {}
- ~MDNamespace() {}
+ ~MDNamespace() = default;
- static MDNamespace *getImpl(LLVMContext &Context, Metadata *Scope,
- Metadata *File, StringRef Name, unsigned Line,
+ static MDNamespace *getImpl(LLVMContext &Context, MDScope *Scope,
+ MDFile *File, StringRef Name, unsigned Line,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Scope, File, getCanonicalMDString(Context, Name),
Line, Storage, ShouldCreate);
@@ -1180,8 +1607,8 @@ class MDNamespace : public MDScope {
}
public:
- DEFINE_MDNODE_GET(MDNamespace, (Metadata * Scope, Metadata *File,
- StringRef Name, unsigned Line),
+ DEFINE_MDNODE_GET(MDNamespace, (MDScope * Scope, MDFile *File, StringRef Name,
+ unsigned Line),
(Scope, File, Name, Line))
DEFINE_MDNODE_GET(MDNamespace, (Metadata * Scope, Metadata *File,
MDString *Name, unsigned Line),
@@ -1190,9 +1617,10 @@ public:
TempMDNamespace clone() const { return cloneImpl(); }
unsigned getLine() const { return Line; }
- Metadata *getScope() const { return getOperand(1); }
+ MDScope *getScope() const { return cast_or_null<MDScope>(getRawScope()); }
StringRef getName() const { return getStringOperand(2); }
+ Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
static bool classof(const Metadata *MD) {
@@ -1206,13 +1634,14 @@ protected:
MDTemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
unsigned Tag, ArrayRef<Metadata *> Ops)
: DebugNode(Context, ID, Storage, Tag, Ops) {}
- ~MDTemplateParameter() {}
+ ~MDTemplateParameter() = default;
public:
StringRef getName() const { return getStringOperand(0); }
- Metadata *getType() const { return getOperand(1); }
+ MDTypeRef getType() const { return MDTypeRef(getRawType()); }
MDString *getRawName() const { return getOperandAs<MDString>(0); }
+ Metadata *getRawType() const { return getOperand(1); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDTemplateTypeParameterKind ||
@@ -1228,10 +1657,10 @@ class MDTemplateTypeParameter : public MDTemplateParameter {
ArrayRef<Metadata *> Ops)
: MDTemplateParameter(Context, MDTemplateTypeParameterKind, Storage,
dwarf::DW_TAG_template_type_parameter, Ops) {}
- ~MDTemplateTypeParameter() {}
+ ~MDTemplateTypeParameter() = default;
static MDTemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
- Metadata *Type, StorageType Storage,
+ MDTypeRef Type, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
ShouldCreate);
@@ -1245,7 +1674,7 @@ class MDTemplateTypeParameter : public MDTemplateParameter {
}
public:
- DEFINE_MDNODE_GET(MDTemplateTypeParameter, (StringRef Name, Metadata *Type),
+ DEFINE_MDNODE_GET(MDTemplateTypeParameter, (StringRef Name, MDTypeRef Type),
(Name, Type))
DEFINE_MDNODE_GET(MDTemplateTypeParameter, (MDString * Name, Metadata *Type),
(Name, Type))
@@ -1265,10 +1694,10 @@ class MDTemplateValueParameter : public MDTemplateParameter {
unsigned Tag, ArrayRef<Metadata *> Ops)
: MDTemplateParameter(Context, MDTemplateValueParameterKind, Storage, Tag,
Ops) {}
- ~MDTemplateValueParameter() {}
+ ~MDTemplateValueParameter() = default;
static MDTemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
- StringRef Name, Metadata *Type,
+ StringRef Name, MDTypeRef Type,
Metadata *Value, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
@@ -1286,7 +1715,7 @@ class MDTemplateValueParameter : public MDTemplateParameter {
public:
DEFINE_MDNODE_GET(MDTemplateValueParameter, (unsigned Tag, StringRef Name,
- Metadata *Type, Metadata *Value),
+ MDTypeRef Type, Metadata *Value),
(Tag, Name, Type, Value))
DEFINE_MDNODE_GET(MDTemplateValueParameter, (unsigned Tag, MDString *Name,
Metadata *Type, Metadata *Value),
@@ -1311,16 +1740,30 @@ protected:
MDVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
unsigned Line, ArrayRef<Metadata *> Ops)
: DebugNode(C, ID, Storage, Tag, Ops), Line(Line) {}
- ~MDVariable() {}
+ ~MDVariable() = default;
public:
unsigned getLine() const { return Line; }
- Metadata *getScope() const { return getOperand(0); }
+ MDScope *getScope() const { return cast_or_null<MDScope>(getRawScope()); }
StringRef getName() const { return getStringOperand(1); }
- Metadata *getFile() const { return getOperand(2); }
- Metadata *getType() const { return getOperand(3); }
+ MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
+ MDTypeRef getType() const { return MDTypeRef(getRawType()); }
+
+ StringRef getFilename() const {
+ if (auto *F = getFile())
+ return F->getFilename();
+ return "";
+ }
+ StringRef getDirectory() const {
+ if (auto *F = getFile())
+ return F->getDirectory();
+ return "";
+ }
+ Metadata *getRawScope() const { return getOperand(0); }
MDString *getRawName() const { return getOperandAs<MDString>(1); }
+ Metadata *getRawFile() const { return getOperand(2); }
+ Metadata *getRawType() const { return getOperand(3); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDLocalVariableKind ||
@@ -1344,17 +1787,18 @@ class MDGlobalVariable : public MDVariable {
: MDVariable(C, MDGlobalVariableKind, Storage, dwarf::DW_TAG_variable,
Line, Ops),
IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
- ~MDGlobalVariable() {}
+ ~MDGlobalVariable() = default;
static MDGlobalVariable *
- getImpl(LLVMContext &Context, Metadata *Scope, StringRef Name,
- StringRef LinkageName, Metadata *File, unsigned Line, Metadata *Type,
- bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
- Metadata *StaticDataMemberDeclaration, StorageType Storage,
+ getImpl(LLVMContext &Context, MDScope *Scope, StringRef Name,
+ StringRef LinkageName, MDFile *File, unsigned Line, MDTypeRef Type,
+ bool IsLocalToUnit, bool IsDefinition, Constant *Variable,
+ MDDerivedType *StaticDataMemberDeclaration, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, LinkageName), File, Line, Type,
- IsLocalToUnit, IsDefinition, Variable,
+ IsLocalToUnit, IsDefinition,
+ Variable ? ConstantAsMetadata::get(Variable) : nullptr,
StaticDataMemberDeclaration, Storage, ShouldCreate);
}
static MDGlobalVariable *
@@ -1373,10 +1817,10 @@ class MDGlobalVariable : public MDVariable {
public:
DEFINE_MDNODE_GET(MDGlobalVariable,
- (Metadata * Scope, StringRef Name, StringRef LinkageName,
- Metadata *File, unsigned Line, Metadata *Type,
- bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
- Metadata *StaticDataMemberDeclaration),
+ (MDScope * Scope, StringRef Name, StringRef LinkageName,
+ MDFile *File, unsigned Line, MDTypeRef Type,
+ bool IsLocalToUnit, bool IsDefinition, Constant *Variable,
+ MDDerivedType *StaticDataMemberDeclaration),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, Variable, StaticDataMemberDeclaration))
DEFINE_MDNODE_GET(MDGlobalVariable,
@@ -1393,10 +1837,18 @@ public:
bool isDefinition() const { return IsDefinition; }
StringRef getDisplayName() const { return getStringOperand(4); }
StringRef getLinkageName() const { return getStringOperand(5); }
- Metadata *getVariable() const { return getOperand(6); }
- Metadata *getStaticDataMemberDeclaration() const { return getOperand(7); }
+ Constant *getVariable() const {
+ if (auto *C = cast_or_null<ConstantAsMetadata>(getRawVariable()))
+ return dyn_cast<Constant>(C->getValue());
+ return nullptr;
+ }
+ MDDerivedType *getStaticDataMemberDeclaration() const {
+ return cast_or_null<MDDerivedType>(getRawStaticDataMemberDeclaration());
+ }
MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
+ Metadata *getRawVariable() const { return getOperand(6); }
+ Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(7); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDGlobalVariableKind;
@@ -1420,62 +1872,61 @@ class MDLocalVariable : public MDVariable {
ArrayRef<Metadata *> Ops)
: MDVariable(C, MDLocalVariableKind, Storage, Tag, Line, Ops), Arg(Arg),
Flags(Flags) {}
- ~MDLocalVariable() {}
+ ~MDLocalVariable() = default;
static MDLocalVariable *getImpl(LLVMContext &Context, unsigned Tag,
- Metadata *Scope, StringRef Name,
- Metadata *File, unsigned Line, Metadata *Type,
- unsigned Arg, unsigned Flags,
- Metadata *InlinedAt, StorageType Storage,
+ MDScope *Scope, StringRef Name, MDFile *File,
+ unsigned Line, MDTypeRef Type, unsigned Arg,
+ unsigned Flags, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Tag, Scope, getCanonicalMDString(Context, Name),
- File, Line, Type, Arg, Flags, InlinedAt, Storage,
- ShouldCreate);
+ File, Line, Type, Arg, Flags, Storage, ShouldCreate);
}
- static MDLocalVariable *getImpl(LLVMContext &Context, unsigned Tag,
- Metadata *Scope, MDString *Name,
- Metadata *File, unsigned Line, Metadata *Type,
- unsigned Arg, unsigned Flags,
- Metadata *InlinedAt, StorageType Storage,
- bool ShouldCreate = true);
+ static MDLocalVariable *
+ getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, MDString *Name,
+ Metadata *File, unsigned Line, Metadata *Type, unsigned Arg,
+ unsigned Flags, StorageType Storage, bool ShouldCreate = true);
TempMDLocalVariable cloneImpl() const {
return getTemporary(getContext(), getTag(), getScope(), getName(),
- getFile(), getLine(), getType(), getArg(), getFlags(),
- getInlinedAt());
+ getFile(), getLine(), getType(), getArg(), getFlags());
}
public:
DEFINE_MDNODE_GET(MDLocalVariable,
- (unsigned Tag, Metadata *Scope, StringRef Name,
- Metadata *File, unsigned Line, Metadata *Type,
- unsigned Arg, unsigned Flags,
- Metadata *InlinedAt = nullptr),
- (Tag, Scope, Name, File, Line, Type, Arg, Flags, InlinedAt))
+ (unsigned Tag, MDLocalScope *Scope, StringRef Name,
+ MDFile *File, unsigned Line, MDTypeRef Type, unsigned Arg,
+ unsigned Flags),
+ (Tag, Scope, Name, File, Line, Type, Arg, Flags))
DEFINE_MDNODE_GET(MDLocalVariable,
(unsigned Tag, Metadata *Scope, MDString *Name,
Metadata *File, unsigned Line, Metadata *Type,
- unsigned Arg, unsigned Flags,
- Metadata *InlinedAt = nullptr),
- (Tag, Scope, Name, File, Line, Type, Arg, Flags, InlinedAt))
+ unsigned Arg, unsigned Flags),
+ (Tag, Scope, Name, File, Line, Type, Arg, Flags))
TempMDLocalVariable clone() const { return cloneImpl(); }
+ /// \brief Get the local scope for this variable.
+ ///
+ /// Variables must be defined in a local scope.
+ MDLocalScope *getScope() const {
+ return cast<MDLocalScope>(MDVariable::getScope());
+ }
+
unsigned getArg() const { return Arg; }
unsigned getFlags() const { return Flags; }
- Metadata *getInlinedAt() const { return getOperand(4); }
- /// \brief Get an inlined version of this variable.
+ bool isArtificial() const { return getFlags() & FlagArtificial; }
+ bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
+
+ /// \brief Check that a location is valid for this variable.
///
- /// Returns a version of this with \a getAlinedAt() set to \c InlinedAt.
- MDLocalVariable *withInline(MDLocation *InlinedAt) const {
- if (InlinedAt == getInlinedAt())
- return const_cast<MDLocalVariable *>(this);
- auto Temp = clone();
- Temp->replaceOperandWith(4, InlinedAt);
- return replaceWithUniqued(std::move(Temp));
+ /// Check that \c DL exists, is in the same subprogram, and has the same
+ /// inlined-at location as \c this. (Otherwise, it's not a valid attachemnt
+ /// to a \a DbgInfoIntrinsic.)
+ bool isValidLocationForIntrinsic(const MDLocation *DL) const {
+ return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
}
- MDLocalVariable *withoutInline() const { return withInline(nullptr); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDLocalVariableKind;
@@ -1484,6 +1935,12 @@ public:
/// \brief DWARF expression.
///
+/// This is (almost) a DWARF expression that modifies the location of a
+/// variable or (or the location of a single piece of a variable).
+///
+/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
+/// and have DW_OP_plus consume the topmost elements on the stack.
+///
/// TODO: Co-allocate the expression elements.
/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
/// storage types.
@@ -1496,7 +1953,7 @@ class MDExpression : public MDNode {
MDExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
: MDNode(C, MDExpressionKind, Storage, None),
Elements(Elements.begin(), Elements.end()) {}
- ~MDExpression() {}
+ ~MDExpression() = default;
static MDExpression *getImpl(LLVMContext &Context,
ArrayRef<uint64_t> Elements, StorageType Storage,
@@ -1519,6 +1976,15 @@ public:
return Elements[I];
}
+ /// \brief Return whether this is a piece of an aggregate variable.
+ bool isBitPiece() const;
+
+ /// \brief Return the offset of this piece in bits.
+ uint64_t getBitPieceOffset() const;
+
+ /// \brief Return the size of this piece in bits.
+ uint64_t getBitPieceSize() const;
+
typedef ArrayRef<uint64_t>::iterator element_iterator;
element_iterator elements_begin() const { return getElements().begin(); }
element_iterator elements_end() const { return getElements().end(); }
@@ -1573,6 +2039,13 @@ public:
return T;
}
+ /// \brief Get the next iterator.
+ ///
+ /// \a std::next() doesn't work because this is technically an
+ /// input_iterator, but it's a perfectly valid operation. This is an
+ /// accessor to provide the same functionality.
+ expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
+
bool operator==(const expr_op_iterator &X) const {
return getBase() == X.getBase();
}
@@ -1619,12 +2092,12 @@ class MDObjCProperty : public DebugNode {
: DebugNode(C, MDObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
Ops),
Line(Line), Attributes(Attributes) {}
- ~MDObjCProperty() {}
+ ~MDObjCProperty() = default;
static MDObjCProperty *
- getImpl(LLVMContext &Context, StringRef Name, Metadata *File, unsigned Line,
+ getImpl(LLVMContext &Context, StringRef Name, MDFile *File, unsigned Line,
StringRef GetterName, StringRef SetterName, unsigned Attributes,
- Metadata *Type, StorageType Storage, bool ShouldCreate = true) {
+ MDType *Type, StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
getCanonicalMDString(Context, GetterName),
getCanonicalMDString(Context, SetterName), Attributes, Type,
@@ -1644,9 +2117,9 @@ class MDObjCProperty : public DebugNode {
public:
DEFINE_MDNODE_GET(MDObjCProperty,
- (StringRef Name, Metadata *File, unsigned Line,
+ (StringRef Name, MDFile *File, unsigned Line,
StringRef GetterName, StringRef SetterName,
- unsigned Attributes, Metadata *Type),
+ unsigned Attributes, MDType *Type),
(Name, File, Line, GetterName, SetterName, Attributes,
Type))
DEFINE_MDNODE_GET(MDObjCProperty,
@@ -1661,20 +2134,39 @@ public:
unsigned getLine() const { return Line; }
unsigned getAttributes() const { return Attributes; }
StringRef getName() const { return getStringOperand(0); }
- Metadata *getFile() const { return getOperand(1); }
+ MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
StringRef getGetterName() const { return getStringOperand(2); }
StringRef getSetterName() const { return getStringOperand(3); }
- Metadata *getType() const { return getOperand(4); }
+
+ /// \brief Get the type.
+ ///
+ /// \note Objective-C doesn't have an ODR, so there is no benefit in storing
+ /// the type as a DITypeRef here.
+ MDType *getType() const { return cast_or_null<MDType>(getRawType()); }
+
+ StringRef getFilename() const {
+ if (auto *F = getFile())
+ return F->getFilename();
+ return "";
+ }
+ StringRef getDirectory() const {
+ if (auto *F = getFile())
+ return F->getDirectory();
+ return "";
+ }
MDString *getRawName() const { return getOperandAs<MDString>(0); }
+ Metadata *getRawFile() const { return getOperand(1); }
MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
+ Metadata *getRawType() const { return getOperand(4); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDObjCPropertyKind;
}
};
+/// \brief An imported module (C++ using directive or similar).
class MDImportedEntity : public DebugNode {
friend class LLVMContextImpl;
friend class MDNode;
@@ -1684,10 +2176,10 @@ class MDImportedEntity : public DebugNode {
MDImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
unsigned Line, ArrayRef<Metadata *> Ops)
: DebugNode(C, MDImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
- ~MDImportedEntity() {}
+ ~MDImportedEntity() = default;
static MDImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
- Metadata *Scope, Metadata *Entity,
+ MDScope *Scope, DebugNodeRef Entity,
unsigned Line, StringRef Name,
StorageType Storage,
bool ShouldCreate = true) {
@@ -1707,7 +2199,7 @@ class MDImportedEntity : public DebugNode {
public:
DEFINE_MDNODE_GET(MDImportedEntity,
- (unsigned Tag, Metadata *Scope, Metadata *Entity,
+ (unsigned Tag, MDScope *Scope, DebugNodeRef Entity,
unsigned Line, StringRef Name = ""),
(Tag, Scope, Entity, Line, Name))
DEFINE_MDNODE_GET(MDImportedEntity,
@@ -1718,10 +2210,12 @@ public:
TempMDImportedEntity clone() const { return cloneImpl(); }
unsigned getLine() const { return Line; }
- Metadata *getScope() const { return getOperand(0); }
- Metadata *getEntity() const { return getOperand(1); }
+ MDScope *getScope() const { return cast_or_null<MDScope>(getRawScope()); }
+ DebugNodeRef getEntity() const { return DebugNodeRef(getRawEntity()); }
StringRef getName() const { return getStringOperand(2); }
+ Metadata *getRawScope() const { return getOperand(0); }
+ Metadata *getRawEntity() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
static bool classof(const Metadata *MD) {
diff --git a/include/llvm/IR/DebugLoc.h b/include/llvm/IR/DebugLoc.h
index c29d5bf..f88a7b1 100644
--- a/include/llvm/IR/DebugLoc.h
+++ b/include/llvm/IR/DebugLoc.h
@@ -22,11 +22,15 @@ namespace llvm {
class LLVMContext;
class raw_ostream;
- class MDNode;
-
- /// DebugLoc - Debug location id. This is carried by Instruction, SDNode,
- /// and MachineInstr to compactly encode file/line/scope information for an
- /// operation.
+ class MDLocation;
+
+ /// \brief A debug info location.
+ ///
+ /// This class is a wrapper around a tracking reference to an \a MDLocation
+ /// pointer.
+ ///
+ /// To avoid extra includes, \a DebugLoc doubles the \a MDLocation API with a
+ /// one based on relatively opaque \a MDNode pointers.
class DebugLoc {
TrackingMDNodeRef Loc;
@@ -43,64 +47,76 @@ namespace llvm {
return *this;
}
+ /// \brief Construct from an \a MDLocation.
+ DebugLoc(const MDLocation *L);
+
+ /// \brief Construct from an \a MDNode.
+ ///
+ /// Note: if \c N is not an \a MDLocation, a verifier check will fail, and
+ /// accessors will crash. However, construction from other nodes is
+ /// supported in order to handle forward references when reading textual
+ /// IR.
+ explicit DebugLoc(const MDNode *N);
+
+ /// \brief Get the underlying \a MDLocation.
+ ///
+ /// \pre !*this or \c isa<MDLocation>(getAsMDNode()).
+ /// @{
+ MDLocation *get() const;
+ operator MDLocation *() const { return get(); }
+ MDLocation *operator->() const { return get(); }
+ MDLocation &operator*() const { return *get(); }
+ /// @}
+
+ /// \brief Check for null.
+ ///
+ /// Check for null in a way that is safe with broken debug info. Unlike
+ /// the conversion to \c MDLocation, this doesn't require that \c Loc is of
+ /// the right type. Important for cases like \a llvm::StripDebugInfo() and
+ /// \a Instruction::hasMetadata().
+ explicit operator bool() const { return Loc; }
+
/// \brief Check whether this has a trivial destructor.
bool hasTrivialDestructor() const { return Loc.hasTrivialDestructor(); }
- /// get - Get a new DebugLoc that corresponds to the specified line/col
- /// scope/inline location.
- static DebugLoc get(unsigned Line, unsigned Col, MDNode *Scope,
- MDNode *InlinedAt = nullptr);
-
- /// getFromDILocation - Translate the DILocation quad into a DebugLoc.
- static DebugLoc getFromDILocation(MDNode *N);
-
- /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
- static DebugLoc getFromDILexicalBlock(MDNode *N);
-
- /// isUnknown - Return true if this is an unknown location.
- bool isUnknown() const { return !Loc; }
+ /// \brief Create a new DebugLoc.
+ ///
+ /// Create a new DebugLoc at the specified line/col and scope/inline. This
+ /// forwards to \a MDLocation::get().
+ ///
+ /// If \c !Scope, returns a default-constructed \a DebugLoc.
+ ///
+ /// FIXME: Remove this. Users should use MDLocation::get().
+ static DebugLoc get(unsigned Line, unsigned Col, const MDNode *Scope,
+ const MDNode *InlinedAt = nullptr);
unsigned getLine() const;
unsigned getCol() const;
-
- /// getScope - This returns the scope pointer for this DebugLoc, or null if
- /// invalid.
MDNode *getScope() const;
- MDNode *getScope(const LLVMContext &) const { return getScope(); }
-
- /// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or
- /// null if invalid or not present.
- MDNode *getInlinedAt() const;
- MDNode *getInlinedAt(const LLVMContext &) const { return getInlinedAt(); }
-
- /// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values.
- void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const;
- void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
- const LLVMContext &) const {
- return getScopeAndInlinedAt(Scope, IA);
- }
-
- /// getScopeNode - Get MDNode for DebugLoc's scope, or null if invalid.
- MDNode *getScopeNode() const;
- MDNode *getScopeNode(const LLVMContext &) const { return getScopeNode(); }
-
- // getFnDebugLoc - Walk up the scope chain of given debug loc and find line
- // number info for the function.
+ MDLocation *getInlinedAt() const;
+
+ /// \brief Get the fully inlined-at scope for a DebugLoc.
+ ///
+ /// Gets the inlined-at scope for a DebugLoc.
+ MDNode *getInlinedAtScope() const;
+
+ /// \brief Find the debug info location for the start of the function.
+ ///
+ /// Walk up the scope chain of given debug loc and find line number info
+ /// for the function.
+ ///
+ /// FIXME: Remove this. Users should use MDLocation/MDLocalScope API to
+ /// find the subprogram, and then MDLocation::get().
DebugLoc getFnDebugLoc() const;
- DebugLoc getFnDebugLoc(const LLVMContext &) const {
- return getFnDebugLoc();
- }
- /// getAsMDNode - This method converts the compressed DebugLoc node into a
- /// DILocation compatible MDNode.
- MDNode *getAsMDNode() const;
- MDNode *getAsMDNode(LLVMContext &) const { return getAsMDNode(); }
+ /// \brief Return \c this as a bar \a MDNode.
+ MDNode *getAsMDNode() const { return Loc; }
bool operator==(const DebugLoc &DL) const { return Loc == DL.Loc; }
- bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
+ bool operator!=(const DebugLoc &DL) const { return Loc != DL.Loc; }
void dump() const;
- void dump(const LLVMContext &) const { dump(); }
+
/// \brief prints source location /path/to/file.exe:line:col @[inlined at]
void print(raw_ostream &OS) const;
};
diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h
index 0cd5afb..a5eed9b 100644
--- a/include/llvm/IR/Function.h
+++ b/include/llvm/IR/Function.h
@@ -31,26 +31,6 @@ namespace llvm {
class FunctionType;
class LLVMContext;
-// Traits for intrusive list of basic blocks...
-template<> struct ilist_traits<BasicBlock>
- : public SymbolTableListTraits<BasicBlock, Function> {
-
- // createSentinel is used to get hold of the node that marks the end of the
- // list... (same trick used here as in ilist_traits<Instruction>)
- BasicBlock *createSentinel() const {
- return static_cast<BasicBlock*>(&Sentinel);
- }
- static void destroySentinel(BasicBlock*) {}
-
- BasicBlock *provideInitialHead() const { return createSentinel(); }
- BasicBlock *ensureHead(BasicBlock*) const { return createSentinel(); }
- static void noteHead(BasicBlock*, BasicBlock*) {}
-
- static ValueSymbolTable *getSymTab(Function *ItemParent);
-private:
- mutable ilist_half_node<BasicBlock> Sentinel;
-};
-
template<> struct ilist_traits<Argument>
: public SymbolTableListTraits<Argument, Function> {
@@ -86,6 +66,7 @@ private:
mutable ArgumentListType ArgumentList; ///< The formal arguments
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
AttributeSet AttributeSets; ///< Parameter attributes
+ FunctionType *Ty;
/*
* Value::SubclassData
@@ -133,7 +114,7 @@ public:
return new(0) Function(Ty, Linkage, N, M);
}
- ~Function();
+ ~Function() override;
Type *getReturnType() const; // Return the type of the ret val
FunctionType *getFunctionType() const; // Return the FunctionType for me
@@ -242,6 +223,10 @@ public:
/// @brief adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);
+ /// @brief adds the dereferenceable_or_null attribute to the list of
+ /// attributes.
+ void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);
+
/// @brief Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned i) const {
return AttributeSets.getParamAlignment(i);
@@ -472,6 +457,10 @@ public:
Constant *getPrologueData() const;
void setPrologueData(Constant *PrologueData);
+ /// Print the function to an output stream with an optional
+ /// AssemblyAnnotationWriter.
+ void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW = nullptr) const;
+
/// viewCFG - This function is meant for use from the debugger. You can just
/// say 'call F->viewCFG()' and a ghostview window should pop up from the
/// program, displaying the CFG of the current function with the code for each
diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h
index ae2f2e1..779f2e0 100644
--- a/include/llvm/IR/GVMaterializer.h
+++ b/include/llvm/IR/GVMaterializer.h
@@ -54,6 +54,7 @@ public:
virtual std::error_code MaterializeModule(Module *M) = 0;
virtual std::error_code materializeMetadata() = 0;
+ virtual void setStripDebugInfo() = 0;
virtual std::vector<StructType *> getIdentifiedStructTypes() const = 0;
};
diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h
index 50deb08..f055241 100644
--- a/include/llvm/IR/GlobalObject.h
+++ b/include/llvm/IR/GlobalObject.h
@@ -27,7 +27,7 @@ class GlobalObject : public GlobalValue {
GlobalObject(const GlobalObject &) = delete;
protected:
- GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
+ GlobalObject(PointerType *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
LinkageTypes Linkage, const Twine &Name)
: GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name), ObjComdat(nullptr) {
setGlobalValueSubClassData(0);
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index 002e5e7..aeaaef4 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -61,7 +61,7 @@ public:
};
protected:
- GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
+ GlobalValue(PointerType *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
LinkageTypes Linkage, const Twine &Name)
: Constant(Ty, VTy, Ops, NumOps), Linkage(Linkage),
Visibility(DefaultVisibility), UnnamedAddr(0),
@@ -104,7 +104,7 @@ public:
LocalExecTLSModel
};
- ~GlobalValue() {
+ ~GlobalValue() override {
removeDeadConstantUsers(); // remove any dead constants using this.
}
@@ -165,9 +165,9 @@ public:
const char *getSection() const;
/// Global values are always pointers.
- inline PointerType *getType() const {
- return cast<PointerType>(User::getType());
- }
+ PointerType *getType() const { return cast<PointerType>(User::getType()); }
+
+ Type *getValueType() const { return getType()->getElementType(); }
static LinkageTypes getLinkOnceLinkage(bool ODR) {
return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage;
@@ -343,11 +343,11 @@ public:
virtual void eraseFromParent() = 0;
/// Get the module that this global value is contained inside of...
- inline Module *getParent() { return Parent; }
- inline const Module *getParent() const { return Parent; }
+ Module *getParent() { return Parent; }
+ const Module *getParent() const { return Parent; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal ||
V->getValueID() == Value::GlobalVariableVal ||
V->getValueID() == Value::GlobalAliasVal;
diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h
index d7b81a2..9f57705 100644
--- a/include/llvm/IR/GlobalVariable.h
+++ b/include/llvm/IR/GlobalVariable.h
@@ -66,7 +66,7 @@ public:
ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
bool isExternallyInitialized = false);
- ~GlobalVariable() {
+ ~GlobalVariable() override {
NumOperands = 1; // FIXME: needed by operator delete
}
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index 617e2bc..9c4ba07 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -21,6 +21,7 @@
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/ConstantFolder.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Operator.h"
@@ -123,7 +124,7 @@ public:
/// \brief If this builder has a current debug location, set it on the
/// specified instruction.
void SetInstDebugLocation(Instruction *I) const {
- if (!CurDbgLocation.isUnknown())
+ if (CurDbgLocation)
I->setDebugLoc(CurDbgLocation);
}
@@ -243,7 +244,7 @@ public:
/// filled in with the null terminated string value specified. The new global
/// variable will be marked mergable with any others of the same contents. If
/// Name is specified, it is the name of the global variable created.
- Value *CreateGlobalString(StringRef Str, const Twine &Name = "");
+ GlobalVariable *CreateGlobalString(StringRef Str, const Twine &Name = "");
/// \brief Get a constant value representing either true or false.
ConstantInt *getInt1(bool V) {
@@ -1028,12 +1029,16 @@ public:
if (!isa<Constant>(IdxList[i]))
break;
if (i == e)
- return Insert(Folder.CreateGetElementPtr(PC, IdxList), Name);
+ return Insert(Folder.CreateGetElementPtr(Ty, PC, IdxList), Name);
}
return Insert(GetElementPtrInst::Create(Ty, Ptr, IdxList), Name);
}
Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &Name = "") {
+ return CreateInBoundsGEP(nullptr, Ptr, IdxList, Name);
+ }
+ Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr)) {
// Every index must be constant.
size_t i, e;
@@ -1041,68 +1046,77 @@ public:
if (!isa<Constant>(IdxList[i]))
break;
if (i == e)
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IdxList),
+ Name);
}
- return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, IdxList), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, IdxList), Name);
}
Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
+ return CreateGEP(nullptr, Ptr, Idx, Name);
+ }
+ Value *CreateGEP(Type *Ty, Value *Ptr, Value *Idx, const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr))
if (Constant *IC = dyn_cast<Constant>(Idx))
- return Insert(Folder.CreateGetElementPtr(PC, IC), Name);
- return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name);
+ return Insert(Folder.CreateGetElementPtr(Ty, PC, IC), Name);
+ return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
}
- Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
+ Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, Value *Idx,
+ const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr))
if (Constant *IC = dyn_cast<Constant>(Idx))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, IC), Name);
- return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IC), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
}
Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") {
+ return CreateConstGEP1_32(nullptr, Ptr, Idx0, Name);
+ }
+ Value *CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0,
+ const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
+ return Insert(Folder.CreateGetElementPtr(Ty, PC, Idx), Name);
- return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
}
- Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
+ Value *CreateConstInBoundsGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0,
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idx), Name);
- return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
}
- Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
- const Twine &Name = "") {
+ Value *CreateConstGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0, unsigned Idx1,
+ const Twine &Name = "") {
Value *Idxs[] = {
ConstantInt::get(Type::getInt32Ty(Context), Idx0),
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
+ return Insert(Folder.CreateGetElementPtr(Ty, PC, Idxs), Name);
- return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name);
}
- Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
- const Twine &Name = "") {
+ Value *CreateConstInBoundsGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0,
+ unsigned Idx1, const Twine &Name = "") {
Value *Idxs[] = {
ConstantInt::get(Type::getInt32Ty(Context), Idx0),
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idxs), Name);
- return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name);
}
Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
+ return Insert(Folder.CreateGetElementPtr(nullptr, PC, Idx), Name);
return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name);
}
@@ -1111,7 +1125,7 @@ public:
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(nullptr, PC, Idx), Name);
return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name);
}
@@ -1123,7 +1137,7 @@ public:
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
+ return Insert(Folder.CreateGetElementPtr(nullptr, PC, Idxs), Name);
return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idxs), Name);
}
@@ -1135,21 +1149,23 @@ public:
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(nullptr, PC, Idxs),
+ Name);
return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idxs), Name);
}
- Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") {
- return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
+ Value *CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx,
+ const Twine &Name = "") {
+ return CreateConstInBoundsGEP2_32(Ty, Ptr, 0, Idx, Name);
}
/// \brief Same as CreateGlobalString, but return a pointer with "i8*" type
/// instead of a pointer to array of i8.
Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") {
- Value *gv = CreateGlobalString(Str, Name);
+ GlobalVariable *gv = CreateGlobalString(Str, Name);
Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
Value *Args[] = { zero, zero };
- return CreateInBoundsGEP(gv, Args, Name);
+ return CreateInBoundsGEP(gv->getValueType(), gv, Args, Name);
}
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/IR/IRPrintingPasses.h b/include/llvm/IR/IRPrintingPasses.h
index 7f2027b..5f1d56f 100644
--- a/include/llvm/IR/IRPrintingPasses.h
+++ b/include/llvm/IR/IRPrintingPasses.h
@@ -34,7 +34,8 @@ class raw_ostream;
/// \brief Create and return a pass that writes the module to the specified
/// \c raw_ostream.
ModulePass *createPrintModulePass(raw_ostream &OS,
- const std::string &Banner = "");
+ const std::string &Banner = "",
+ bool ShouldPreserveUseListOrder = false);
/// \brief Create and return a pass that prints functions to the specified
/// \c raw_ostream as they are processed.
@@ -53,10 +54,12 @@ BasicBlockPass *createPrintBasicBlockPass(raw_ostream &OS,
class PrintModulePass {
raw_ostream &OS;
std::string Banner;
+ bool ShouldPreserveUseListOrder;
public:
PrintModulePass();
- PrintModulePass(raw_ostream &OS, const std::string &Banner = "");
+ PrintModulePass(raw_ostream &OS, const std::string &Banner = "",
+ bool ShouldPreserveUseListOrder = false);
PreservedAnalyses run(Module &M);
diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h
index 6ae4122..c8f25e7 100644
--- a/include/llvm/IR/InlineAsm.h
+++ b/include/llvm/IR/InlineAsm.h
@@ -51,7 +51,7 @@ private:
InlineAsm(PointerType *Ty, const std::string &AsmString,
const std::string &Constraints, bool hasSideEffects,
bool isAlignStack, AsmDialect asmDialect);
- virtual ~InlineAsm();
+ ~InlineAsm() override;
/// When the ConstantUniqueMap merges two types and makes two InlineAsms
/// identical, it destroys one of them with this method.
diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h
index 3a33f43..108b9eb 100644
--- a/include/llvm/IR/InstrTypes.h
+++ b/include/llvm/IR/InstrTypes.h
@@ -44,7 +44,7 @@ protected:
: Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {}
// Out of line virtual method, so the vtable, etc has a home.
- ~TerminatorInst();
+ ~TerminatorInst() override;
/// Virtual methods - Terminators should overload these and provide inline
/// overrides of non-V methods.
@@ -102,7 +102,7 @@ public:
}
// Out of line virtual method, so the vtable, etc has a home.
- ~UnaryInstruction();
+ ~UnaryInstruction() override;
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h
index dc96b57..9dd16fd 100644
--- a/include/llvm/IR/Instruction.h
+++ b/include/llvm/IR/Instruction.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/User.h"
namespace llvm {
@@ -25,10 +26,27 @@ namespace llvm {
class FastMathFlags;
class LLVMContext;
class MDNode;
+class BasicBlock;
struct AAMDNodes;
-template<typename ValueSubClass, typename ItemParentClass>
- class SymbolTableListTraits;
+template <>
+struct ilist_traits<Instruction>
+ : public SymbolTableListTraits<Instruction, BasicBlock> {
+
+ /// \brief Return a node that marks the end of a list.
+ ///
+ /// The sentinel is relative to this instance, so we use a non-static
+ /// method.
+ Instruction *createSentinel() const;
+ static void destroySentinel(Instruction *) {}
+
+ Instruction *provideInitialHead() const { return createSentinel(); }
+ Instruction *ensureHead(Instruction *) const { return createSentinel(); }
+ static void noteHead(Instruction *, Instruction *) {}
+
+private:
+ mutable ilist_half_node<Instruction> Sentinel;
+};
class Instruction : public User, public ilist_node<Instruction> {
void operator=(const Instruction &) = delete;
@@ -44,7 +62,7 @@ class Instruction : public User, public ilist_node<Instruction> {
};
public:
// Out of line virtual method, so the vtable, etc has a home.
- ~Instruction();
+ ~Instruction() override;
/// user_back - Specialize the methods defined in Value, as we know that an
/// instruction can only be used by other instructions.
@@ -69,7 +87,8 @@ public:
/// eraseFromParent - This method unlinks 'this' from the containing basic
/// block and deletes it.
///
- void eraseFromParent();
+ /// \returns an iterator pointing to the element after the erased one
+ iplist<Instruction>::iterator eraseFromParent();
/// insertBefore - Insert an unlinked instructions into a basic block
/// immediately before the specified instruction.
@@ -134,9 +153,7 @@ public:
/// hasMetadata() - Return true if this instruction has any metadata attached
/// to it.
- bool hasMetadata() const {
- return !DbgLoc.isUnknown() || hasMetadataHashEntry();
- }
+ bool hasMetadata() const { return DbgLoc || hasMetadataHashEntry(); }
/// hasMetadataOtherThanDebugLoc - Return true if this instruction has
/// metadata attached to it other than a debug location.
@@ -495,6 +512,17 @@ protected:
};
+inline Instruction *ilist_traits<Instruction>::createSentinel() const {
+ // Since i(p)lists always publicly derive from their corresponding traits,
+ // placing a data member in this class will augment the i(p)list. But since
+ // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
+ // there is a legal viable downcast from it to NodeTy. We use this trick to
+ // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
+ // sentinel. Dereferencing the sentinel is forbidden (save the
+ // ilist_node<NodeTy>), so no one will ever notice the superposition.
+ return static_cast<Instruction *>(&Sentinel);
+}
+
// Instruction* is only 4-byte aligned.
template<>
class PointerLikeTypeTraits<Instruction*> {
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index 52fa360..1f2ca30 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -91,7 +91,7 @@ public:
const Twine &Name, BasicBlock *InsertAtEnd);
// Out of line virtual method, so the vtable, etc. has a home.
- virtual ~AllocaInst();
+ ~AllocaInst() override;
/// isArrayAllocation - Return true if there is an allocation size parameter
/// to the allocation instruction that is not 1.
@@ -180,7 +180,12 @@ public:
unsigned Align, Instruction *InsertBefore = nullptr);
LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
unsigned Align, BasicBlock *InsertAtEnd);
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align,
+ AtomicOrdering Order, SynchronizationScope SynchScope = CrossThread,
+ Instruction *InsertBefore = nullptr)
+ : LoadInst(cast<PointerType>(Ptr->getType())->getElementType(), Ptr,
+ NameStr, isVolatile, Align, Order, SynchScope, InsertBefore) {}
+ LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
unsigned Align, AtomicOrdering Order,
SynchronizationScope SynchScope = CrossThread,
Instruction *InsertBefore = nullptr);
@@ -882,9 +887,9 @@ public:
/// Null is returned if the indices are invalid for the specified
/// pointer type.
///
- static Type *getIndexedType(Type *Ptr, ArrayRef<Value *> IdxList);
- static Type *getIndexedType(Type *Ptr, ArrayRef<Constant *> IdxList);
- static Type *getIndexedType(Type *Ptr, ArrayRef<uint64_t> IdxList);
+ static Type *getIndexedType(Type *Ty, ArrayRef<Value *> IdxList);
+ static Type *getIndexedType(Type *Ty, ArrayRef<Constant *> IdxList);
+ static Type *getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList);
inline op_iterator idx_begin() { return op_begin()+1; }
inline const_op_iterator idx_begin() const { return op_begin()+1; }
@@ -915,9 +920,12 @@ public:
/// GetGEPReturnType - Returns the pointer type returned by the GEP
/// instruction, which may be a vector of pointers.
static Type *getGEPReturnType(Value *Ptr, ArrayRef<Value *> IdxList) {
- Type *PtrTy = PointerType::get(checkGEPType(
- getIndexedType(Ptr->getType(), IdxList)),
- Ptr->getType()->getPointerAddressSpace());
+ Type *PtrTy =
+ PointerType::get(checkGEPType(getIndexedType(
+ cast<PointerType>(Ptr->getType()->getScalarType())
+ ->getElementType(),
+ IdxList)),
+ Ptr->getType()->getPointerAddressSpace());
// Vector GEP
if (Ptr->getType()->isVectorTy()) {
unsigned NumElem = cast<VectorType>(Ptr->getType())->getNumElements();
@@ -1327,7 +1335,11 @@ public:
static Instruction* CreateFree(Value* Source, Instruction *InsertBefore);
static Instruction* CreateFree(Value* Source, BasicBlock *InsertAtEnd);
- ~CallInst();
+ ~CallInst() override;
+
+ Type *getFunctionType() const {
+ return cast<PointerType>(getCalledValue()->getType())->getElementType();
+ }
// Note that 'musttail' implies 'tail'.
enum TailCallKind { TCK_None = 0, TCK_Tail = 1, TCK_MustTail = 2 };
@@ -1404,6 +1416,10 @@ public:
/// \brief adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);
+ /// \brief adds the dereferenceable_or_null attribute to the list of
+ /// attributes.
+ void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);
+
/// \brief Determine whether this call has the given attribute.
bool hasFnAttr(Attribute::AttrKind A) const {
assert(A != Attribute::NoBuiltin &&
@@ -2167,7 +2183,7 @@ public:
const Twine &NameStr, BasicBlock *InsertAtEnd) {
return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd);
}
- ~PHINode();
+ ~PHINode() override;
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2358,7 +2374,7 @@ public:
static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn,
unsigned NumReservedClauses,
const Twine &NameStr, BasicBlock *InsertAtEnd);
- ~LandingPadInst();
+ ~LandingPadInst() override;
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2460,7 +2476,7 @@ public:
static ReturnInst* Create(LLVMContext &C, BasicBlock *InsertAtEnd) {
return new(0) ReturnInst(C, InsertAtEnd);
}
- virtual ~ReturnInst();
+ ~ReturnInst() override;
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2757,7 +2773,7 @@ public:
return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
}
- ~SwitchInst();
+ ~SwitchInst() override;
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2943,7 +2959,7 @@ public:
BasicBlock *InsertAtEnd) {
return new IndirectBrInst(Address, NumDests, InsertAtEnd);
}
- ~IndirectBrInst();
+ ~IndirectBrInst() override;
/// Provide fast operand accessors.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -3093,9 +3109,13 @@ public:
/// removeAttribute - removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute attr);
- /// \brief removes the dereferenceable attribute to the list of attributes.
+ /// \brief adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);
+ /// \brief adds the dereferenceable_or_null attribute to the list of
+ /// attributes.
+ void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);
+
/// \brief Determine whether this call has the given attribute.
bool hasFnAttr(Attribute::AttrKind A) const {
assert(A != Attribute::NoBuiltin &&
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index da9d8cb..4052a31 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -421,10 +421,6 @@ def int_eh_endcatch : Intrinsic<[], []>;
// Represents the list of actions to take when an exception is thrown.
def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>;
-// Designates the provided static alloca as the unwind help object. Required
-// for WinEH.
-def int_eh_unwindhelp : Intrinsic<[], [llvm_ptr_ty], []>;
-
// __builtin_unwind_init is an undocumented GCC intrinsic that causes all
// callee-saved registers to be saved and restored (regardless of whether they
// are used) in the calling function. It is used by libgcc_eh.
@@ -630,3 +626,4 @@ include "llvm/IR/IntrinsicsNVVM.td"
include "llvm/IR/IntrinsicsMips.td"
include "llvm/IR/IntrinsicsR600.td"
include "llvm/IR/IntrinsicsBPF.td"
+include "llvm/IR/IntrinsicsSystemZ.td"
diff --git a/include/llvm/IR/IntrinsicsBPF.td b/include/llvm/IR/IntrinsicsBPF.td
index 6b5110b..94eca8e 100644
--- a/include/llvm/IR/IntrinsicsBPF.td
+++ b/include/llvm/IR/IntrinsicsBPF.td
@@ -19,4 +19,6 @@ let TargetPrefix = "bpf" in { // All intrinsics start with "llvm.bpf."
Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_i64_ty], [IntrReadMem]>;
def int_bpf_load_word : GCCBuiltin<"__builtin_bpf_load_word">,
Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_i64_ty], [IntrReadMem]>;
+ def int_bpf_pseudo : GCCBuiltin<"__builtin_bpf_pseudo">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty]>;
}
diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td
index 95fc3e5..74c0172 100644
--- a/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/include/llvm/IR/IntrinsicsPowerPC.td
@@ -37,6 +37,25 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
// generated by the PowerPC backend!
def int_ppc_mtctr : Intrinsic<[], [llvm_anyint_ty], []>;
def int_ppc_is_decremented_ctr_nonzero : Intrinsic<[llvm_i1_ty], [], []>;
+
+ // Intrinsics for [double]word extended forms of divide instructions
+ def int_ppc_divwe : GCCBuiltin<"__builtin_divwe">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_divweu : GCCBuiltin<"__builtin_divweu">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_divde : GCCBuiltin<"__builtin_divde">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_divdeu : GCCBuiltin<"__builtin_divdeu">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+
+ // Bit permute doubleword
+ def int_ppc_bpermd : GCCBuiltin<"__builtin_bpermd">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
}
@@ -563,11 +582,12 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
-// These need diagnostics for invalid arguments so don't inherit from GCCBuiltin
def int_ppc_altivec_crypto_vshasigmad :
+ GCCBuiltin<"__builtin_altivec_crypto_vshasigmad">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_ppc_altivec_crypto_vshasigmaw :
+ GCCBuiltin<"__builtin_altivec_crypto_vshasigmaw">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
}
@@ -801,20 +821,20 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
-def int_ppc_tbegin :
+def int_ppc_tbegin : GCCBuiltin<"__builtin_tbegin">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
-def int_ppc_tend :
+def int_ppc_tend : GCCBuiltin<"__builtin_tend">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
def int_ppc_tabort : GCCBuiltin<"__builtin_tabort">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
-def int_ppc_tabortwc :
+def int_ppc_tabortwc : GCCBuiltin<"__builtin_tabortwc">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
-def int_ppc_tabortwci :
+def int_ppc_tabortwci : GCCBuiltin<"__builtin_tabortwci">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
-def int_ppc_tabortdc :
+def int_ppc_tabortdc : GCCBuiltin<"__builtin_tabortdc">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
-def int_ppc_tabortdci :
+def int_ppc_tabortdci : GCCBuiltin<"__builtin_tabortdci">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
def int_ppc_tcheck : GCCBuiltin<"__builtin_tcheck">,
@@ -823,7 +843,7 @@ def int_ppc_treclaim : GCCBuiltin<"__builtin_treclaim">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
def int_ppc_trechkpt : GCCBuiltin<"__builtin_trechkpt">,
Intrinsic<[llvm_i32_ty], [], []>;
-def int_ppc_tsr :
+def int_ppc_tsr : GCCBuiltin<"__builtin_tsr">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
def int_ppc_get_texasr : GCCBuiltin<"__builtin_get_texasr">,
diff --git a/include/llvm/IR/IntrinsicsSystemZ.td b/include/llvm/IR/IntrinsicsSystemZ.td
new file mode 100644
index 0000000..6883db3
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsSystemZ.td
@@ -0,0 +1,46 @@
+//===- IntrinsicsSystemZ.td - Defines SystemZ intrinsics ---*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the SystemZ-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//
+// Transactional-execution intrinsics
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "s390" in {
+ def int_s390_tbegin : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoDuplicate]>;
+
+ def int_s390_tbegin_nofloat : Intrinsic<[llvm_i32_ty],
+ [llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoDuplicate]>;
+
+ def int_s390_tbeginc : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoDuplicate]>;
+
+ def int_s390_tabort : Intrinsic<[], [llvm_i64_ty],
+ [IntrNoReturn, Throws]>;
+
+ def int_s390_tend : GCCBuiltin<"__builtin_tend">,
+ Intrinsic<[llvm_i32_ty], []>;
+
+ def int_s390_etnd : GCCBuiltin<"__builtin_tx_nesting_depth">,
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+
+ def int_s390_ntstg : Intrinsic<[], [llvm_i64_ty, llvm_ptr64_ty],
+ [IntrReadWriteArgMem]>;
+
+ def int_s390_ppa_txassist : GCCBuiltin<"__builtin_tx_assist">,
+ Intrinsic<[], [llvm_i32_ty]>;
+}
+
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 39b8e3b..49231d8 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -1408,12 +1408,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw256">,
Intrinsic<[llvm_v4i64_ty], [llvm_v32i8_ty,
llvm_v32i8_ty], [IntrNoMem, Commutative]>;
- def int_x86_avx512_mask_pmulu_dq_512 : GCCBuiltin<"__builtin_ia32_pmuludq512_mask">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
- llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_pmul_dq_512 : GCCBuiltin<"__builtin_ia32_pmuldq512_mask">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
- llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
}
// Vector min, max
@@ -3093,7 +3087,27 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v8i64_ty], [llvm_v8i32_ty],
[IntrNoMem]>;
}
-
+//Bitwise Ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx512_mask_pand_d_512 : GCCBuiltin<"__builtin_ia32_pandd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pand_q_512 : GCCBuiltin<"__builtin_ia32_pandq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_por_d_512 : GCCBuiltin<"__builtin_ia32_pord512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_por_q_512 : GCCBuiltin<"__builtin_ia32_porq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pxor_d_512 : GCCBuiltin<"__builtin_ia32_pxord512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pxor_q_512 : GCCBuiltin<"__builtin_ia32_pxorq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+}
// Arithmetic ops
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
@@ -3222,6 +3236,27 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
[IntrNoMem]>;
}
+// Integer arithmetic ops
+let TargetPrefix = "x86" in {
+ def int_x86_avx512_mask_padd_d_512 : GCCBuiltin<"__builtin_ia32_paddd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_q_512 : GCCBuiltin<"__builtin_ia32_paddq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_d_512 : GCCBuiltin<"__builtin_ia32_psubd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_q_512 : GCCBuiltin<"__builtin_ia32_psubq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmulu_dq_512 : GCCBuiltin<"__builtin_ia32_pmuludq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmul_dq_512 : GCCBuiltin<"__builtin_ia32_pmuldq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+}
// Gather and Scatter ops
let TargetPrefix = "x86" in {
def int_x86_avx512_gather_dpd_512 : GCCBuiltin<"__builtin_ia32_gathersiv8df">,
@@ -3813,14 +3848,6 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_mask_cmp_pd_512 : GCCBuiltin<"__builtin_ia32_cmppd512_mask">,
Intrinsic<[llvm_i8_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty,
llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_pand_d_512 : GCCBuiltin<"__builtin_ia32_pandd512_mask">,
- Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
- llvm_v16i32_ty, llvm_i16_ty],
- [IntrNoMem]>;
- def int_x86_avx512_mask_pand_q_512 : GCCBuiltin<"__builtin_ia32_pandq512_mask">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
- llvm_v8i64_ty, llvm_i8_ty],
- [IntrNoMem]>;
def int_x86_avx512_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa512">,
Intrinsic<[llvm_v8i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
}
diff --git a/include/llvm/IR/LegacyPassManager.h b/include/llvm/IR/LegacyPassManager.h
index 6c04e9d..5257a0e 100644
--- a/include/llvm/IR/LegacyPassManager.h
+++ b/include/llvm/IR/LegacyPassManager.h
@@ -50,7 +50,7 @@ class PassManager : public PassManagerBase {
public:
PassManager();
- ~PassManager();
+ ~PassManager() override;
void add(Pass *P) override;
@@ -70,7 +70,7 @@ public:
/// FunctionPassManager ctor - This initializes the pass manager. It needs,
/// but does not take ownership of, the specified Module.
explicit FunctionPassManager(Module *M);
- ~FunctionPassManager();
+ ~FunctionPassManager() override;
void add(Pass *P) override;
diff --git a/include/llvm/IR/LegacyPassNameParser.h b/include/llvm/IR/LegacyPassNameParser.h
index 52db1c3..39ae80d 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*> {
public:
PassNameParser(cl::Option &O);
- virtual ~PassNameParser();
+ ~PassNameParser() override;
void initialize() {
cl::parser<const PassInfo*>::initialize();
diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h
index a31bdbf..03e70fe 100644
--- a/include/llvm/IR/Metadata.h
+++ b/include/llvm/IR/Metadata.h
@@ -89,7 +89,7 @@ protected:
Metadata(unsigned ID, StorageType Storage)
: SubclassID(ID), Storage(Storage), SubclassData16(0), SubclassData32(0) {
}
- ~Metadata() {}
+ ~Metadata() = default;
/// \brief Default handling of a changed operand, which asserts.
///
@@ -164,7 +164,7 @@ class MetadataAsValue : public Value {
Metadata *MD;
MetadataAsValue(Type *Ty, Metadata *MD);
- ~MetadataAsValue();
+ ~MetadataAsValue() override;
/// \brief Drop use of metadata (during teardown).
void dropUse() { MD = nullptr; }
@@ -253,7 +253,7 @@ protected:
: Metadata(ID, Uniqued), ReplaceableMetadataImpl(V->getContext()), V(V) {
assert(V && "Expected valid value");
}
- ~ValueAsMetadata() {}
+ ~ValueAsMetadata() = default;
public:
static ValueAsMetadata *get(Value *V);
@@ -754,13 +754,18 @@ protected:
MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None);
- ~MDNode() {}
+ ~MDNode() = default;
void dropAllReferences();
MDOperand *mutable_begin() { return mutable_end() - NumOperands; }
MDOperand *mutable_end() { return reinterpret_cast<MDOperand *>(this); }
+ typedef iterator_range<MDOperand *> mutable_op_range;
+ mutable_op_range mutable_operands() {
+ return mutable_op_range(mutable_begin(), mutable_end());
+ }
+
public:
static inline MDTuple *get(LLVMContext &Context, ArrayRef<Metadata *> MDs);
static inline MDTuple *getIfExists(LLVMContext &Context,
@@ -1028,6 +1033,78 @@ void TempMDNodeDeleter::operator()(MDNode *Node) const {
MDNode::deleteTemporary(Node);
}
+/// \brief Typed iterator through MDNode operands.
+///
+/// An iterator that transforms an \a MDNode::iterator into an iterator over a
+/// particular Metadata subclass.
+template <class T>
+class TypedMDOperandIterator
+ : std::iterator<std::input_iterator_tag, T *, std::ptrdiff_t, void, T *> {
+ MDNode::op_iterator I = nullptr;
+
+public:
+ TypedMDOperandIterator() = default;
+ explicit TypedMDOperandIterator(MDNode::op_iterator I) : I(I) {}
+ T *operator*() const { return cast_or_null<T>(*I); }
+ TypedMDOperandIterator &operator++() {
+ ++I;
+ return *this;
+ }
+ TypedMDOperandIterator operator++(int) {
+ TypedMDOperandIterator Temp(*this);
+ ++I;
+ return Temp;
+ }
+ bool operator==(const TypedMDOperandIterator &X) const { return I == X.I; }
+ bool operator!=(const TypedMDOperandIterator &X) const { return I != X.I; }
+};
+
+/// \brief Typed, array-like tuple of metadata.
+///
+/// This is a wrapper for \a MDTuple that makes it act like an array holding a
+/// particular type of metadata.
+template <class T> class MDTupleTypedArrayWrapper {
+ const MDTuple *N = nullptr;
+
+public:
+ MDTupleTypedArrayWrapper() = default;
+ MDTupleTypedArrayWrapper(const MDTuple *N) : N(N) {}
+
+ template <class U>
+ MDTupleTypedArrayWrapper(
+ const MDTupleTypedArrayWrapper<U> &Other,
+ typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
+ nullptr)
+ : N(Other.get()) {}
+
+ template <class U>
+ explicit MDTupleTypedArrayWrapper(
+ const MDTupleTypedArrayWrapper<U> &Other,
+ typename std::enable_if<!std::is_convertible<U *, T *>::value>::type * =
+ nullptr)
+ : N(Other.get()) {}
+
+ explicit operator bool() const { return get(); }
+ explicit operator MDTuple *() const { return get(); }
+
+ MDTuple *get() const { return const_cast<MDTuple *>(N); }
+ MDTuple *operator->() const { return get(); }
+ MDTuple &operator*() const { return *get(); }
+
+ // FIXME: Fix callers and remove condition on N.
+ unsigned size() const { return N ? N->getNumOperands() : 0u; }
+ T *operator[](unsigned I) const { return cast_or_null<T>(N->getOperand(I)); }
+
+ // FIXME: Fix callers and remove condition on N.
+ typedef TypedMDOperandIterator<T> iterator;
+ iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
+ iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
+};
+
+#define HANDLE_METADATA(CLASS) \
+ typedef MDTupleTypedArrayWrapper<CLASS> CLASS##Array;
+#include "llvm/IR/Metadata.def"
+
//===----------------------------------------------------------------------===//
/// \brief A tuple of MDNodes.
///
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index ac60c8e..dbaf322 100644
--- a/include/llvm/IR/Module.h
+++ b/include/llvm/IR/Module.h
@@ -642,8 +642,11 @@ public:
/// @{
/// Print the module to an output stream with an optional
- /// AssemblyAnnotationWriter.
- void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const;
+ /// AssemblyAnnotationWriter. If \c ShouldPreserveUseListOrder, then include
+ /// uselistorder directives so that use-lists can be recreated when reading
+ /// the assembly.
+ void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder = false) const;
/// Dump the module to stderr (for debugging).
void dump() const;
diff --git a/include/llvm/IR/NoFolder.h b/include/llvm/IR/NoFolder.h
index ab7bed6..61f4817 100644
--- a/include/llvm/IR/NoFolder.h
+++ b/include/llvm/IR/NoFolder.h
@@ -177,34 +177,35 @@ public:
// Memory Instructions
//===--------------------------------------------------------------------===//
- Constant *CreateGetElementPtr(Constant *C,
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getGetElementPtr(C, IdxList);
+ return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return ConstantExpr::getGetElementPtr(C, Idx);
+ return ConstantExpr::getGetElementPtr(Ty, C, Idx);
}
- Instruction *CreateGetElementPtr(Constant *C,
+ Instruction *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
- return GetElementPtrInst::Create(nullptr, C, IdxList);
+ return GetElementPtrInst::Create(Ty, C, IdxList);
}
- Constant *CreateInBoundsGetElementPtr(Constant *C,
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
+ Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
}
- Instruction *CreateInBoundsGetElementPtr(Constant *C,
+ Instruction *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
- return GetElementPtrInst::CreateInBounds(nullptr, C, IdxList);
+ return GetElementPtrInst::CreateInBounds(Ty, C, IdxList);
}
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h
index c87f89c..8c3afdd 100644
--- a/include/llvm/IR/Operator.h
+++ b/include/llvm/IR/Operator.h
@@ -42,7 +42,7 @@ protected:
// NOTE: Cannot use = delete because it's not legal to delete
// an overridden method that's not deleted in the base class. Cannot leave
// this unimplemented because that leads to an ODR-violation.
- ~Operator();
+ ~Operator() override;
public:
/// Return the opcode for this Instruction or ConstantExpr.
@@ -181,17 +181,17 @@ public:
{ }
/// Whether any flag is set
- bool any() { return Flags != 0; }
+ bool any() const { return Flags != 0; }
/// Set all the flags to false
void clear() { Flags = 0; }
/// Flag queries
- bool noNaNs() { return 0 != (Flags & NoNaNs); }
- bool noInfs() { return 0 != (Flags & NoInfs); }
- bool noSignedZeros() { return 0 != (Flags & NoSignedZeros); }
- bool allowReciprocal() { return 0 != (Flags & AllowReciprocal); }
- bool unsafeAlgebra() { return 0 != (Flags & UnsafeAlgebra); }
+ bool noNaNs() const { return 0 != (Flags & NoNaNs); }
+ bool noInfs() const { return 0 != (Flags & NoInfs); }
+ bool noSignedZeros() const { return 0 != (Flags & NoSignedZeros); }
+ bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
+ bool unsafeAlgebra() const { return 0 != (Flags & UnsafeAlgebra); }
/// Flag setters
void setNoNaNs() { Flags |= NoNaNs; }
diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h
index f94e105..41154e6 100644
--- a/include/llvm/IR/PatternMatch.h
+++ b/include/llvm/IR/PatternMatch.h
@@ -295,6 +295,9 @@ template <typename Class> struct bind_ty {
/// \brief Match a value, capturing it if we match.
inline bind_ty<Value> m_Value(Value *&V) { return V; }
+/// \brief Match an instruction, capturing it if we match.
+inline bind_ty<Instruction> m_Instruction(Instruction *&I) { return I; }
+
/// \brief Match a binary operator, capturing it if we match.
inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; }
@@ -1103,6 +1106,52 @@ m_UnordFMax(const LHS &L, const RHS &R) {
return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R);
}
+//===----------------------------------------------------------------------===//
+// Matchers for overflow check patterns: e.g. (a + b) u< a
+//
+
+template <typename LHS_t, typename RHS_t, typename Sum_t>
+struct UAddWithOverflow_match {
+ LHS_t L;
+ RHS_t R;
+ Sum_t S;
+
+ UAddWithOverflow_match(const LHS_t &L, const RHS_t &R, const Sum_t &S)
+ : L(L), R(R), S(S) {}
+
+ template <typename OpTy> bool match(OpTy *V) {
+ Value *ICmpLHS, *ICmpRHS;
+ ICmpInst::Predicate Pred;
+ if (!m_ICmp(Pred, m_Value(ICmpLHS), m_Value(ICmpRHS)).match(V))
+ return false;
+
+ Value *AddLHS, *AddRHS;
+ auto AddExpr = m_Add(m_Value(AddLHS), m_Value(AddRHS));
+
+ // (a + b) u< a, (a + b) u< b
+ if (Pred == ICmpInst::ICMP_ULT)
+ if (AddExpr.match(ICmpLHS) && (ICmpRHS == AddLHS || ICmpRHS == AddRHS))
+ return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS);
+
+ // a >u (a + b), b >u (a + b)
+ if (Pred == ICmpInst::ICMP_UGT)
+ if (AddExpr.match(ICmpRHS) && (ICmpLHS == AddLHS || ICmpLHS == AddRHS))
+ return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS);
+
+ return false;
+ }
+};
+
+/// \brief Match an icmp instruction checking for unsigned overflow on addition.
+///
+/// S is matched to the addition whose result is being checked for overflow, and
+/// L and R are matched to the LHS and RHS of S.
+template <typename LHS_t, typename RHS_t, typename Sum_t>
+UAddWithOverflow_match<LHS_t, RHS_t, Sum_t>
+m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S) {
+ return UAddWithOverflow_match<LHS_t, RHS_t, Sum_t>(L, R, S);
+}
+
/// \brief Match an 'unordered' floating point minimum function.
/// Floating point has one special value 'NaN'. Therefore, there is no total
/// order. However, if we can ignore the 'NaN' value (for example, because of a
diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h
index c2073c7..09b6388 100644
--- a/include/llvm/IR/Type.h
+++ b/include/llvm/IR/Type.h
@@ -91,8 +91,8 @@ protected:
NumContainedTys(0), ContainedTys(nullptr) {
setTypeID(tid);
}
- ~Type() {}
-
+ ~Type() = default;
+
void setTypeID(TypeID ID) {
IDAndSubclassData = (ID & 0xFF) | (IDAndSubclassData & 0xFFFFFF00);
assert(getTypeID() == ID && "TypeID data too large for field");
diff --git a/include/llvm/IR/UseListOrder.h b/include/llvm/IR/UseListOrder.h
index 7d8205d..b7c2418 100644
--- a/include/llvm/IR/UseListOrder.h
+++ b/include/llvm/IR/UseListOrder.h
@@ -51,12 +51,6 @@ private:
typedef std::vector<UseListOrder> UseListOrderStack;
-/// \brief Whether to preserve use-list ordering.
-bool shouldPreserveBitcodeUseListOrder();
-bool shouldPreserveAssemblyUseListOrder();
-void setPreserveBitcodeUseListOrder(bool ShouldPreserve);
-void setPreserveAssemblyUseListOrder(bool ShouldPreserve);
-
} // end namespace llvm
#endif
diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h
index d39378d..4559005 100644
--- a/include/llvm/IR/User.h
+++ b/include/llvm/IR/User.h
@@ -60,9 +60,7 @@ protected:
NumOperands = 0;
}
public:
- ~User() {
- Use::zap(OperandList, OperandList + NumOperands);
- }
+ ~User() override { Use::zap(OperandList, OperandList + NumOperands); }
/// \brief Free memory allocated for User and Use objects.
void operator delete(void *Usr);
/// \brief Placement delete - required by std, but never called.
diff --git a/include/llvm/IR/ValueMap.h b/include/llvm/IR/ValueMap.h
index 08d6d17..4d00b63 100644
--- a/include/llvm/IR/ValueMap.h
+++ b/include/llvm/IR/ValueMap.h
@@ -99,8 +99,6 @@ public:
explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64)
: Map(NumInitBuckets), Data(Data) {}
- ~ValueMap() {}
-
bool hasMD() const { return MDMap; }
MDMapT &MD() {
if (!MDMap)
@@ -149,9 +147,14 @@ public:
// If the key is already in the map, it returns false and doesn't update the
// value.
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
- std::pair<typename MapT::iterator, bool> map_result=
- Map.insert(std::make_pair(Wrap(KV.first), KV.second));
- return std::make_pair(iterator(map_result.first), map_result.second);
+ auto MapResult = Map.insert(std::make_pair(Wrap(KV.first), KV.second));
+ return std::make_pair(iterator(MapResult.first), MapResult.second);
+ }
+
+ std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
+ auto MapResult =
+ Map.insert(std::make_pair(Wrap(KV.first), std::move(KV.second)));
+ return std::make_pair(iterator(MapResult.first), MapResult.second);
}
/// insert - Range insertion of pairs.
@@ -258,9 +261,9 @@ public:
// I could == Copy.Map->Map.end() if the onRAUW callback already
// removed the old mapping.
if (I != Copy.Map->Map.end()) {
- ValueT Target(I->second);
+ ValueT Target(std::move(I->second));
Copy.Map->Map.erase(I); // Definitely destroys *this.
- Copy.Map->insert(std::make_pair(typed_new_key, Target));
+ Copy.Map->insert(std::make_pair(typed_new_key, std::move(Target)));
}
}
}
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 1d428b0..490d814 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -110,6 +110,7 @@ void initializeDeadInstEliminationPass(PassRegistry&);
void initializeDeadMachineInstructionElimPass(PassRegistry&);
void initializeDelinearizationPass(PassRegistry &);
void initializeDependenceAnalysisPass(PassRegistry&);
+void initializeDivergenceAnalysisPass(PassRegistry&);
void initializeDomOnlyPrinterPass(PassRegistry&);
void initializeDomOnlyViewerPass(PassRegistry&);
void initializeDomPrinterPass(PassRegistry&);
@@ -205,6 +206,7 @@ void initializeMergedLoadStoreMotionPass(PassRegistry &);
void initializeMetaRenamerPass(PassRegistry&);
void initializeMergeFunctionsPass(PassRegistry&);
void initializeModuleDebugInfoPrinterPass(PassRegistry&);
+void initializeNaryReassociatePass(PassRegistry&);
void initializeNoAAPass(PassRegistry&);
void initializeObjCARCAliasAnalysisPass(PassRegistry&);
void initializeObjCARCAPElimPass(PassRegistry&);
@@ -294,6 +296,7 @@ void initializeWinEHPreparePass(PassRegistry&);
void initializePlaceBackedgeSafepointsImplPass(PassRegistry&);
void initializePlaceSafepointsPass(PassRegistry&);
void initializeDwarfEHPreparePass(PassRegistry&);
+void initializeFloat2IntPass(PassRegistry&);
}
#endif
diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h
index 820d6d5..a4aace4 100644
--- a/include/llvm/LTO/LTOCodeGenerator.h
+++ b/include/llvm/LTO/LTOCodeGenerator.h
@@ -53,6 +53,7 @@ namespace llvm {
class TargetLibraryInfo;
class TargetMachine;
class raw_ostream;
+ class raw_pwrite_stream;
//===----------------------------------------------------------------------===//
/// C++ class which implements the opaque lto_code_gen_t type.
@@ -137,7 +138,7 @@ struct LTOCodeGenerator {
private:
void initializeLTOPasses();
- bool compileOptimized(raw_ostream &out, std::string &errMsg);
+ bool compileOptimized(raw_pwrite_stream &out, std::string &errMsg);
bool compileOptimizedToFile(const char **name, std::string &errMsg);
void applyScopeRestrictions();
void applyRestriction(GlobalValue &GV, ArrayRef<StringRef> Libcalls,
diff --git a/include/llvm/LineEditor/LineEditor.h b/include/llvm/LineEditor/LineEditor.h
index 1a9a691..bb106f8 100644
--- a/include/llvm/LineEditor/LineEditor.h
+++ b/include/llvm/LineEditor/LineEditor.h
@@ -119,7 +119,7 @@ private:
};
struct ListCompleterConcept : CompleterConcept {
- ~ListCompleterConcept();
+ ~ListCompleterConcept() override;
CompletionAction complete(StringRef Buffer, size_t Pos) const override;
static std::string getCommonPrefix(const std::vector<Completion> &Comps);
virtual std::vector<Completion> getCompletions(StringRef Buffer,
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index 391267c..bee39b1 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -15,6 +15,7 @@
#ifndef LLVM_LINKALLPASSES_H
#define LLVM_LINKALLPASSES_H
+#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/CallPrinter.h"
#include "llvm/Analysis/DomPrinter.h"
@@ -35,6 +36,7 @@
#include "llvm/Transforms/Utils/SymbolRewriter.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Transforms/Vectorize.h"
+#include "llvm/Support/Valgrind.h"
#include <cstdlib>
namespace {
@@ -74,6 +76,7 @@ namespace {
(void) llvm::createDeadInstEliminationPass();
(void) llvm::createDeadStoreEliminationPass();
(void) llvm::createDependenceAnalysisPass();
+ (void) llvm::createDivergenceAnalysisPass();
(void) llvm::createDomOnlyPrinterPass();
(void) llvm::createDomPrinterPass();
(void) llvm::createDomOnlyViewerPass();
@@ -106,6 +109,7 @@ namespace {
(void) llvm::createLowerExpectIntrinsicPass();
(void) llvm::createLowerInvokePass();
(void) llvm::createLowerSwitchPass();
+ (void) llvm::createNaryReassociatePass();
(void) llvm::createNoAAPass();
(void) llvm::createObjCARCAliasAnalysisPass();
(void) llvm::createObjCARCAPElimPass();
@@ -169,6 +173,7 @@ namespace {
(void) llvm::createRewriteSymbolsPass();
(void) llvm::createStraightLineStrengthReducePass();
(void) llvm::createMemDerefPrinter();
+ (void) llvm::createFloat2IntPass();
(void)new llvm::IntervalPartition();
(void)new llvm::ScalarEvolution();
@@ -177,6 +182,8 @@ namespace {
((llvm::RegionPass*)nullptr)->runOnRegion((llvm::Region*)nullptr, RGM);
llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)nullptr);
X.add(nullptr, 0, llvm::AAMDNodes()); // for -print-alias-sets
+ (void) llvm::AreStatisticsEnabled();
+ (void) llvm::sys::RunningOnValgrind();
}
} ForcePassLinking; // Force link by creating a global definition.
}
diff --git a/include/llvm/MC/ConstantPools.h b/include/llvm/MC/ConstantPools.h
index 1fc0332..ee7022b 100644
--- a/include/llvm/MC/ConstantPools.h
+++ b/include/llvm/MC/ConstantPools.h
@@ -77,9 +77,6 @@ class AssemblerConstantPools {
ConstantPoolMapTy ConstantPools;
public:
- AssemblerConstantPools() {}
- ~AssemblerConstantPools() {}
-
void emitAll(MCStreamer &Streamer);
void emitForCurrentSection(MCStreamer &Streamer);
const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr,
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h
index 56da95d..ff77dc9 100644
--- a/include/llvm/MC/MCAsmBackend.h
+++ b/include/llvm/MC/MCAsmBackend.h
@@ -30,7 +30,7 @@ class MCSection;
class MCValue;
class raw_ostream;
-/// MCAsmBackend - Generic interface to target specific assembler backends.
+/// Generic interface to target specific assembler backends.
class MCAsmBackend {
MCAsmBackend(const MCAsmBackend &) = delete;
void operator=(const MCAsmBackend &) = delete;
@@ -46,42 +46,42 @@ public:
/// lifetime management
virtual void reset() {}
- /// createObjectWriter - Create a new MCObjectWriter instance for use by the
- /// assembler backend to emit the final object file.
- virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;
+ /// Create a new MCObjectWriter instance for use by the assembler backend to
+ /// emit the final object file.
+ virtual MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const = 0;
- /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to enable
- /// non-standard ELFObjectWriters.
+ /// Create a new ELFObjectTargetWriter to enable non-standard
+ /// ELFObjectWriters.
virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const {
llvm_unreachable("createELFObjectTargetWriter is not supported by asm "
"backend");
}
- /// hasDataInCodeSupport - Check whether this target implements data-in-code
- /// markers. If not, data region directives will be ignored.
+ /// Check whether this target implements data-in-code markers. If not, data
+ /// region directives will be ignored.
bool hasDataInCodeSupport() const { return HasDataInCodeSupport; }
/// @name Target Fixup Interfaces
/// @{
- /// getNumFixupKinds - Get the number of target specific fixup kinds.
+ /// Get the number of target specific fixup kinds.
virtual unsigned getNumFixupKinds() const = 0;
- /// getFixupKindInfo - Get information on a fixup kind.
+ /// Get information on a fixup kind.
virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
- /// processFixupValue - Target hook to adjust the literal value of a fixup
- /// if necessary. IsResolved signals whether the caller believes a relocation
- /// is needed; the target can modify the value. The default does nothing.
+ /// Target hook to adjust the literal value of a fixup if necessary.
+ /// IsResolved signals whether the caller believes a relocation is needed; the
+ /// target can modify the value. The default does nothing.
virtual void processFixupValue(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
const MCValue &Target, uint64_t &Value,
bool &IsResolved) {}
- /// applyFixup - Apply the \p Value for given \p Fixup into the provided
- /// data fragment, at the offset specified by the fixup and following the
- /// fixup kind as appropriate.
+ /// Apply the \p Value for given \p Fixup into the provided data fragment, at
+ /// the offset specified by the fixup and following the fixup kind as
+ /// appropriate.
virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
uint64_t Value, bool IsPCRel) const = 0;
@@ -90,20 +90,18 @@ public:
/// @name Target Relaxation Interfaces
/// @{
- /// mayNeedRelaxation - Check whether the given instruction may need
- /// relaxation.
+ /// Check whether the given instruction may need relaxation.
///
/// \param Inst - The instruction to test.
virtual bool mayNeedRelaxation(const MCInst &Inst) const = 0;
- /// fixupNeedsRelaxation - Target specific predicate for whether a given
- /// fixup requires the associated instruction to be relaxed.
+ /// Target specific predicate for whether a given fixup requires the
+ /// associated instruction to be relaxed.
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const = 0;
- /// RelaxInstruction - Relax the instruction in the given fragment to the next
- /// wider instruction.
+ /// Relax the instruction in the given fragment to the next wider instruction.
///
/// \param Inst The instruction to relax, which may be the same as the
/// output.
@@ -112,22 +110,19 @@ public:
/// @}
- /// getMinimumNopSize - Returns the minimum size of a nop in bytes on this
- /// target. The assembler will use this to emit excess padding in situations
- /// where the padding required for simple alignment would be less than the
- /// minimum nop size.
+ /// Returns the minimum size of a nop in bytes on this target. The assembler
+ /// will use this to emit excess padding in situations where the padding
+ /// required for simple alignment would be less than the minimum nop size.
///
virtual unsigned getMinimumNopSize() const { return 1; }
- /// writeNopData - Write an (optimal) nop sequence of Count bytes to the given
- /// output. If the target cannot generate such a sequence, it should return an
- /// error.
+ /// Write an (optimal) nop sequence of Count bytes to the given output. If the
+ /// target cannot generate such a sequence, it should return an error.
///
/// \return - True on success.
virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const = 0;
- /// handleAssemblerFlag - Handle any target-specific assembler flags.
- /// By default, do nothing.
+ /// Handle any target-specific assembler flags. By default, do nothing.
virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {}
/// \brief Generate the compact unwind encoding for the CFI instructions.
diff --git a/include/llvm/MC/MCAsmInfoELF.h b/include/llvm/MC/MCAsmInfoELF.h
index 7bd2460..afd4933 100644
--- a/include/llvm/MC/MCAsmInfoELF.h
+++ b/include/llvm/MC/MCAsmInfoELF.h
@@ -15,8 +15,7 @@
namespace llvm {
class MCAsmInfoELF : public MCAsmInfo {
virtual void anchor();
- const MCSection *
- getNonexecutableStackSection(MCContext &Ctx) const override final;
+ const MCSection *getNonexecutableStackSection(MCContext &Ctx) const final;
protected:
MCAsmInfoELF();
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index 4d1590a..8b012be 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -50,11 +50,6 @@ private:
/// \brief Is the layout for this fragment valid?
bool isFragmentValid(const MCFragment *F) const;
- /// \brief Compute the amount of padding required before this fragment to
- /// obey bundling restrictions.
- uint64_t computeBundlePadding(const MCFragment *F,
- uint64_t FOffset, uint64_t FSize);
-
public:
MCAsmLayout(MCAssembler &Assembler);
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 9a85293..b8e9227 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -143,7 +143,7 @@ public:
: MCFragment(FType, SD), BundlePadding(0)
{
}
- virtual ~MCEncodedFragment();
+ ~MCEncodedFragment() override;
virtual SmallVectorImpl<char> &getContents() = 0;
virtual const SmallVectorImpl<char> &getContents() const = 0;
@@ -182,7 +182,7 @@ public:
{
}
- virtual ~MCEncodedFragmentWithFixups();
+ ~MCEncodedFragmentWithFixups() override;
typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
@@ -1245,11 +1245,23 @@ public:
FileNames.push_back(FileName);
}
+ /// \brief Write the necessary bundle padding to the given object writer.
+ /// Expects a fragment \p F containing instructions and its size \p FSize.
+ void writeFragmentPadding(const MCFragment &F, uint64_t FSize,
+ MCObjectWriter *OW) const;
+
/// @}
void dump();
};
+/// \brief Compute the amount of padding required before the fragment \p F to
+/// obey bundling restrictions, where \p FOffset is the fragment's offset in
+/// its section and \p FSize is the fragment's size.
+uint64_t computeBundlePadding(const MCAssembler &Assembler,
+ const MCFragment *F,
+ uint64_t FOffset, uint64_t FSize);
+
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 064f471..bf473cc 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -162,12 +162,44 @@ namespace llvm {
/// The Compile Unit ID that we are currently processing.
unsigned DwarfCompileUnitID;
- typedef std::pair<std::string, std::string> SectionGroupPair;
- typedef std::tuple<std::string, std::string, int> SectionGroupTriple;
+ struct ELFSectionKey {
+ std::string SectionName;
+ StringRef GroupName;
+ unsigned UniqueID;
+ ELFSectionKey(StringRef SectionName, StringRef GroupName,
+ unsigned UniqueID)
+ : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
+ }
+ bool operator<(const ELFSectionKey &Other) const {
+ if (SectionName != Other.SectionName)
+ return SectionName < Other.SectionName;
+ if (GroupName != Other.GroupName)
+ return GroupName < Other.GroupName;
+ return UniqueID < Other.UniqueID;
+ }
+ };
+
+ struct COFFSectionKey {
+ std::string SectionName;
+ StringRef GroupName;
+ int SelectionKey;
+ COFFSectionKey(StringRef SectionName, StringRef GroupName,
+ int SelectionKey)
+ : SectionName(SectionName), GroupName(GroupName),
+ SelectionKey(SelectionKey) {}
+ bool operator<(const COFFSectionKey &Other) const {
+ if (SectionName != Other.SectionName)
+ return SectionName < Other.SectionName;
+ if (GroupName != Other.GroupName)
+ return GroupName < Other.GroupName;
+ return SelectionKey < Other.SelectionKey;
+ }
+ };
StringMap<const MCSectionMachO*> MachOUniquingMap;
- std::map<SectionGroupPair, const MCSectionELF *> ELFUniquingMap;
- std::map<SectionGroupTriple, const MCSectionCOFF *> COFFUniquingMap;
+ std::map<ELFSectionKey, const MCSectionELF *> ELFUniquingMap;
+ std::map<COFFSectionKey, const MCSectionCOFF *> COFFUniquingMap;
+ StringMap<bool> ELFRelSecNames;
/// Do automatic reset in destructor
bool AutoReset;
@@ -231,8 +263,14 @@ namespace llvm {
MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section);
+ /// Gets a symbol that will be defined to the final stack offset of a local
+ /// variable after codegen.
+ ///
+ /// @param Idx - The index of a local variable passed to @llvm.frameescape.
MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx);
+ MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName);
+
/// Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(const Twine &Name) const;
@@ -265,18 +303,52 @@ namespace llvm {
}
const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags) {
+ return getELFSection(Section, Type, Flags, nullptr);
+ }
+
+ const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags,
- const char *BeginSymName = nullptr);
+ const char *BeginSymName) {
+ return getELFSection(Section, Type, Flags, 0, "", BeginSymName);
+ }
+
+ const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ StringRef Group) {
+ return getELFSection(Section, Type, Flags, EntrySize, Group, nullptr);
+ }
const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
StringRef Group,
- const char *BeginSymName = nullptr);
+ const char *BeginSymName) {
+ return getELFSection(Section, Type, Flags, EntrySize, Group, ~0,
+ BeginSymName);
+ }
+
+ const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ StringRef Group, unsigned UniqueID) {
+ return getELFSection(Section, Type, Flags, EntrySize, Group, UniqueID,
+ nullptr);
+ }
+
+ const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ StringRef Group, unsigned UniqueID,
+ const char *BeginSymName);
const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
- StringRef Group, bool Unique,
- const char *BeginSymName = nullptr);
+ const MCSymbol *Group, unsigned UniqueID,
+ const char *BeginSymName,
+ const MCSectionELF *Associated);
+
+ const MCSectionELF *createELFRelSection(StringRef Name, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ const MCSymbol *Group,
+ const MCSectionELF *Associated);
void renameELFSection(const MCSectionELF *Section, StringRef Name);
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index 7493507..e9fef76 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -24,6 +24,18 @@ class MCSectionData;
class MCSymbol;
class MCSymbolData;
class MCValue;
+class raw_pwrite_stream;
+
+struct ELFRelocationEntry {
+ uint64_t Offset; // Where is the relocation.
+ const MCSymbol *Symbol; // The symbol to relocate with.
+ unsigned Type; // The type of the relocation.
+ uint64_t Addend; // The addend to use.
+
+ ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type,
+ uint64_t Addend)
+ : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {}
+};
class MCELFObjectTargetWriter {
const uint8_t OSABI;
@@ -61,6 +73,9 @@ public:
virtual bool needsRelocateWithSymbol(const MCSymbolData &SD,
unsigned Type) const;
+ virtual void sortRelocs(const MCAssembler &Asm,
+ std::vector<ELFRelocationEntry> &Relocs);
+
/// @name Accessors
/// @{
uint8_t getOSABI() const { return OSABI; }
@@ -116,7 +131,8 @@ public:
/// \param OS - The stream to write to.
/// \returns The constructed object writer.
MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &OS, bool IsLittleEndian);
+ raw_pwrite_stream &OS,
+ bool IsLittleEndian);
} // End llvm namespace
#endif
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
index ab6c5e3..ace4ee3 100644
--- a/include/llvm/MC/MCELFStreamer.h
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -29,23 +29,18 @@ class raw_ostream;
class MCELFStreamer : public MCObjectStreamer {
public:
- MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter),
- SeenIdent(false) {}
+ : MCObjectStreamer(Context, TAB, OS, Emitter), SeenIdent(false) {}
- MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
- MCCodeEmitter *Emitter, MCAssembler *Assembler)
- : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler),
- SeenIdent(false) {}
-
- virtual ~MCELFStreamer();
+ ~MCELFStreamer() override;
/// state management
void reset() override {
+ SeenIdent = false;
LocalCommons.clear();
BindingExplicitlySet.clear();
- SeenIdent = false;
+ BundleGroups.clear();
MCObjectStreamer::reset();
}
@@ -100,6 +95,9 @@ private:
void fixSymbolsInTLSFixups(const MCExpr *expr);
+ /// \brief Merge the content of the fragment \p EF into the fragment \p DF.
+ void mergeFragment(MCDataFragment *, MCEncodedFragmentWithFixups *);
+
bool SeenIdent;
struct LocalCommon {
@@ -111,11 +109,16 @@ private:
std::vector<LocalCommon> LocalCommons;
SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
+
+ /// BundleGroups - The stack of fragments holding the bundle-locked
+ /// instructions.
+ llvm::SmallVector<MCDataFragment *, 4> BundleGroups;
};
MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter,
- bool RelaxAll, bool IsThumb);
+ raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter, bool RelaxAll,
+ bool IsThumb);
} // end namespace llvm
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
index dce3a06..4181d00 100644
--- a/include/llvm/MC/MCInstPrinter.h
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -19,6 +19,7 @@ class raw_ostream;
class MCAsmInfo;
class MCInstrInfo;
class MCRegisterInfo;
+class MCSubtargetInfo;
class StringRef;
namespace HexStyle {
@@ -40,9 +41,6 @@ protected:
const MCInstrInfo &MII;
const MCRegisterInfo &MRI;
- /// The current set of available features.
- uint64_t AvailableFeatures;
-
/// True if we are printing marked up assembly.
bool UseMarkup;
@@ -58,7 +56,7 @@ public:
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
const MCRegisterInfo &mri)
: CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri),
- AvailableFeatures(0), UseMarkup(0), PrintImmHex(0),
+ UseMarkup(0), PrintImmHex(0),
PrintHexStyle(HexStyle::C) {}
virtual ~MCInstPrinter();
@@ -69,7 +67,7 @@ public:
/// printInst - Print the specified MCInst to the specified raw_ostream.
///
virtual void printInst(const MCInst *MI, raw_ostream &OS,
- StringRef Annot) = 0;
+ StringRef Annot, const MCSubtargetInfo &STI) = 0;
/// getOpcodeName - Return the name of the specified opcode enum (e.g.
/// "MOV32ri") or empty if we can't resolve it.
@@ -78,9 +76,6 @@ public:
/// printRegName - Print the assembler register name.
virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
- uint64_t getAvailableFeatures() const { return AvailableFeatures; }
- void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; }
-
bool getUseMarkup() const { return UseMarkup; }
void setUseMarkup(bool Value) { UseMarkup = Value; }
diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h
index 890d638..c96d578 100644
--- a/include/llvm/MC/MCLinkerOptimizationHint.h
+++ b/include/llvm/MC/MCLinkerOptimizationHint.h
@@ -141,7 +141,7 @@ public:
public:
raw_counting_ostream() : Count(0) {}
- ~raw_counting_ostream() { flush(); }
+ ~raw_counting_ostream() override { flush(); }
};
raw_counting_ostream OutStream;
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index 514700b..bfe5d36 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -119,7 +119,7 @@ class MachObjectWriter : public MCObjectWriter {
MachSymbolData *findSymbolData(const MCSymbol &Sym);
public:
- MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &OS,
+ MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_pwrite_stream &OS,
bool IsLittleEndian)
: MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
@@ -257,13 +257,12 @@ public:
void computeSectionAddresses(const MCAssembler &Asm,
const MCAsmLayout &Layout);
- void markAbsoluteVariableSymbols(MCAssembler &Asm,
- const MCAsmLayout &Layout);
void ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) override;
bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbolData &DataA,
+ const MCSymbolData *DataB,
const MCFragment &FB,
bool InSet,
bool IsPCRel) const override;
@@ -280,7 +279,8 @@ public:
/// \param OS - The stream to write to.
/// \returns The constructed object writer.
MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
- raw_ostream &OS, bool IsLittleEndian);
+ raw_pwrite_stream &OS,
+ bool IsLittleEndian);
} // End llvm namespace
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 2420072..6666a50 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -24,6 +24,7 @@ class MCFragment;
class MCDataFragment;
class MCAsmBackend;
class raw_ostream;
+class raw_pwrite_stream;
/// \brief Streaming object file generation interface.
///
@@ -44,16 +45,10 @@ class MCObjectStreamer : public MCStreamer {
void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
- // If any labels have been emitted but not assigned fragments, ensure that
- // they get assigned, either to F if possible or to a new data fragment.
- void flushPendingLabels(MCFragment *F);
-
protected:
- MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
MCCodeEmitter *Emitter);
- MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
- MCCodeEmitter *Emitter, MCAssembler *Assembler);
- ~MCObjectStreamer();
+ ~MCObjectStreamer() override;
public:
/// state management
@@ -87,6 +82,12 @@ protected:
bool changeSectionImpl(const MCSection *Section, const MCExpr *Subsection);
+ /// If any labels have been emitted but not assigned fragments, ensure that
+ /// they get assigned, either to F if possible or to a new data fragment.
+ /// Optionally, it is also possible to provide an offset \p FOffset, which
+ /// will be used as a symbol offset within the fragment.
+ void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0);
+
public:
void visitUsedSymbol(const MCSymbol &Sym) override;
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index fcfa968..f8e2821 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/EndianStream.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
@@ -41,12 +42,12 @@ class MCObjectWriter {
void operator=(const MCObjectWriter &) = delete;
protected:
- raw_ostream &OS;
+ raw_pwrite_stream &OS;
unsigned IsLittleEndian : 1;
protected: // Can only create subclasses.
- MCObjectWriter(raw_ostream &OS, bool IsLittleEndian)
+ MCObjectWriter(raw_pwrite_stream &OS, bool IsLittleEndian)
: OS(OS), IsLittleEndian(IsLittleEndian) {}
public:
@@ -91,12 +92,12 @@ public:
const MCSymbolRefExpr *B,
bool InSet) const;
- virtual bool
- IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
- const MCSymbolData &DataA,
- const MCFragment &FB,
- bool InSet,
- bool IsPCRel) const;
+ virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCSymbolData *DataB,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
/// \brief True if this symbol (which is a variable) is weak. This is not
/// just STB_WEAK, but more generally whether or not we can evaluate
@@ -120,33 +121,27 @@ public:
}
void WriteLE16(uint16_t Value) {
- Write8(uint8_t(Value >> 0));
- Write8(uint8_t(Value >> 8));
+ support::endian::Writer<support::little>(OS).write(Value);
}
void WriteLE32(uint32_t Value) {
- WriteLE16(uint16_t(Value >> 0));
- WriteLE16(uint16_t(Value >> 16));
+ support::endian::Writer<support::little>(OS).write(Value);
}
void WriteLE64(uint64_t Value) {
- WriteLE32(uint32_t(Value >> 0));
- WriteLE32(uint32_t(Value >> 32));
+ support::endian::Writer<support::little>(OS).write(Value);
}
void WriteBE16(uint16_t Value) {
- Write8(uint8_t(Value >> 8));
- Write8(uint8_t(Value >> 0));
+ support::endian::Writer<support::big>(OS).write(Value);
}
void WriteBE32(uint32_t Value) {
- WriteBE16(uint16_t(Value >> 16));
- WriteBE16(uint16_t(Value >> 0));
+ support::endian::Writer<support::big>(OS).write(Value);
}
void WriteBE64(uint64_t Value) {
- WriteBE32(uint32_t(Value >> 32));
- WriteBE32(uint32_t(Value >> 0));
+ support::endian::Writer<support::big>(OS).write(Value);
}
void Write16(uint16_t Value) {
diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h
index 2f681d6..62d39b2 100644
--- a/include/llvm/MC/MCParser/AsmLexer.h
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -40,7 +40,7 @@ protected:
public:
AsmLexer(const MCAsmInfo &MAI);
- ~AsmLexer();
+ ~AsmLexer() override;
void setBuffer(StringRef Buf, const char *ptr = nullptr);
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index b6ec1d8..237f6d3 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -53,7 +53,7 @@ class MCSymbol;
assert ((Characteristics & 0x00F00000) == 0 &&
"alignment must not be set upon section creation");
}
- ~MCSectionCOFF();
+ ~MCSectionCOFF() override;
public:
/// ShouldOmitSectionDirective - Decides whether a '.section' directive
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 434a5b6..9efe102 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -39,7 +39,7 @@ class MCSectionELF : public MCSection {
/// below.
unsigned Flags;
- bool Unique;
+ unsigned UniqueID;
/// EntrySize - The size of each entry in this section. This size only
/// makes sense for sections that contain fixed-sized entries. If a
@@ -48,14 +48,18 @@ class MCSectionELF : public MCSection {
const MCSymbol *Group;
+ /// Depending on the type of the section this is sh_link or sh_info.
+ const MCSectionELF *Associated;
+
private:
friend class MCContext;
MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K,
- unsigned entrySize, const MCSymbol *group, bool Unique,
- MCSymbol *Begin)
+ unsigned entrySize, const MCSymbol *group, unsigned UniqueID,
+ MCSymbol *Begin, const MCSectionELF *Associated)
: MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type),
- Flags(flags), Unique(Unique), EntrySize(entrySize), Group(group) {}
- ~MCSectionELF();
+ Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group),
+ Associated(Associated) {}
+ ~MCSectionELF() override;
void setSectionName(StringRef Name) { SectionName = Name; }
@@ -76,6 +80,11 @@ public:
bool UseCodeAlign() const override;
bool isVirtualSection() const override;
+ bool isUnique() const { return UniqueID != ~0U; }
+ unsigned getUniqueID() const { return UniqueID; }
+
+ const MCSectionELF *getAssociatedSection() const { return Associated; }
+
static bool classof(const MCSection *S) {
return S->getVariant() == SV_ELF;
}
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index df7610b..ad2bbcf 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -90,7 +90,7 @@ public:
class AArch64TargetStreamer : public MCTargetStreamer {
public:
AArch64TargetStreamer(MCStreamer &S);
- ~AArch64TargetStreamer();
+ ~AArch64TargetStreamer() override;
void finish() override;
@@ -115,7 +115,7 @@ private:
class ARMTargetStreamer : public MCTargetStreamer {
public:
ARMTargetStreamer(MCStreamer &S);
- ~ARMTargetStreamer();
+ ~ARMTargetStreamer() override;
virtual void emitFnStart();
virtual void emitFnEnd();
@@ -746,7 +746,8 @@ MCStreamer *createNullStreamer(MCContext &Ctx);
///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
-MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+MCStreamer *createAsmStreamer(MCContext &Ctx,
+ std::unique_ptr<formatted_raw_ostream> OS,
bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index 53443b0..e4bdfda 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -15,6 +15,7 @@
#define LLVM_MC_MCSYMBOL_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -42,8 +43,9 @@ namespace llvm {
/// Section - The section the symbol is defined in. This is null for
/// undefined symbols, and the special AbsolutePseudoSection value for
- /// absolute symbols.
- const MCSection *Section;
+ /// absolute symbols. If this is a variable symbol, this caches the
+ /// variable value's section.
+ mutable const MCSection *Section;
/// Value - If non-null, the value for a variable symbol.
const MCExpr *Value;
@@ -68,6 +70,12 @@ namespace llvm {
MCSymbol(const MCSymbol&) = delete;
void operator=(const MCSymbol&) = delete;
+ const MCSection *getSectionPtr() const {
+ if (Section || !Value)
+ return Section;
+ return Section = Value->FindAssociatedSection();
+ }
+
public:
/// getName - Get the symbol name.
StringRef getName() const { return Name; }
@@ -103,7 +111,7 @@ namespace llvm {
///
/// Defined symbols are either absolute or in some section.
bool isDefined() const {
- return Section != nullptr;
+ return getSectionPtr() != nullptr;
}
/// isInSection - Check if this symbol is defined in some section (i.e., it
@@ -119,27 +127,27 @@ namespace llvm {
/// isAbsolute - Check if this is an absolute symbol.
bool isAbsolute() const {
- return Section == AbsolutePseudoSection;
+ return getSectionPtr() == AbsolutePseudoSection;
}
/// getSection - Get the section associated with a defined, non-absolute
/// symbol.
const MCSection &getSection() const {
assert(isInSection() && "Invalid accessor!");
- return *Section;
+ return *getSectionPtr();
}
/// setSection - Mark the symbol as defined in the section \p S.
- void setSection(const MCSection &S) { Section = &S; }
+ void setSection(const MCSection &S) {
+ assert(!isVariable() && "Cannot set section of variable");
+ Section = &S;
+ }
/// setUndefined - Mark the symbol as undefined.
void setUndefined() {
Section = nullptr;
}
- /// setAbsolute - Mark the symbol as absolute.
- void setAbsolute() { Section = AbsolutePseudoSection; }
-
/// @}
/// @name Variable Symbols
/// @{
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 8412b1d..36db391 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -75,8 +75,6 @@ struct ParseInstructionInfo {
ParseInstructionInfo() : AsmRewrites(nullptr) {}
ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites)
: AsmRewrites(rewrites) {}
-
- ~ParseInstructionInfo() {}
};
/// MCTargetAsmParser - Generic interface to target specific assembly parsers.
@@ -110,7 +108,7 @@ protected: // Can only create subclasses.
MCTargetOptions MCOptions;
public:
- virtual ~MCTargetAsmParser();
+ ~MCTargetAsmParser() override;
uint64_t getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; }
diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h
index 956e436..e2e95c7 100644
--- a/include/llvm/MC/MCWinCOFFObjectWriter.h
+++ b/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -16,6 +16,7 @@ class MCFixup;
class MCObjectWriter;
class MCValue;
class raw_ostream;
+class raw_pwrite_stream;
class MCWinCOFFObjectTargetWriter {
virtual void anchor();
@@ -40,7 +41,7 @@ class raw_ostream;
/// \param OS - The stream to write to.
/// \returns The constructed object writer.
MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
- raw_ostream &OS);
+ raw_pwrite_stream &OS);
} // End llvm namespace
#endif
diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h
index 57a75ce..b3fee81 100644
--- a/include/llvm/MC/MCWinCOFFStreamer.h
+++ b/include/llvm/MC/MCWinCOFFStreamer.h
@@ -24,11 +24,12 @@ class MCSubtargetInfo;
class MCSymbol;
class StringRef;
class raw_ostream;
+class raw_pwrite_stream;
class MCWinCOFFStreamer : public MCObjectStreamer {
public:
MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, MCCodeEmitter &CE,
- raw_ostream &OS);
+ raw_pwrite_stream &OS);
/// state management
void reset() override {
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
index bfecb8b..6f195d7 100644
--- a/include/llvm/MC/SubtargetFeature.h
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -78,7 +78,7 @@ public:
std::string getString() const;
/// Adding Features.
- void AddFeature(StringRef String);
+ void AddFeature(StringRef String, bool Enable = true);
/// ToggleFeature - Toggle a feature and returns the newly updated feature
/// bits.
diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h
index 74f4666..ef65528 100644
--- a/include/llvm/Object/IRObjectFile.h
+++ b/include/llvm/Object/IRObjectFile.h
@@ -31,7 +31,7 @@ class IRObjectFile : public SymbolicFile {
public:
IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> M);
- ~IRObjectFile();
+ ~IRObjectFile() override;
void moveSymbolNext(DataRefImpl &Symb) const override;
std::error_code printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const override;
diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h
index b6a8b4d..114b229 100644
--- a/include/llvm/Object/SymbolicFile.h
+++ b/include/llvm/Object/SymbolicFile.h
@@ -118,7 +118,7 @@ const uint64_t UnknownAddressOrSize = ~0ULL;
class SymbolicFile : public Binary {
public:
- virtual ~SymbolicFile();
+ ~SymbolicFile() override;
SymbolicFile(unsigned int Type, MemoryBufferRef Source);
// virtual interface.
diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h
index 9a09309..23b0451 100644
--- a/include/llvm/Option/ArgList.h
+++ b/include/llvm/Option/ArgList.h
@@ -320,7 +320,7 @@ private:
public:
InputArgList(const char* const *ArgBegin, const char* const *ArgEnd);
- ~InputArgList();
+ ~InputArgList() override;
const char *getArgString(unsigned Index) const override {
return ArgStrings[Index];
@@ -355,7 +355,7 @@ class DerivedArgList : public ArgList {
public:
/// Construct a new derived arg list from \p BaseArgs.
DerivedArgList(const InputArgList &BaseArgs);
- ~DerivedArgList();
+ ~DerivedArgList() override;
const char *getArgString(unsigned Index) const override {
return BaseArgs.getArgString(Index);
diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h
index 6e92d96..3c4d838 100644
--- a/include/llvm/Pass.h
+++ b/include/llvm/Pass.h
@@ -250,7 +250,7 @@ public:
explicit ModulePass(char &pid) : Pass(PT_Module, pid) {}
// Force out-of-line virtual method.
- virtual ~ModulePass();
+ ~ModulePass() override;
};
@@ -279,7 +279,7 @@ public:
: ModulePass(pid) {}
// Force out-of-line virtual method.
- virtual ~ImmutablePass();
+ ~ImmutablePass() override;
};
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index de31771..94cf3e8 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -203,7 +203,8 @@ public:
}
/// \brief Allocate space at the specified alignment.
- LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) {
+ LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void *
+ Allocate(size_t Size, size_t Alignment) {
assert(Alignment > 0 && "0-byte alignnment is not allowed. Use 1 instead.");
// Keep track of how many bytes we've allocated.
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index f7de840..c81fbaf 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -72,20 +72,20 @@
#define LLVM_NOEXCEPT
#endif
-/// \brief Does the compiler support r-value reference *this?
+/// \brief Does the compiler support ref-qualifiers for *this?
///
-/// Sadly, this is separate from just r-value reference support because GCC
-/// implemented this later than everything else.
+/// Sadly, this is separate from just rvalue reference support because GCC
+/// and MSVC implemented this later than everything else.
#if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1)
#define LLVM_HAS_RVALUE_REFERENCE_THIS 1
#else
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
#endif
-/// Expands to '&' if r-value references are supported.
+/// Expands to '&' if ref-qualifiers for *this are supported.
///
-/// This can be used to provide l-value/r-value overrides of member functions.
-/// The r-value override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
+/// This can be used to provide lvalue/rvalue overrides of member functions.
+/// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
#if LLVM_HAS_RVALUE_REFERENCE_THIS
#define LLVM_LVALUE_FUNCTION &
#else
@@ -223,6 +223,16 @@
#define LLVM_ATTRIBUTE_RETURNS_NONNULL
#endif
+/// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a
+/// pointer that does not alias any other valid pointer.
+#ifdef __GNUC__
+#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
+#elif defined(_MSC_VER)
+#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
+#else
+#define LLVM_ATTRIBUTE_RETURNS_NOALIAS
+#endif
+
/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
/// pedantic diagnostics.
#ifdef __GNUC__
@@ -281,6 +291,37 @@
# define LLVM_ASSUME_ALIGNED(p, a) (p)
#endif
+/// \macro LLVM_ALIGNAS
+/// \brief Used to specify a minimum alignment for a structure or variable. The
+/// alignment must be a constant integer. Use LLVM_PTR_SIZE to compute
+/// alignments in terms of the size of a pointer.
+///
+/// Note that __declspec(align) has special quirks, it's not legal to pass a
+/// structure with __declspec(align) as a formal parameter.
+#ifdef _MSC_VER
+# define LLVM_ALIGNAS(x) __declspec(align(x))
+#elif __GNUC__ && !__has_feature(cxx_alignas) && !LLVM_GNUC_PREREQ(4, 8, 0)
+# define LLVM_ALIGNAS(x) __attribute__((aligned(x)))
+#else
+# define LLVM_ALIGNAS(x) alignas(x)
+#endif
+
+/// \macro LLVM_PTR_SIZE
+/// \brief A constant integer equivalent to the value of sizeof(void*).
+/// Generally used in combination with LLVM_ALIGNAS or when doing computation in
+/// the preprocessor.
+#ifdef __SIZEOF_POINTER__
+# define LLVM_PTR_SIZE __SIZEOF_POINTER__
+#elif defined(_WIN64)
+# define LLVM_PTR_SIZE 8
+#elif defined(_WIN32)
+# define LLVM_PTR_SIZE 4
+#elif defined(_MSC_VER)
+# error "could not determine LLVM_PTR_SIZE as a constant int for MSVC"
+#else
+# define LLVM_PTR_SIZE sizeof(void *)
+#endif
+
/// \macro LLVM_FUNCTION_NAME
/// \brief Expands to __func__ on compilers which support it. Otherwise,
/// expands to a compiler-dependent replacement.
diff --git a/include/llvm/Support/ELFRelocs/Mips.def b/include/llvm/Support/ELFRelocs/Mips.def
index dc57346..0e6de3b 100644
--- a/include/llvm/Support/ELFRelocs/Mips.def
+++ b/include/llvm/Support/ELFRelocs/Mips.def
@@ -110,3 +110,4 @@ ELF_RELOC(R_MICROMIPS_GPREL7_S2, 172)
ELF_RELOC(R_MICROMIPS_PC23_S2, 173)
ELF_RELOC(R_MIPS_NUM, 218)
ELF_RELOC(R_MIPS_PC32, 248)
+ELF_RELOC(R_MIPS_EH, 249)
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index b3b44c4..a736c32 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -120,7 +120,7 @@ class UniqueID {
uint64_t File;
public:
- UniqueID() {}
+ UniqueID() = default;
UniqueID(uint64_t Device, uint64_t File) : Device(Device), File(File) {}
bool operator==(const UniqueID &Other) const {
return Device == Other.Device && File == Other.File;
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index 8137daa..4a135cd 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -25,27 +25,11 @@ namespace llvm {
/// boundaries and querying the number of lines written to the stream.
///
class formatted_raw_ostream : public raw_ostream {
-public:
- /// DELETE_STREAM - Tell the destructor to delete the held stream.
- ///
- static const bool DELETE_STREAM = true;
-
- /// PRESERVE_STREAM - Tell the destructor to not delete the held
- /// stream.
- ///
- static const bool PRESERVE_STREAM = false;
-
-private:
/// TheStream - The real stream we output to. We set it to be
/// unbuffered, since we're already doing our own buffering.
///
raw_ostream *TheStream;
- /// DeleteStream - Do we need to delete TheStream in the
- /// destructor?
- ///
- bool DeleteStream;
-
/// Position - The current output column and line of the data that's
/// been flushed and the portion of the buffer that's been
/// scanned. The line and column scheme is zero-based.
@@ -73,6 +57,24 @@ private:
///
void ComputePosition(const char *Ptr, size_t size);
+ void setStream(raw_ostream &Stream) {
+ releaseStream();
+
+ TheStream = &Stream;
+
+ // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
+ // own buffering, and it doesn't need or want TheStream to do another
+ // layer of buffering underneath. Resize the buffer to what TheStream
+ // had been using, and tell TheStream not to do its own buffering.
+ if (size_t BufferSize = TheStream->GetBufferSize())
+ SetBufferSize(BufferSize);
+ else
+ SetUnbuffered();
+ TheStream->SetUnbuffered();
+
+ Scanned = nullptr;
+ }
+
public:
/// formatted_raw_ostream - Open the specified file for
/// writing. If an error occurs, information about the error is
@@ -84,39 +86,19 @@ public:
/// so it doesn't want another layer of buffering to be happening
/// underneath it.
///
- formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
- : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
- setStream(Stream, Delete);
+ formatted_raw_ostream(raw_ostream &Stream)
+ : TheStream(nullptr), Position(0, 0) {
+ setStream(Stream);
}
- explicit formatted_raw_ostream()
- : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
+ explicit formatted_raw_ostream() : TheStream(nullptr), Position(0, 0) {
Scanned = nullptr;
}
- ~formatted_raw_ostream() {
+ ~formatted_raw_ostream() override {
flush();
releaseStream();
}
- void setStream(raw_ostream &Stream, bool Delete = false) {
- releaseStream();
-
- TheStream = &Stream;
- DeleteStream = Delete;
-
- // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
- // own buffering, and it doesn't need or want TheStream to do another
- // layer of buffering underneath. Resize the buffer to what TheStream
- // had been using, and tell TheStream not to do its own buffering.
- if (size_t BufferSize = TheStream->GetBufferSize())
- SetBufferSize(BufferSize);
- else
- SetUnbuffered();
- TheStream->SetUnbuffered();
-
- Scanned = nullptr;
- }
-
/// PadToColumn - Align the output to some column number. If the current
/// column is already equal to or more than NewCol, PadToColumn inserts one
/// space.
@@ -151,13 +133,11 @@ public:
private:
void releaseStream() {
- // Delete the stream if needed. Otherwise, transfer the buffer
- // settings from this raw_ostream back to the underlying stream.
+ // Transfer the buffer settings from this raw_ostream back to the underlying
+ // stream.
if (!TheStream)
return;
- if (DeleteStream)
- delete TheStream;
- else if (size_t BufferSize = GetBufferSize())
+ if (size_t BufferSize = GetBufferSize())
TheStream->SetBufferSize(BufferSize);
else
TheStream->SetUnbuffered();
diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h
index 0998eb9..63678bb 100644
--- a/include/llvm/Support/GenericDomTree.h
+++ b/include/llvm/Support/GenericDomTree.h
@@ -243,6 +243,8 @@ protected:
this->Roots.clear();
Vertex.clear();
RootNode = nullptr;
+ DFSInfoValid = false;
+ SlowQueries = 0;
}
// NewBB is split and now it has one successor. Update dominator tree to
@@ -637,9 +639,38 @@ protected:
friend void
Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT, FuncT &F);
+
+ DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
+ if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
+ return Node;
+
+ // Haven't calculated this node yet? Get or calculate the node for the
+ // immediate dominator.
+ NodeT *IDom = getIDom(BB);
+
+ assert(IDom || this->DomTreeNodes[nullptr]);
+ DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
+
+ // Add a new tree node for this NodeT, and link it as a child of
+ // IDomNode
+ return (this->DomTreeNodes[BB] = IDomNode->addChild(
+ llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get();
+ }
+
+ NodeT *getIDom(NodeT *BB) const { return IDoms.lookup(BB); }
+
+ void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
+
+public:
/// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
/// dominator tree in dfs order.
void updateDFSNumbers() const {
+
+ if (DFSInfoValid) {
+ SlowQueries = 0;
+ return;
+ }
+
unsigned DFSNum = 0;
SmallVector<std::pair<const DomTreeNodeBase<NodeT> *,
@@ -682,28 +713,6 @@ protected:
DFSInfoValid = true;
}
- DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
- if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
- return Node;
-
- // Haven't calculated this node yet? Get or calculate the node for the
- // immediate dominator.
- NodeT *IDom = getIDom(BB);
-
- assert(IDom || this->DomTreeNodes[nullptr]);
- DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
-
- // Add a new tree node for this NodeT, and link it as a child of
- // IDomNode
- return (this->DomTreeNodes[BB] = IDomNode->addChild(
- llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get();
- }
-
- NodeT *getIDom(NodeT *BB) const { return IDoms.lookup(BB); }
-
- void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
-
-public:
/// recalculate - compute a dominator tree for the given function
template <class FT> void recalculate(FT &F) {
typedef GraphTraits<FT *> TraitsTy;
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index 388d82c..7edc2ac 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -318,31 +318,31 @@ inline bool isIntN(unsigned N, int64_t x) {
return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
}
-/// isMask_32 - This function returns true if the argument is a sequence of ones
-/// starting at the least significant bit with the remainder zero (32 bit
-/// version). Ex. isMask_32(0x0000FFFFU) == true.
+/// isMask_32 - This function returns true if the argument is a non-empty
+/// sequence of ones starting at the least significant bit with the remainder
+/// zero (32 bit version). Ex. isMask_32(0x0000FFFFU) == true.
inline bool isMask_32(uint32_t Value) {
return Value && ((Value + 1) & Value) == 0;
}
-/// isMask_64 - This function returns true if the argument is a sequence of ones
-/// starting at the least significant bit with the remainder zero (64 bit
-/// version).
+/// isMask_64 - This function returns true if the argument is a non-empty
+/// sequence of ones starting at the least significant bit with the remainder
+/// zero (64 bit version).
inline bool isMask_64(uint64_t Value) {
return Value && ((Value + 1) & Value) == 0;
}
/// isShiftedMask_32 - This function returns true if the argument contains a
-/// sequence of ones with the remainder zero (32 bit version.)
+/// non-empty sequence of ones with the remainder zero (32 bit version.)
/// Ex. isShiftedMask_32(0x0000FF00U) == true.
inline bool isShiftedMask_32(uint32_t Value) {
- return isMask_32((Value - 1) | Value);
+ return Value && isMask_32((Value - 1) | Value);
}
/// isShiftedMask_64 - This function returns true if the argument contains a
-/// sequence of ones with the remainder zero (64 bit version.)
+/// non-empty sequence of ones with the remainder zero (64 bit version.)
inline bool isShiftedMask_64(uint64_t Value) {
- return isMask_64((Value - 1) | Value);
+ return Value && isMask_64((Value - 1) | Value);
}
/// isPowerOf2_32 - This function returns true if the argument is a power of
diff --git a/include/llvm/Support/OnDiskHashTable.h b/include/llvm/Support/OnDiskHashTable.h
index 52f133c..0f097f2 100644
--- a/include/llvm/Support/OnDiskHashTable.h
+++ b/include/llvm/Support/OnDiskHashTable.h
@@ -75,13 +75,10 @@ template <typename Info> class OnDiskChainedHashTableGenerator {
llvm::SpecificBumpPtrAllocator<Item> BA;
/// \brief A linked list of values in a particular hash bucket.
- class Bucket {
- public:
+ struct Bucket {
offset_type Off;
- Item *Head;
unsigned Length;
-
- Bucket() {}
+ Item *Head;
};
Bucket *Buckets;
diff --git a/include/llvm/Support/Options.h b/include/llvm/Support/Options.h
index 4fd1bff..2742d39 100644
--- a/include/llvm/Support/Options.h
+++ b/include/llvm/Support/Options.h
@@ -61,7 +61,7 @@ char OptionKey<ValT, Base, Mem>::ID = 0;
/// The OptionRegistry is responsible for managing lifetimes of the options and
/// provides interfaces for option registration and reading values from options.
/// This object is a singleton, only one instance should ever exist so that all
-/// options are registered in teh same place.
+/// options are registered in the same place.
class OptionRegistry {
private:
DenseMap<void *, cl::Option *> Options;
diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h
index a067b13..7e165d7 100644
--- a/include/llvm/Support/Signals.h
+++ b/include/llvm/Support/Signals.h
@@ -39,7 +39,7 @@ namespace sys {
/// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
/// process, print a stack trace and then exit.
/// @brief Print a stack trace if a fatal signal occurs.
- void PrintStackTraceOnErrorSignal();
+ void PrintStackTraceOnErrorSignal(bool DisableCrashReporting = false);
/// Disable all system dialog boxes that appear when the process crashes.
void DisableSystemDialogsOnCrash();
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index ba6bbde..a4bf51f 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -22,6 +22,7 @@
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/FormattedStream.h"
#include <cassert>
#include <memory>
#include <string>
@@ -49,20 +50,22 @@ namespace llvm {
class TargetMachine;
class TargetOptions;
class raw_ostream;
+ class raw_pwrite_stream;
class formatted_raw_ostream;
MCStreamer *createNullStreamer(MCContext &Ctx);
- MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ MCStreamer *createAsmStreamer(MCContext &Ctx,
+ std::unique_ptr<formatted_raw_ostream> OS,
bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
/// Takes ownership of \p TAB and \p CE.
MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *CE,
+ raw_pwrite_stream &OS, MCCodeEmitter *CE,
bool RelaxAll);
MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *CE,
+ raw_pwrite_stream &OS, MCCodeEmitter *CE,
bool RelaxAll, bool DWARFMustBeAtTheEnd,
bool LabelSections = false);
@@ -124,24 +127,24 @@ namespace llvm {
typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
const MCSubtargetInfo &STI,
MCContext &Ctx);
- typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
+ typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Triple &T,
unsigned SyntaxVariant,
const MCAsmInfo &MAI,
const MCInstrInfo &MII,
- const MCRegisterInfo &MRI,
- const MCSubtargetInfo &STI);
+ const MCRegisterInfo &MRI);
typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
const MCRegisterInfo &MRI,
MCContext &Ctx);
typedef MCStreamer *(*ELFStreamerCtorTy)(const Triple &T, MCContext &Ctx,
- MCAsmBackend &TAB, raw_ostream &OS,
+ MCAsmBackend &TAB,
+ raw_pwrite_stream &OS,
MCCodeEmitter *Emitter,
bool RelaxAll);
typedef MCStreamer *(*MachOStreamerCtorTy)(
- MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS,
+ MCContext &Ctx, MCAsmBackend &TAB, raw_pwrite_stream &OS,
MCCodeEmitter *Emitter, bool RelaxAll, bool DWARFMustBeAtTheEnd);
typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB,
- raw_ostream &OS,
+ raw_pwrite_stream &OS,
MCCodeEmitter *Emitter,
bool RelaxAll);
typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S);
@@ -409,14 +412,13 @@ namespace llvm {
return MCDisassemblerCtorFn(*this, STI, Ctx);
}
- MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
+ MCInstPrinter *createMCInstPrinter(const Triple &T, unsigned SyntaxVariant,
const MCAsmInfo &MAI,
const MCInstrInfo &MII,
- const MCRegisterInfo &MRI,
- const MCSubtargetInfo &STI) const {
+ const MCRegisterInfo &MRI) const {
if (!MCInstPrinterCtorFn)
return nullptr;
- return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
+ return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI);
}
@@ -438,7 +440,7 @@ namespace llvm {
/// \param Emitter The target independent assembler object.Takes ownership.
/// \param RelaxAll Relax all fixups?
MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx,
- MCAsmBackend &TAB, raw_ostream &OS,
+ MCAsmBackend &TAB, raw_pwrite_stream &OS,
MCCodeEmitter *Emitter,
const MCSubtargetInfo &STI,
bool RelaxAll,
@@ -471,14 +473,16 @@ namespace llvm {
return S;
}
- MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ MCStreamer *createAsmStreamer(MCContext &Ctx,
+ std::unique_ptr<formatted_raw_ostream> OS,
bool IsVerboseAsm, bool UseDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst) const {
- MCStreamer *S =
- llvm::createAsmStreamer(Ctx, OS, IsVerboseAsm, UseDwarfDirectory,
- InstPrint, CE, TAB, ShowInst);
- createAsmTargetStreamer(*S, OS, InstPrint, IsVerboseAsm);
+ formatted_raw_ostream &OSRef = *OS;
+ MCStreamer *S = llvm::createAsmStreamer(Ctx, std::move(OS), IsVerboseAsm,
+ UseDwarfDirectory, InstPrint, CE,
+ TAB, ShowInst);
+ createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm);
return S;
}
diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h
index d98e7bb..1be26c2 100644
--- a/include/llvm/Support/ToolOutputFile.h
+++ b/include/llvm/Support/ToolOutputFile.h
@@ -18,16 +18,16 @@
namespace llvm {
-/// tool_output_file - This class contains a raw_fd_ostream and adds a
-/// few extra features commonly needed for compiler-like tool output files:
+/// This class contains a raw_fd_ostream and adds a few extra features commonly
+/// needed for compiler-like tool output files:
/// - The file is automatically deleted if the process is killed.
/// - The file is automatically deleted when the tool_output_file
/// object is destroyed unless the client calls keep().
class tool_output_file {
- /// Installer - This class is declared before the raw_fd_ostream so that
- /// it is constructed before the raw_fd_ostream is constructed and
- /// destructed after the raw_fd_ostream is destructed. It installs
- /// cleanups in its constructor and uninstalls them in its destructor.
+ /// This class is declared before the raw_fd_ostream so that it is constructed
+ /// before the raw_fd_ostream is constructed and destructed after the
+ /// raw_fd_ostream is destructed. It installs cleanups in its constructor and
+ /// uninstalls them in its destructor.
class CleanupInstaller {
/// The name of the file.
std::string Filename;
@@ -39,8 +39,7 @@ class tool_output_file {
~CleanupInstaller();
} Installer;
- /// OS - The contained stream. This is intentionally declared after
- /// Installer.
+ /// The contained stream. This is intentionally declared after Installer.
raw_fd_ostream OS;
public:
@@ -51,11 +50,11 @@ public:
tool_output_file(StringRef Filename, int FD);
- /// os - Return the contained raw_fd_ostream.
+ /// Return the contained raw_fd_ostream.
raw_fd_ostream &os() { return OS; }
- /// keep - Indicate that the tool's job wrt this output file has been
- /// successful and the file should not be deleted.
+ /// Indicate that the tool's job wrt this output file has been successful and
+ /// the file should not be deleted.
void keep() { Installer.Keep = true; }
};
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 78829f8..672cf30 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -888,7 +888,7 @@ public:
void *Ctxt = nullptr,
SourceMgr::DiagHandlerTy DiagHandler = nullptr,
void *DiagHandlerCtxt = nullptr);
- ~Input();
+ ~Input() override;
// Check if there was an syntax or semantic error during parsing.
std::error_code error();
@@ -955,7 +955,7 @@ private:
};
class MapHNode : public HNode {
- virtual void anchor();
+ void anchor() override;
public:
MapHNode(Node *n) : HNode(n) { }
@@ -974,7 +974,7 @@ private:
};
class SequenceHNode : public HNode {
- virtual void anchor();
+ void anchor() override;
public:
SequenceHNode(Node *n) : HNode(n) { }
@@ -1020,7 +1020,7 @@ private:
class Output : public IO {
public:
Output(llvm::raw_ostream &, void *Ctxt=nullptr);
- virtual ~Output();
+ ~Output() override;
bool outputting() override;
bool mapTag(StringRef, bool) override;
diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h
index ee7b89f..19f9c2c 100644
--- a/include/llvm/Support/circular_raw_ostream.h
+++ b/include/llvm/Support/circular_raw_ostream.h
@@ -107,30 +107,17 @@ namespace llvm
/// management of it, etc.
///
circular_raw_ostream(raw_ostream &Stream, const char *Header,
- size_t BuffSize = 0, bool Owns = REFERENCE_ONLY)
- : raw_ostream(/*unbuffered*/true),
- TheStream(nullptr),
- OwnsStream(Owns),
- BufferSize(BuffSize),
- BufferArray(nullptr),
- Filled(false),
- Banner(Header) {
+ size_t BuffSize = 0, bool Owns = REFERENCE_ONLY)
+ : raw_ostream(/*unbuffered*/ true), TheStream(nullptr),
+ OwnsStream(Owns), BufferSize(BuffSize), BufferArray(nullptr),
+ Filled(false), Banner(Header) {
if (BufferSize != 0)
BufferArray = new char[BufferSize];
Cur = BufferArray;
setStream(Stream, Owns);
}
- explicit circular_raw_ostream()
- : raw_ostream(/*unbuffered*/true),
- TheStream(nullptr),
- OwnsStream(REFERENCE_ONLY),
- BufferArray(nullptr),
- Filled(false),
- Banner("") {
- Cur = BufferArray;
- }
- ~circular_raw_ostream() {
+ ~circular_raw_ostream() override {
flush();
flushBufferWithBanner();
releaseStream();
diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h
index 04cf3b6..a983aeb 100644
--- a/include/llvm/Support/raw_os_ostream.h
+++ b/include/llvm/Support/raw_os_ostream.h
@@ -34,7 +34,7 @@ class raw_os_ostream : public raw_ostream {
public:
raw_os_ostream(std::ostream &O) : OS(O) {}
- ~raw_os_ostream();
+ ~raw_os_ostream() override;
};
} // end llvm namespace
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 12783c7..338f0f4 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -20,21 +20,20 @@
#include <system_error>
namespace llvm {
- class format_object_base;
- class FormattedString;
- class FormattedNumber;
- template <typename T>
- class SmallVectorImpl;
-
- namespace sys {
- namespace fs {
- enum OpenFlags : unsigned;
- }
- }
-
-/// raw_ostream - This class implements an extremely fast bulk output stream
-/// that can *only* output to a stream. It does not support seeking, reopening,
-/// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
+class format_object_base;
+class FormattedString;
+class FormattedNumber;
+template <typename T> class SmallVectorImpl;
+
+namespace sys {
+namespace fs {
+enum OpenFlags : unsigned;
+}
+}
+
+/// This class implements an extremely fast bulk output stream that can *only*
+/// output to a stream. It does not support seeking, reopening, rewinding, line
+/// buffered disciplines etc. It is a simple buffer that outputs
/// a chunk at a time.
class raw_ostream {
private:
@@ -81,8 +80,8 @@ public:
SAVEDCOLOR
};
- explicit raw_ostream(bool unbuffered=false)
- : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
+ explicit raw_ostream(bool unbuffered = false)
+ : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
// Start out ready to flush.
OutBufStart = OutBufEnd = OutBufCur = nullptr;
}
@@ -96,12 +95,11 @@ public:
// Configuration Interface
//===--------------------------------------------------------------------===//
- /// SetBuffered - Set the stream to be buffered, with an automatically
- /// determined buffer size.
+ /// Set the stream to be buffered, with an automatically determined buffer
+ /// size.
void SetBuffered();
- /// SetBufferSize - Set the stream to be buffered, using the
- /// specified buffer size.
+ /// Set the stream to be buffered, using the specified buffer size.
void SetBufferSize(size_t Size) {
flush();
SetBufferAndMode(new char[Size], Size, InternalBuffer);
@@ -117,10 +115,9 @@ public:
return OutBufEnd - OutBufStart;
}
- /// SetUnbuffered - Set the stream to be unbuffered. When
- /// unbuffered, the stream will flush after every write. This routine
- /// will also flush the buffer immediately when the stream is being
- /// set to unbuffered.
+ /// Set the stream to be unbuffered. When unbuffered, the stream will flush
+ /// after every write. This routine will also flush the buffer immediately
+ /// when the stream is being set to unbuffered.
void SetUnbuffered() {
flush();
SetBufferAndMode(nullptr, 0, Unbuffered);
@@ -204,11 +201,11 @@ public:
raw_ostream &operator<<(double N);
- /// write_hex - Output \p N in hexadecimal, without any prefix or padding.
+ /// Output \p N in hexadecimal, without any prefix or padding.
raw_ostream &write_hex(unsigned long long N);
- /// write_escaped - Output \p Str, turning '\\', '\t', '\n', '"', and
- /// anything that doesn't satisfy std::isprint into an escape sequence.
+ /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't
+ /// satisfy std::isprint into an escape sequence.
raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
raw_ostream &write(unsigned char C);
@@ -263,8 +260,8 @@ public:
//===--------------------------------------------------------------------===//
private:
- /// write_impl - The is the piece of the class that is implemented
- /// by subclasses. This writes the \p Size bytes starting at
+ /// The is the piece of the class that is implemented by subclasses. This
+ /// writes the \p Size bytes starting at
/// \p Ptr to the underlying stream.
///
/// This function is guaranteed to only be called at a point at which it is
@@ -281,51 +278,58 @@ private:
// An out of line virtual method to provide a home for the class vtable.
virtual void handle();
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
+ /// Return the current position within the stream, not counting the bytes
+ /// currently in the buffer.
virtual uint64_t current_pos() const = 0;
protected:
- /// SetBuffer - Use the provided buffer as the raw_ostream buffer. This is
- /// intended for use only by subclasses which can arrange for the output to go
- /// directly into the desired output buffer, instead of being copied on each
- /// flush.
+ /// Use the provided buffer as the raw_ostream buffer. This is intended for
+ /// use only by subclasses which can arrange for the output to go directly
+ /// into the desired output buffer, instead of being copied on each flush.
void SetBuffer(char *BufferStart, size_t Size) {
SetBufferAndMode(BufferStart, Size, ExternalBuffer);
}
- /// preferred_buffer_size - Return an efficient buffer size for the
- /// underlying output mechanism.
+ /// Return an efficient buffer size for the underlying output mechanism.
virtual size_t preferred_buffer_size() const;
- /// getBufferStart - Return the beginning of the current stream buffer, or 0
- /// if the stream is unbuffered.
+ /// Return the beginning of the current stream buffer, or 0 if the stream is
+ /// unbuffered.
const char *getBufferStart() const { return OutBufStart; }
//===--------------------------------------------------------------------===//
// Private Interface
//===--------------------------------------------------------------------===//
private:
- /// SetBufferAndMode - Install the given buffer and mode.
+ /// Install the given buffer and mode.
void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode);
- /// flush_nonempty - Flush the current buffer, which is known to be
- /// non-empty. This outputs the currently buffered data and resets
- /// the buffer to empty.
+ /// Flush the current buffer, which is known to be non-empty. This outputs the
+ /// currently buffered data and resets the buffer to empty.
void flush_nonempty();
- /// copy_to_buffer - Copy data into the buffer. Size must not be
- /// greater than the number of unused bytes in the buffer.
+ /// Copy data into the buffer. Size must not be greater than the number of
+ /// unused bytes in the buffer.
void copy_to_buffer(const char *Ptr, size_t Size);
};
+/// An abstract base class for streams implementations that also support a
+/// pwrite operation. This is usefull for code that can mostly stream out data,
+/// but needs to patch in a header that needs to know the output size.
+class raw_pwrite_stream : public raw_ostream {
+public:
+ explicit raw_pwrite_stream(bool Unbuffered = false)
+ : raw_ostream(Unbuffered) {}
+ virtual void pwrite(const char *Ptr, size_t Size, uint64_t Offset) = 0;
+};
+
//===----------------------------------------------------------------------===//
// File Output Streams
//===----------------------------------------------------------------------===//
-/// raw_fd_ostream - A raw_ostream that writes to a file descriptor.
+/// A raw_ostream that writes to a file descriptor.
///
-class raw_fd_ostream : public raw_ostream {
+class raw_fd_ostream : public raw_pwrite_stream {
int FD;
bool ShouldClose;
@@ -339,18 +343,19 @@ class raw_fd_ostream : public raw_ostream {
uint64_t pos;
- /// write_impl - See raw_ostream::write_impl.
+ bool SupportsSeeking;
+
+ /// See raw_ostream::write_impl.
void write_impl(const char *Ptr, size_t Size) override;
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
+ /// Return the current position within the stream, not counting the bytes
+ /// currently in the buffer.
uint64_t current_pos() const override { return pos; }
- /// preferred_buffer_size - Determine an efficient buffer size.
+ /// Determine an efficient buffer size.
size_t preferred_buffer_size() const override;
- /// error_detected - Set the flag indicating that an output error has
- /// been encountered.
+ /// Set the flag indicating that an output error has been encountered.
void error_detected() { Error = true; }
public:
@@ -367,22 +372,26 @@ public:
raw_fd_ostream(StringRef Filename, std::error_code &EC,
sys::fs::OpenFlags Flags);
- /// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If
- /// ShouldClose is true, this closes the file when the stream is destroyed.
+ /// FD is the file descriptor that this writes to. If ShouldClose is true,
+ /// this closes the file when the stream is destroyed.
raw_fd_ostream(int fd, bool shouldClose, bool unbuffered=false);
- ~raw_fd_ostream();
+ ~raw_fd_ostream() override;
- /// close - Manually flush the stream and close the file.
- /// Note that this does not call fsync.
+ /// Manually flush the stream and close the file. Note that this does not call
+ /// fsync.
void close();
- /// seek - Flushes the stream and repositions the underlying file descriptor
- /// position to the offset specified from the beginning of the file.
+ bool supportsSeeking() { return SupportsSeeking; }
+
+ /// Flushes the stream and repositions the underlying file descriptor position
+ /// to the offset specified from the beginning of the file.
uint64_t seek(uint64_t off);
- /// SetUseAtomicWrite - Set the stream to attempt to use atomic writes for
- /// individual output routines where possible.
+ void pwrite(const char *Ptr, size_t Size, uint64_t Offset) override;
+
+ /// Set the stream to attempt to use atomic writes for individual output
+ /// routines where possible.
///
/// Note that because raw_ostream's are typically buffered, this flag is only
/// sensible when used on unbuffered streams which will flush their output
@@ -401,18 +410,18 @@ public:
bool has_colors() const override;
- /// has_error - Return the value of the flag in this raw_fd_ostream indicating
- /// whether an output error has been encountered.
+ /// Return the value of the flag in this raw_fd_ostream indicating whether an
+ /// output error has been encountered.
/// This doesn't implicitly flush any pending output. Also, it doesn't
/// guarantee to detect all errors unless the stream has been closed.
bool has_error() const {
return Error;
}
- /// clear_error - Set the flag read by has_error() to false. If the error
- /// flag is set at the time when this raw_ostream's destructor is called,
- /// report_fatal_error is called to report the error. Use clear_error()
- /// after handling the error to avoid this behavior.
+ /// Set the flag read by has_error() to false. If the error flag is set at the
+ /// time when this raw_ostream's destructor is called, report_fatal_error is
+ /// called to report the error. Use clear_error() after handling the error to
+ /// avoid this behavior.
///
/// "Errors should never pass silently.
/// Unless explicitly silenced."
@@ -423,87 +432,105 @@ public:
}
};
-/// outs() - This returns a reference to a raw_ostream for standard output.
-/// Use it like: outs() << "foo" << "bar";
+/// This returns a reference to a raw_ostream for standard output. Use it like:
+/// outs() << "foo" << "bar";
raw_ostream &outs();
-/// errs() - This returns a reference to a raw_ostream for standard error.
-/// Use it like: errs() << "foo" << "bar";
+/// This returns a reference to a raw_ostream for standard error. Use it like:
+/// errs() << "foo" << "bar";
raw_ostream &errs();
-/// nulls() - This returns a reference to a raw_ostream which simply discards
-/// output.
+/// This returns a reference to a raw_ostream which simply discards output.
raw_ostream &nulls();
//===----------------------------------------------------------------------===//
// Output Stream Adaptors
//===----------------------------------------------------------------------===//
-/// raw_string_ostream - A raw_ostream that writes to an std::string. This is a
-/// simple adaptor class. This class does not encounter output errors.
+/// A raw_ostream that writes to an std::string. This is a simple adaptor
+/// class. This class does not encounter output errors.
class raw_string_ostream : public raw_ostream {
std::string &OS;
- /// write_impl - See raw_ostream::write_impl.
+ /// See raw_ostream::write_impl.
void write_impl(const char *Ptr, size_t Size) override;
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
+ /// Return the current position within the stream, not counting the bytes
+ /// currently in the buffer.
uint64_t current_pos() const override { return OS.size(); }
public:
explicit raw_string_ostream(std::string &O) : OS(O) {}
- ~raw_string_ostream();
+ ~raw_string_ostream() override;
- /// str - Flushes the stream contents to the target string and returns
- /// the string's reference.
+ /// Flushes the stream contents to the target string and returns the string's
+ /// reference.
std::string& str() {
flush();
return OS;
}
};
-/// raw_svector_ostream - A raw_ostream that writes to an SmallVector or
-/// SmallString. This is a simple adaptor class. This class does not
-/// encounter output errors.
-class raw_svector_ostream : public raw_ostream {
+/// A raw_ostream that writes to an SmallVector or SmallString. This is a
+/// simple adaptor class. This class does not encounter output errors.
+class raw_svector_ostream : public raw_pwrite_stream {
SmallVectorImpl<char> &OS;
- /// write_impl - See raw_ostream::write_impl.
+ /// See raw_ostream::write_impl.
void write_impl(const char *Ptr, size_t Size) override;
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
+ /// Return the current position within the stream, not counting the bytes
+ /// currently in the buffer.
uint64_t current_pos() const override;
+
+protected:
+ // Like the regular constructor, but doesn't call init.
+ explicit raw_svector_ostream(SmallVectorImpl<char> &O, unsigned);
+ void init();
+
public:
/// Construct a new raw_svector_ostream.
///
/// \param O The vector to write to; this should generally have at least 128
/// bytes free to avoid any extraneous memory overhead.
explicit raw_svector_ostream(SmallVectorImpl<char> &O);
- ~raw_svector_ostream();
+ ~raw_svector_ostream() override;
- /// resync - This is called when the SmallVector we're appending to is changed
- /// outside of the raw_svector_ostream's control. It is only safe to do this
- /// if the raw_svector_ostream has previously been flushed.
+ void pwrite(const char *Ptr, size_t Size, uint64_t Offset) override;
+
+ /// This is called when the SmallVector we're appending to is changed outside
+ /// of the raw_svector_ostream's control. It is only safe to do this if the
+ /// raw_svector_ostream has previously been flushed.
void resync();
- /// str - Flushes the stream contents to the target vector and return a
- /// StringRef for the vector contents.
+ /// Flushes the stream contents to the target vector and return a StringRef
+ /// for the vector contents.
StringRef str();
};
-/// raw_null_ostream - A raw_ostream that discards all output.
-class raw_null_ostream : public raw_ostream {
- /// write_impl - See raw_ostream::write_impl.
+/// A raw_ostream that discards all output.
+class raw_null_ostream : public raw_pwrite_stream {
+ /// See raw_ostream::write_impl.
void write_impl(const char *Ptr, size_t size) override;
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
+ /// Return the current position within the stream, not counting the bytes
+ /// currently in the buffer.
uint64_t current_pos() const override;
public:
explicit raw_null_ostream() {}
- ~raw_null_ostream();
+ ~raw_null_ostream() override;
+ void pwrite(const char *Ptr, size_t Size, uint64_t Offset) override;
+};
+
+class buffer_ostream : public raw_svector_ostream {
+ raw_ostream &OS;
+ SmallVector<char, 0> Buffer;
+
+public:
+ buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer, 0), OS(OS) {
+ init();
+ }
+ ~buffer_ostream() { OS << str(); }
};
} // end llvm namespace
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index 5233493..e746e7d 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -1442,8 +1442,6 @@ public:
TheInit(O.TheInit), IsAnonymous(O.IsAnonymous),
ResolveFirst(O.ResolveFirst) { }
- ~Record() {}
-
static unsigned getNewUID() { return LastID++; }
unsigned getID() const { return ID; }
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 6c970d0..1ff8db8 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -207,6 +207,12 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// The function should return 0 to select the default order defined by
// MemberList, 1 to select the first AltOrders entry and so on.
code AltOrderSelect = [{}];
+
+ // Specify allocation priority for register allocators using a greedy
+ // heuristic. Classes with higher priority values are assigned first. This is
+ // useful as it is sometimes beneficial to assign registers to highly
+ // constrained classes first. The value has to be in the range [0,63].
+ int AllocationPriority = 0;
}
// The memberList in a RegisterClass is a dag of set operations. TableGen
@@ -1015,6 +1021,11 @@ class AsmWriter {
// name.
string AsmWriterClassName = "InstPrinter";
+ // PassSubtarget - Determines whether MCSubtargetInfo should be passed to
+ // the various print methods.
+ // FIXME: Remove after all ports are updated.
+ int PassSubtarget = 0;
+
// Variant - AsmWriters can be of multiple different variants. Variants are
// used to support targets that need to emit assembly code in ways that are
// mostly the same for different targets, but have minor differences in
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 87aba9f..2a1ce04 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -48,6 +48,7 @@ class TargetSubtargetInfo;
class TargetTransformInfo;
class formatted_raw_ostream;
class raw_ostream;
+class raw_pwrite_stream;
class TargetLoweringObjectFile;
// The old pass manager infrastructure is hidden in a legacy namespace now.
@@ -58,9 +59,9 @@ using legacy::PassManagerBase;
//===----------------------------------------------------------------------===//
///
-/// TargetMachine - Primary interface to the complete machine description for
-/// the target machine. All target-specific information should be accessible
-/// through this interface.
+/// Primary interface to the complete machine description for the target
+/// machine. All target-specific information should be accessible through this
+/// interface.
///
class TargetMachine {
TargetMachine(const TargetMachine &) = delete;
@@ -70,25 +71,25 @@ protected: // Can only create subclasses.
StringRef TargetTriple, StringRef CPU, StringRef FS,
const TargetOptions &Options);
- /// TheTarget - The Target that this machine was created for.
+ /// The Target that this machine was created for.
const Target &TheTarget;
- /// DataLayout - For ABI type size and alignment.
+ /// For ABI type size and alignment.
const DataLayout DL;
- /// TargetTriple, TargetCPU, TargetFS - Triple string, CPU name, and target
- /// feature strings the TargetMachine instance is created with.
+ /// Triple string, CPU name, and target feature strings the TargetMachine
+ /// instance is created with.
std::string TargetTriple;
std::string TargetCPU;
std::string TargetFS;
- /// CodeGenInfo - Low level target information such as relocation model.
- /// Non-const to allow resetting optimization level per-function.
+ /// Low level target information such as relocation model. Non-const to
+ /// allow resetting optimization level per-function.
MCCodeGenInfo *CodeGenInfo;
- /// AsmInfo - Contains target specific asm information.
- ///
+ /// Contains target specific asm information.
const MCAsmInfo *AsmInfo;
+
const MCRegisterInfo *MRI;
const MCInstrInfo *MII;
const MCSubtargetInfo *STI;
@@ -106,8 +107,8 @@ public:
StringRef getTargetCPU() const { return TargetCPU; }
StringRef getTargetFeatureString() const { return TargetFS; }
- /// getSubtargetImpl - virtual method implemented by subclasses that returns
- /// a reference to that target's TargetSubtargetInfo-derived member variable.
+ /// Virtual method implemented by subclasses that returns a reference to that
+ /// target's TargetSubtargetInfo-derived member variable.
virtual const TargetSubtargetInfo *getSubtargetImpl(const Function &) const {
return nullptr;
}
@@ -115,15 +116,15 @@ public:
return nullptr;
}
- /// getSubtarget - This method returns a pointer to the specified type of
+ /// This method returns a pointer to the specified type of
/// TargetSubtargetInfo. In debug builds, it verifies that the object being
/// returned is of the correct type.
template <typename STC> const STC &getSubtarget(const Function &F) const {
return *static_cast<const STC*>(getSubtargetImpl(F));
}
- /// getDataLayout - This method returns a pointer to the DataLayout for
- /// the target. It should be unchanging for every subtarget.
+ /// This method returns a pointer to the DataLayout for the target. It should
+ /// be unchanging for every subtarget.
const DataLayout *getDataLayout() const { return &DL; }
/// \brief Reset the target options based on the function's attributes.
@@ -131,16 +132,14 @@ public:
// from TargetMachine.
void resetTargetOptions(const Function &F) const;
- /// getMCAsmInfo - Return target specific asm information.
- ///
+ /// Return target specific asm information.
const MCAsmInfo *getMCAsmInfo() const { return AsmInfo; }
+
const MCRegisterInfo *getMCRegisterInfo() const { return MRI; }
const MCInstrInfo *getMCInstrInfo() const { return MII; }
const MCSubtargetInfo *getMCSubtargetInfo() const { return STI; }
- /// getIntrinsicInfo - If intrinsic information is available, return it. If
- /// not, return null.
- ///
+ /// If intrinsic information is available, return it. If not, return null.
virtual const TargetIntrinsicInfo *getIntrinsicInfo() const {
return nullptr;
}
@@ -148,20 +147,18 @@ public:
bool requiresStructuredCFG() const { return RequireStructuredCFG; }
void setRequiresStructuredCFG(bool Value) { RequireStructuredCFG = Value; }
- /// getRelocationModel - Returns the code generation relocation model. The
- /// choices are static, PIC, and dynamic-no-pic, and target default.
+ /// Returns the code generation relocation model. The choices are static, PIC,
+ /// and dynamic-no-pic, and target default.
Reloc::Model getRelocationModel() const;
- /// getCodeModel - Returns the code model. The choices are small, kernel,
- /// medium, large, and target default.
+ /// Returns the code model. The choices are small, kernel, medium, large, and
+ /// target default.
CodeModel::Model getCodeModel() const;
- /// getTLSModel - Returns the TLS model which should be used for the given
- /// global variable.
+ /// Returns the TLS model which should be used for the given global variable.
TLSModel::Model getTLSModel(const GlobalValue *GV) const;
- /// getOptLevel - Returns the optimization level: None, Less,
- /// Default, or Aggressive.
+ /// Returns the optimization level: None, Less, Default, or Aggressive.
CodeGenOpt::Level getOptLevel() const;
/// \brief Overrides the optimization level.
@@ -198,21 +195,20 @@ public:
/// uses this to answer queries about the IR.
virtual TargetIRAnalysis getTargetIRAnalysis();
- /// CodeGenFileType - These enums are meant to be passed into
- /// addPassesToEmitFile to indicate what type of file to emit, and returned by
- /// it to indicate what type of file could actually be made.
+ /// These enums are meant to be passed into addPassesToEmitFile to indicate
+ /// what type of file to emit, and returned by it to indicate what type of
+ /// file could actually be made.
enum CodeGenFileType {
CGFT_AssemblyFile,
CGFT_ObjectFile,
CGFT_Null // Do not emit any output.
};
- /// addPassesToEmitFile - Add passes to the specified pass manager to get the
- /// specified file emitted. Typically this will involve several steps of code
- /// generation. This method should return true if emission of this file type
- /// is not supported, or false on success.
- virtual bool addPassesToEmitFile(PassManagerBase &,
- formatted_raw_ostream &,
+ /// Add passes to the specified pass manager to get the specified file
+ /// emitted. Typically this will involve several steps of code generation.
+ /// This method should return true if emission of this file type is not
+ /// supported, or false on success.
+ virtual bool addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &,
CodeGenFileType,
bool /*DisableVerify*/ = true,
AnalysisID /*StartAfter*/ = nullptr,
@@ -220,14 +216,13 @@ public:
return true;
}
- /// addPassesToEmitMC - Add passes to the specified pass manager to get
- /// machine code emitted with the MCJIT. This method returns true if machine
- /// code is not supported. It fills the MCContext Ctx pointer which can be
- /// used to build custom MCStreamer.
+ /// Add passes to the specified pass manager to get machine code emitted with
+ /// the MCJIT. This method returns true if machine code is not supported. It
+ /// fills the MCContext Ctx pointer which can be used to build custom
+ /// MCStreamer.
///
- virtual bool addPassesToEmitMC(PassManagerBase &,
- MCContext *&,
- raw_ostream &,
+ virtual bool addPassesToEmitMC(PassManagerBase &, MCContext *&,
+ raw_pwrite_stream &,
bool /*DisableVerify*/ = true) {
return true;
}
@@ -237,8 +232,8 @@ public:
MCSymbol *getSymbol(const GlobalValue *GV, Mangler &Mang) const;
};
-/// LLVMTargetMachine - This class describes a target machine that is
-/// implemented with the LLVM target-independent code generator.
+/// This class describes a target machine that is implemented with the LLVM
+/// target-independent code generator.
///
class LLVMTargetMachine : public TargetMachine {
protected: // Can only create subclasses.
@@ -255,25 +250,24 @@ public:
/// generator to answer queries about the IR.
TargetIRAnalysis getTargetIRAnalysis() override;
- /// createPassConfig - Create a pass configuration object to be used by
- /// addPassToEmitX methods for generating a pipeline of CodeGen passes.
+ /// Create a pass configuration object to be used by addPassToEmitX methods
+ /// for generating a pipeline of CodeGen passes.
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
- /// addPassesToEmitFile - Add passes to the specified pass manager to get the
- /// specified file emitted. Typically this will involve several steps of code
- /// generation.
- bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out,
+ /// Add passes to the specified pass manager to get the specified file
+ /// emitted. Typically this will involve several steps of code generation.
+ bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,
CodeGenFileType FileType, bool DisableVerify = true,
AnalysisID StartAfter = nullptr,
AnalysisID StopAfter = nullptr) override;
- /// addPassesToEmitMC - Add passes to the specified pass manager to get
- /// machine code emitted with the MCJIT. This method returns true if machine
- /// code is not supported. It fills the MCContext Ctx pointer which can be
- /// used to build custom MCStreamer.
- ///
+ /// Add passes to the specified pass manager to get machine code emitted with
+ /// the MCJIT. This method returns true if machine code is not supported. It
+ /// fills the MCContext Ctx pointer which can be used to build custom
+ /// MCStreamer.
bool addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
- raw_ostream &OS, bool DisableVerify = true) override;
+ raw_pwrite_stream &OS,
+ bool DisableVerify = true) override;
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index f447fd6..d41ca99 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -212,9 +212,9 @@ namespace llvm {
/// FloatABIType - This setting is set by -float-abi=xxx option is specfied
/// on the command line. This setting may either be Default, Soft, or Hard.
/// Default selects the target's default behavior. Soft selects the ABI for
- /// UseSoftFloat, but does not indicate that FP hardware may not be used.
- /// Such a combination is unfortunately popular (e.g. arm-apple-darwin).
- /// Hard presumes that the normal FP ABI is used.
+ /// software floating point, but does not indicate that FP hardware may not
+ /// be used. Such a combination is unfortunately popular (e.g.
+ /// arm-apple-darwin). Hard presumes that the normal FP ABI is used.
FloatABI::ABIType FloatABIType;
/// AllowFPOpFusion - This flag is set by the -fuse-fp-ops=xxx option.
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 4184052..121b8a2 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -46,6 +46,9 @@ public:
const uint32_t *SubClassMask;
const uint16_t *SuperRegIndices;
const unsigned LaneMask;
+ /// Classes with a higher priority value are assigned first by register
+ /// allocators using a greedy heuristic. The value is in the range [0,63].
+ const uint8_t AllocationPriority;
/// Whether the class supports two (or more) disjunct subregister indices.
const bool HasDisjunctSubRegs;
const sc_iterator SuperClasses;
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index bb5409b6..0f42790 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -42,15 +42,17 @@ template <typename T> class SmallVectorImpl;
/// be exposed through a TargetSubtargetInfo-derived class.
///
class TargetSubtargetInfo : public MCSubtargetInfo {
- TargetSubtargetInfo(const TargetSubtargetInfo&) = delete;
- void operator=(const TargetSubtargetInfo&) = delete;
+ TargetSubtargetInfo(const TargetSubtargetInfo &) = delete;
+ void operator=(const TargetSubtargetInfo &) = delete;
+
protected: // Can only create subclasses...
TargetSubtargetInfo();
+
public:
// AntiDepBreakMode - Type of anti-dependence breaking that should
// be performed before post-RA scheduling.
typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode;
- typedef SmallVectorImpl<const TargetRegisterClass*> RegClassVector;
+ typedef SmallVectorImpl<const TargetRegisterClass *> RegClassVector;
virtual ~TargetSubtargetInfo();
@@ -89,8 +91,9 @@ public:
/// MCSchedClassDesc with the isVariant property. This may return the ID of
/// another variant SchedClass, but repeated invocation must quickly terminate
/// in a nonvariant SchedClass.
- virtual unsigned resolveSchedClass(unsigned SchedClass, const MachineInstr *MI,
- const TargetSchedModel* SchedModel) const {
+ virtual unsigned resolveSchedClass(unsigned SchedClass,
+ const MachineInstr *MI,
+ const TargetSchedModel *SchedModel) const {
return 0;
}
@@ -128,20 +131,16 @@ public:
/// scheduling heuristics (no custom MachineSchedStrategy) to make
/// changes to the generic scheduling policy.
virtual void overrideSchedPolicy(MachineSchedPolicy &Policy,
- MachineInstr *begin,
- MachineInstr *end,
+ MachineInstr *begin, MachineInstr *end,
unsigned NumRegionInstrs) const {}
// \brief Perform target specific adjustments to the latency of a schedule
// dependency.
- virtual void adjustSchedDependency(SUnit *def, SUnit *use,
- SDep& dep) const { }
+ virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep &dep) const {}
// For use with PostRAScheduling: get the anti-dependence breaking that should
// be performed before post-RA scheduling.
- virtual AntiDepBreakMode getAntiDepBreakMode() const {
- return ANTIDEP_NONE;
- }
+ virtual AntiDepBreakMode getAntiDepBreakMode() const { return ANTIDEP_NONE; }
// For use with PostRAScheduling: in CriticalPathRCs, return any register
// classes that should only be considered for anti-dependence breaking if they
@@ -177,9 +176,7 @@ public:
}
/// Enable tracking of subregister liveness in register allocator.
- virtual bool enableSubRegLiveness() const {
- return false;
- }
+ virtual bool enableSubRegLiveness() const { return false; }
};
} // End llvm namespace
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 2d754d0..925ebda 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -427,6 +427,11 @@ createSeparateConstOffsetFromGEPPass(const TargetMachine *TM = nullptr,
//
BasicBlockPass *createLoadCombinePass();
+//===----------------------------------------------------------------------===//
+//
+// StraightLineStrengthReduce - This pass strength-reduces some certain
+// instruction patterns in straight-line code.
+//
FunctionPass *createStraightLineStrengthReducePass();
//===----------------------------------------------------------------------===//
@@ -446,6 +451,18 @@ ModulePass *createPlaceSafepointsPass();
//
FunctionPass *createRewriteStatepointsForGCPass();
+//===----------------------------------------------------------------------===//
+//
+// Float2Int - Demote floats to ints where possible.
+//
+FunctionPass *createFloat2IntPass();
+
+//===----------------------------------------------------------------------===//
+//
+// NaryReassociate - Simplify n-ary operations by reassociation.
+//
+FunctionPass *createNaryReassociatePass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
index 2eb2555..e8f3172 100644
--- a/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -122,6 +122,10 @@ bool promoteLoopAccessesToScalars(AliasSet &, SmallVectorImpl<BasicBlock*> &,
/// Updates safety information in LICMSafetyInfo argument.
void computeLICMSafetyInfo(LICMSafetyInfo *, Loop *);
+/// \brief Checks if the given PHINode in a loop header is an induction
+/// variable. Returns true if this is an induction PHI along with the step
+/// value.
+bool isInductionPHI(PHINode *, ScalarEvolution *, ConstantInt *&);
}
#endif
diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h
index 16904f1..907563e 100644
--- a/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -20,6 +20,7 @@ class Module;
class Function;
class GlobalValue;
class GlobalVariable;
+class Constant;
template <class PtrType> class SmallPtrSetImpl;
/// Append F to the list of global ctors of module M with the given Priority.
@@ -36,6 +37,12 @@ void appendToGlobalDtors(Module &M, Function *F, int Priority);
GlobalVariable *collectUsedGlobalVariables(Module &M,
SmallPtrSetImpl<GlobalValue *> &Set,
bool CompilerUsed);
+
+// Validate the result of Module::getOrInsertFunction called for an interface
+// function of given sanitizer. If the instrumented module defines a function
+// with the same name, their prototypes must match, otherwise
+// getOrInsertFunction returns a bitcast.
+Function *checkSanitizerInterfaceFunction(Constant *FuncOrBitcast);
} // End llvm namespace
#endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
diff --git a/include/llvm/Transforms/Utils/SymbolRewriter.h b/include/llvm/Transforms/Utils/SymbolRewriter.h
index 48dea04..5ccee98 100644
--- a/include/llvm/Transforms/Utils/SymbolRewriter.h
+++ b/include/llvm/Transforms/Utils/SymbolRewriter.h
@@ -90,9 +90,6 @@ typedef iplist<RewriteDescriptor> RewriteDescriptorList;
class RewriteMapParser {
public:
- RewriteMapParser() {}
- ~RewriteMapParser() {}
-
bool parse(const std::string &MapFile, RewriteDescriptorList *Descriptors);
private:
diff --git a/include/llvm/Transforms/Utils/UnrollLoop.h b/include/llvm/Transforms/Utils/UnrollLoop.h
index 04d9ee1..7f2cf8d 100644
--- a/include/llvm/Transforms/Utils/UnrollLoop.h
+++ b/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -28,11 +28,13 @@ class MDNode;
class Pass;
bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool AllowRuntime,
- unsigned TripMultiple, LoopInfo *LI, Pass *PP,
- LPPassManager *LPM, AssumptionCache *AC);
+ bool AllowExpensiveTripCount, unsigned TripMultiple,
+ LoopInfo *LI, Pass *PP, LPPassManager *LPM,
+ AssumptionCache *AC);
-bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
- LPPassManager* LPM);
+bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count,
+ bool AllowExpensiveTripCount, LoopInfo *LI,
+ LPPassManager *LPM);
MDNode *GetUnrollMetadata(MDNode *LoopID, StringRef Name);
}