aboutsummaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/APInt.h5
-rw-r--r--include/llvm/ADT/Triple.h12
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h92
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfoImpl.h6
-rw-r--r--include/llvm/Analysis/BranchProbabilityInfo.h3
-rw-r--r--include/llvm/Analysis/CallGraph.h2
-rw-r--r--include/llvm/Analysis/DependenceAnalysis.h9
-rw-r--r--include/llvm/Analysis/LoopAccessAnalysis.h18
-rw-r--r--include/llvm/Analysis/LoopInfo.h26
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h2
-rw-r--r--include/llvm/Analysis/MemoryLocation.h137
-rw-r--r--include/llvm/Analysis/PHITransAddr.h8
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h73
-rw-r--r--include/llvm/Analysis/TargetTransformInfoImpl.h16
-rw-r--r--include/llvm/Bitcode/BitstreamReader.h2
-rw-r--r--include/llvm/Bitcode/BitstreamWriter.h4
-rw-r--r--include/llvm/CodeGen/BasicTTIImpl.h76
-rw-r--r--include/llvm/CodeGen/CommandFlags.h8
-rw-r--r--include/llvm/CodeGen/DIE.h612
-rw-r--r--include/llvm/CodeGen/DIEValue.def47
-rw-r--r--include/llvm/CodeGen/GCMetadata.h2
-rw-r--r--include/llvm/CodeGen/LiveRangeEdit.h4
-rw-r--r--include/llvm/CodeGen/MIRParser/MIRParser.h52
-rw-r--r--include/llvm/CodeGen/MIRYamlMapping.h40
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h14
-rw-r--r--include/llvm/CodeGen/MachineInstr.h20
-rw-r--r--include/llvm/CodeGen/MachineLoopInfo.h2
-rw-r--r--include/llvm/CodeGen/Passes.h15
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h2
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h4
-rw-r--r--include/llvm/CodeGen/WinEHFuncInfo.h7
-rw-r--r--include/llvm/Config/config.h.in3
-rw-r--r--include/llvm/DebugInfo/DIContext.h5
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugLine.h27
-rw-r--r--include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h3
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h7
-rw-r--r--include/llvm/IR/InlineAsm.h7
-rw-r--r--include/llvm/IR/Instructions.h16
-rw-r--r--include/llvm/IR/Intrinsics.td3
-rw-r--r--include/llvm/IR/IntrinsicsX86.td34
-rw-r--r--include/llvm/IR/MDBuilder.h2
-rw-r--r--include/llvm/IR/Value.h16
-rw-r--r--include/llvm/InitializePasses.h1
-rw-r--r--include/llvm/LTO/LTOCodeGenerator.h14
-rw-r--r--include/llvm/MC/MCAsmBackend.h6
-rw-r--r--include/llvm/MC/MCAsmInfo.h9
-rw-r--r--include/llvm/MC/MCAsmLayout.h1
-rw-r--r--include/llvm/MC/MCAssembler.h72
-rw-r--r--include/llvm/MC/MCContext.h16
-rw-r--r--include/llvm/MC/MCELF.h35
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h8
-rw-r--r--include/llvm/MC/MCELFStreamer.h7
-rw-r--r--include/llvm/MC/MCELFSymbolFlags.h56
-rw-r--r--include/llvm/MC/MCExpr.h135
-rw-r--r--include/llvm/MC/MCInst.h27
-rw-r--r--include/llvm/MC/MCInstPrinter.h26
-rw-r--r--include/llvm/MC/MCInstrDesc.h16
-rw-r--r--include/llvm/MC/MCLabel.h70
-rw-r--r--include/llvm/MC/MCLinkerOptimizationHint.h14
-rw-r--r--include/llvm/MC/MCMachOSymbolFlags.h46
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h79
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h98
-rw-r--r--include/llvm/MC/MCObjectStreamer.h13
-rw-r--r--include/llvm/MC/MCObjectWriter.h83
-rw-r--r--include/llvm/MC/MCSection.h7
-rw-r--r--include/llvm/MC/MCSectionELF.h13
-rw-r--r--include/llvm/MC/MCStreamer.h20
-rw-r--r--include/llvm/MC/MCSubtargetInfo.h8
-rw-r--r--include/llvm/MC/MCSymbol.h301
-rw-r--r--include/llvm/MC/MCSymbolCOFF.h64
-rw-r--r--include/llvm/MC/MCSymbolELF.h57
-rw-r--r--include/llvm/MC/MCSymbolMachO.h123
-rw-r--r--include/llvm/MC/MCWinCOFFStreamer.h2
-rw-r--r--include/llvm/MC/SubtargetFeature.h4
-rw-r--r--include/llvm/Object/ArchiveWriter.h51
-rw-r--r--include/llvm/Object/COFF.h10
-rw-r--r--include/llvm/Object/ELF.h103
-rw-r--r--include/llvm/Object/ELFObjectFile.h148
-rw-r--r--include/llvm/Object/ELFTypes.h206
-rw-r--r--include/llvm/Object/Error.h7
-rw-r--r--include/llvm/Object/MachO.h38
-rw-r--r--include/llvm/Object/ObjectFile.h33
-rw-r--r--include/llvm/Object/RelocVisitor.h31
-rw-r--r--include/llvm/Support/COFF.h10
-rw-r--r--include/llvm/Support/CommandLine.h77
-rw-r--r--include/llvm/Support/Compiler.h13
-rw-r--r--include/llvm/Support/ELFRelocs/Hexagon.def8
-rw-r--r--include/llvm/Support/MathExtras.h4
-rw-r--r--include/llvm/Support/TargetParser.h51
-rw-r--r--include/llvm/Support/TargetRegistry.h11
-rw-r--r--include/llvm/Support/YAMLTraits.h6
-rw-r--r--include/llvm/TableGen/Record.h310
-rw-r--r--include/llvm/TableGen/SetTheory.h4
-rw-r--r--include/llvm/Target/Target.td3
-rw-r--r--include/llvm/Target/TargetInstrInfo.h18
-rw-r--r--include/llvm/Target/TargetLowering.h17
-rw-r--r--include/llvm/Target/TargetOptions.h8
-rw-r--r--include/llvm/Target/TargetRecip.h73
-rw-r--r--include/llvm/Transforms/Scalar.h16
99 files changed, 2381 insertions, 1749 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index 36d8159d21ba..e5d143d8ebe1 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -351,8 +351,7 @@ public:
/// This checks to see if the value of this APInt is the maximum signed
/// value for the APInt's bit width.
bool isMaxSignedValue() const {
- return BitWidth == 1 ? VAL == 0
- : !isNegative() && countPopulation() == BitWidth - 1;
+ return !isNegative() && countPopulation() == BitWidth - 1;
}
/// \brief Determine if this is the smallest unsigned value.
@@ -366,7 +365,7 @@ public:
/// This checks to see if the value of this APInt is the minimum signed
/// value for the APInt's bit width.
bool isMinSignedValue() const {
- return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2();
+ return isNegative() && isPowerOf2();
}
/// \brief Check if this APInt has an N-bits unsigned integer value.
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 2416ce342c9b..1362fe37c426 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -50,7 +50,8 @@ public:
armeb, // ARM (big endian): armeb
aarch64, // AArch64 (little endian): aarch64
aarch64_be, // AArch64 (big endian): aarch64_be
- bpf, // eBPF or extended BPF or 64-bit BPF (little endian)
+ bpfel, // eBPF or extended BPF or 64-bit BPF (little endian)
+ bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian)
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel
@@ -255,6 +256,15 @@ public:
/// getEnvironment - Get the parsed environment type of this triple.
EnvironmentType getEnvironment() const { return Environment; }
+ /// \brief Parse the version number from the OS name component of the
+ /// triple, if present.
+ ///
+ /// For example, "fooos1.2.3" would return (1, 2, 3).
+ ///
+ /// If an entry is not defined, it will be returned as 0.
+ void getEnvironmentVersion(unsigned &Major, unsigned &Minor,
+ unsigned &Micro) const;
+
/// getFormat - Get the object format for this triple.
ObjectFormatType getObjectFormat() const { return ObjectFormat; }
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index ac9d21c590a4..de18e585f11d 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -40,6 +40,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/Analysis/MemoryLocation.h"
namespace llvm {
@@ -82,7 +83,7 @@ public:
/// UnknownSize - This is a special value which can be used with the
/// size arguments in alias queries to indicate that the caller does not
/// know the sizes of the potential memory references.
- static uint64_t const UnknownSize = ~UINT64_C(0);
+ static uint64_t const UnknownSize = MemoryLocation::UnknownSize;
/// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
/// object, or null if no TargetLibraryInfo object is available.
@@ -98,70 +99,9 @@ public:
/// Alias Queries...
///
- /// Location - A description of a memory location.
- struct Location {
- /// Ptr - The address of the start of the location.
- const Value *Ptr;
- /// Size - The maximum size of the location, in address-units, or
- /// UnknownSize if the size is not known. Note that an unknown size does
- /// not mean the pointer aliases the entire virtual address space, because
- /// there are restrictions on stepping out of one object and into another.
- /// See http://llvm.org/docs/LangRef.html#pointeraliasing
- uint64_t Size;
- /// AATags - The metadata nodes which describes the aliasing of the
- /// location (each member is null if that kind of information is
- /// unavailable)..
- AAMDNodes AATags;
-
- explicit Location(const Value *P = nullptr, uint64_t S = UnknownSize,
- const AAMDNodes &N = AAMDNodes())
- : Ptr(P), Size(S), AATags(N) {}
-
- Location getWithNewPtr(const Value *NewPtr) const {
- Location Copy(*this);
- Copy.Ptr = NewPtr;
- return Copy;
- }
-
- Location getWithNewSize(uint64_t NewSize) const {
- Location Copy(*this);
- Copy.Size = NewSize;
- return Copy;
- }
-
- Location getWithoutAATags() const {
- Location Copy(*this);
- Copy.AATags = AAMDNodes();
- return Copy;
- }
-
- bool operator==(const AliasAnalysis::Location &Other) const {
- return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags;
- }
- };
-
- /// getLocation - Fill in Loc with information about the memory reference by
- /// the given instruction.
- Location getLocation(const LoadInst *LI);
- Location getLocation(const StoreInst *SI);
- Location getLocation(const VAArgInst *VI);
- Location getLocation(const AtomicCmpXchgInst *CXI);
- Location getLocation(const AtomicRMWInst *RMWI);
- static Location getLocationForSource(const MemTransferInst *MTI);
- static Location getLocationForDest(const MemIntrinsic *MI);
- 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");
- }
+ /// Legacy typedef for the AA location object. New code should use \c
+ /// MemoryLocation directly.
+ typedef MemoryLocation Location;
/// 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
@@ -601,28 +541,6 @@ public:
}
};
-// Specialize DenseMapInfo for Location.
-template<>
-struct DenseMapInfo<AliasAnalysis::Location> {
- static inline AliasAnalysis::Location getEmptyKey() {
- return AliasAnalysis::Location(DenseMapInfo<const Value *>::getEmptyKey(),
- 0);
- }
- static inline AliasAnalysis::Location getTombstoneKey() {
- return AliasAnalysis::Location(
- DenseMapInfo<const Value *>::getTombstoneKey(), 0);
- }
- static unsigned getHashValue(const AliasAnalysis::Location &Val) {
- return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
- DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^
- DenseMapInfo<AAMDNodes>::getHashValue(Val.AATags);
- }
- static bool isEqual(const AliasAnalysis::Location &LHS,
- const AliasAnalysis::Location &RHS) {
- return LHS == RHS;
- }
-};
-
/// isNoAliasCall - Return true if this pointer is returned by a noalias
/// function.
bool isNoAliasCall(const Value *V);
diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
index 9acc863a7382..85a299b6dddf 100644
--- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -191,8 +191,8 @@ public:
/// \brief Data about a loop.
///
- /// Contains the data necessary to represent represent a loop as a
- /// pseudo-node once it's packaged.
+ /// Contains the data necessary to represent a loop as a pseudo-node once it's
+ /// packaged.
struct LoopData {
typedef SmallVector<std::pair<BlockNode, BlockMass>, 4> ExitMap;
typedef SmallVector<BlockNode, 4> NodeList;
@@ -930,7 +930,7 @@ void BlockFrequencyInfoImpl<BT>::doFunction(const FunctionT *F,
initializeRPOT();
initializeLoops();
- // Visit loops in post-order to find thelocal mass distribution, and then do
+ // Visit loops in post-order to find the local mass distribution, and then do
// the full function.
computeMassInLoops();
computeMassInFunction();
diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h
index 89eef68d8431..9d867567ba29 100644
--- a/include/llvm/Analysis/BranchProbabilityInfo.h
+++ b/include/llvm/Analysis/BranchProbabilityInfo.h
@@ -47,6 +47,9 @@ public:
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnFunction(Function &F) override;
+
+ void releaseMemory() override;
+
void print(raw_ostream &OS, const Module *M = nullptr) const override;
/// \brief Get an edge's probability, relative to other out-edges of the Src.
diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h
index 14b88220202a..5b64d857bf71 100644
--- a/include/llvm/Analysis/CallGraph.h
+++ b/include/llvm/Analysis/CallGraph.h
@@ -230,7 +230,7 @@ public:
void addCalledFunction(CallSite CS, CallGraphNode *M) {
assert(!CS.getInstruction() || !CS.getCalledFunction() ||
!CS.getCalledFunction()->isIntrinsic());
- CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M));
+ CalledFunctions.emplace_back(CS.getInstruction(), M);
M->AddRef();
}
diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h
index 0b3b2ea42813..a08ce574ea56 100644
--- a/include/llvm/Analysis/DependenceAnalysis.h
+++ b/include/llvm/Analysis/DependenceAnalysis.h
@@ -41,6 +41,7 @@
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
@@ -520,11 +521,11 @@ namespace llvm {
/// in LoopNest.
bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const;
- /// Makes sure both subscripts (i.e. Pair->Src and Pair->Dst) share the same
- /// integer type by sign-extending one of them when necessary.
+ /// Makes sure all subscript pairs share the same integer type by
+ /// sign-extending as necessary.
/// Sign-extending a subscript is safe because getelementptr assumes the
- /// array subscripts are signed.
- void unifySubscriptType(Subscript *Pair);
+ /// array subscripts are signed.
+ void unifySubscriptType(ArrayRef<Subscript *> Pairs);
/// removeMatchingExtensions - Examines a subscript pair.
/// If the source and destination are identically sign (or zero)
diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h
index c14e1451f338..7b635a8b4960 100644
--- a/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -345,6 +345,10 @@ public:
/// to needsChecking.
bool needsAnyChecking(const SmallVectorImpl<int> *PtrPartition) const;
+ /// \brief Returns the number of run-time checks required according to
+ /// needsChecking.
+ unsigned getNumberOfChecks(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
@@ -385,7 +389,10 @@ public:
/// \brief Number of memchecks required to prove independence of otherwise
/// may-alias pointers.
- unsigned getNumRuntimePointerChecks() const { return NumComparisons; }
+ unsigned getNumRuntimePointerChecks(
+ const SmallVectorImpl<int> *PtrPartition = nullptr) const {
+ return PtrRtCheck.getNumberOfChecks(PtrPartition);
+ }
/// Return true if the block BB needs to be predicated in order for the loop
/// to be vectorized.
@@ -460,10 +467,6 @@ private:
/// loop-independent and loop-carried dependences between memory accesses.
MemoryDepChecker DepChecker;
- /// \brief Number of memchecks required to prove independence of otherwise
- /// may-alias pointers
- unsigned NumComparisons;
-
Loop *TheLoop;
ScalarEvolution *SE;
const DataLayout &DL;
@@ -501,6 +504,11 @@ const SCEV *replaceSymbolicStrideSCEV(ScalarEvolution *SE,
const ValueToValueMap &PtrToStride,
Value *Ptr, Value *OrigPtr = nullptr);
+/// \brief Check the stride of the pointer and ensure that it does not wrap in
+/// the address space.
+int isStridedPtr(ScalarEvolution *SE, Value *Ptr, const Loop *Lp,
+ const ValueToValueMap &StridesMap);
+
/// \brief This analysis provides dependence information for the memory accesses
/// of a loop.
///
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index be78c15e7224..bbcde8d9721a 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -47,13 +47,6 @@ namespace llvm {
template <typename IRUnitT> class AnalysisManager;
class PreservedAnalyses;
-template<typename T>
-inline void RemoveFromVector(std::vector<T*> &V, T *N) {
- typename std::vector<T*>::iterator I = std::find(V.begin(), V.end(), N);
- assert(I != V.end() && "N is not in this list!");
- V.erase(I);
-}
-
class DominatorTree;
class LoopInfo;
class Loop;
@@ -324,7 +317,10 @@ public:
/// current loop, updating the Blocks as appropriate. This does not update
/// the mapping in the LoopInfo class.
void removeBlockFromLoop(BlockT *BB) {
- RemoveFromVector(Blocks, BB);
+ auto I = std::find(Blocks.begin(), Blocks.end(), BB);
+ assert(I != Blocks.end() && "N is not in this list!");
+ Blocks.erase(I);
+
DenseBlockSet.erase(BB);
}
@@ -493,7 +489,7 @@ private:
template<class BlockT, class LoopT>
class LoopInfoBase {
// BBMap - Mapping of basic blocks to the inner most loop they occur in
- DenseMap<BlockT *, LoopT *> BBMap;
+ DenseMap<const BlockT *, LoopT *> BBMap;
std::vector<LoopT *> TopLevelLoops;
friend class LoopBase<BlockT, LoopT>;
friend class LoopInfo;
@@ -543,9 +539,7 @@ public:
/// getLoopFor - Return the inner most loop that BB lives in. If a basic
/// block is in no loop (for example the entry node), null is returned.
///
- LoopT *getLoopFor(const BlockT *BB) const {
- return BBMap.lookup(const_cast<BlockT*>(BB));
- }
+ LoopT *getLoopFor(const BlockT *BB) const { return BBMap.lookup(BB); }
/// operator[] - same as getLoopFor...
///
@@ -562,7 +556,7 @@ public:
}
// isLoopHeader - True if the block is a loop header node
- bool isLoopHeader(BlockT *BB) const {
+ bool isLoopHeader(const BlockT *BB) const {
const LoopT *L = getLoopFor(BB);
return L && L->getHeader() == BB;
}
@@ -729,12 +723,6 @@ public:
/// \brief Provide a name for the analysis for debugging and logging.
static StringRef name() { return "LoopAnalysis"; }
- LoopAnalysis() {}
- LoopAnalysis(const LoopAnalysis &Arg) {}
- LoopAnalysis(LoopAnalysis &&Arg) {}
- LoopAnalysis &operator=(const LoopAnalysis &RHS) { return *this; }
- LoopAnalysis &operator=(LoopAnalysis &&RHS) { return *this; }
-
LoopInfo run(Function &F, AnalysisManager<Function> *AM);
};
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
index 0490bb1d761a..f5cc856f6247 100644
--- a/include/llvm/Analysis/LoopInfoImpl.h
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -527,7 +527,7 @@ void LoopInfoBase<BlockT, LoopT>::verify() const {
// Verify that blocks are mapped to valid loops.
#ifndef NDEBUG
for (auto &Entry : BBMap) {
- BlockT *BB = Entry.first;
+ const BlockT *BB = Entry.first;
LoopT *L = Entry.second;
assert(Loops.count(L) && "orphaned loop");
assert(L->contains(BB) && "orphaned block");
diff --git a/include/llvm/Analysis/MemoryLocation.h b/include/llvm/Analysis/MemoryLocation.h
new file mode 100644
index 000000000000..94d938dc491f
--- /dev/null
+++ b/include/llvm/Analysis/MemoryLocation.h
@@ -0,0 +1,137 @@
+//===- MemoryLocation.h - Memory location descriptions ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file provides utility analysis objects describing memory locations.
+/// These are used both by the Alias Analysis infrastructure and more
+/// specialized memory analysis layers.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_MEMORYLOCATION_H
+#define LLVM_ANALYSIS_MEMORYLOCATION_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Metadata.h"
+
+namespace llvm {
+
+class LoadInst;
+class StoreInst;
+class MemTransferInst;
+class MemIntrinsic;
+
+/// Representation for a specific memory location.
+///
+/// This abstraction can be used to represent a specific location in memory.
+/// The goal of the location is to represent enough information to describe
+/// abstract aliasing, modification, and reference behaviors of whatever
+/// value(s) are stored in memory at the particular location.
+///
+/// The primary user of this interface is LLVM's Alias Analysis, but other
+/// memory analyses such as MemoryDependence can use it as well.
+class MemoryLocation {
+public:
+ /// UnknownSize - This is a special value which can be used with the
+ /// size arguments in alias queries to indicate that the caller does not
+ /// know the sizes of the potential memory references.
+ enum : uint64_t { UnknownSize = ~UINT64_C(0) };
+
+ /// The address of the start of the location.
+ const Value *Ptr;
+
+ /// The maximum size of the location, in address-units, or
+ /// UnknownSize if the size is not known.
+ ///
+ /// Note that an unknown size does not mean the pointer aliases the entire
+ /// virtual address space, because there are restrictions on stepping out of
+ /// one object and into another. See
+ /// http://llvm.org/docs/LangRef.html#pointeraliasing
+ uint64_t Size;
+
+ /// The metadata nodes which describes the aliasing of the location (each
+ /// member is null if that kind of information is unavailable).
+ AAMDNodes AATags;
+
+ /// Return a location with information about the memory reference by the given
+ /// instruction.
+ static MemoryLocation get(const LoadInst *LI);
+ static MemoryLocation get(const StoreInst *SI);
+ static MemoryLocation get(const VAArgInst *VI);
+ static MemoryLocation get(const AtomicCmpXchgInst *CXI);
+ static MemoryLocation get(const AtomicRMWInst *RMWI);
+ static MemoryLocation get(const Instruction *Inst) {
+ if (auto *I = dyn_cast<LoadInst>(Inst))
+ return get(I);
+ else if (auto *I = dyn_cast<StoreInst>(Inst))
+ return get(I);
+ else if (auto *I = dyn_cast<VAArgInst>(Inst))
+ return get(I);
+ else if (auto *I = dyn_cast<AtomicCmpXchgInst>(Inst))
+ return get(I);
+ else if (auto *I = dyn_cast<AtomicRMWInst>(Inst))
+ return get(I);
+ llvm_unreachable("unsupported memory instruction");
+ }
+
+ /// Return a location representing the source of a memory transfer.
+ static MemoryLocation getForSource(const MemTransferInst *MTI);
+
+ /// Return a location representing the destination of a memory set or
+ /// transfer.
+ static MemoryLocation getForDest(const MemIntrinsic *MI);
+
+ explicit MemoryLocation(const Value *Ptr = nullptr,
+ uint64_t Size = UnknownSize,
+ const AAMDNodes &AATags = AAMDNodes())
+ : Ptr(Ptr), Size(Size), AATags(AATags) {}
+
+ MemoryLocation getWithNewPtr(const Value *NewPtr) const {
+ MemoryLocation Copy(*this);
+ Copy.Ptr = NewPtr;
+ return Copy;
+ }
+
+ MemoryLocation getWithNewSize(uint64_t NewSize) const {
+ MemoryLocation Copy(*this);
+ Copy.Size = NewSize;
+ return Copy;
+ }
+
+ MemoryLocation getWithoutAATags() const {
+ MemoryLocation Copy(*this);
+ Copy.AATags = AAMDNodes();
+ return Copy;
+ }
+
+ bool operator==(const MemoryLocation &Other) const {
+ return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags;
+ }
+};
+
+// Specialize DenseMapInfo for MemoryLocation.
+template <> struct DenseMapInfo<MemoryLocation> {
+ static inline MemoryLocation getEmptyKey() {
+ return MemoryLocation(DenseMapInfo<const Value *>::getEmptyKey(), 0);
+ }
+ static inline MemoryLocation getTombstoneKey() {
+ return MemoryLocation(DenseMapInfo<const Value *>::getTombstoneKey(), 0);
+ }
+ static unsigned getHashValue(const MemoryLocation &Val) {
+ return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
+ DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^
+ DenseMapInfo<AAMDNodes>::getHashValue(Val.AATags);
+ }
+ static bool isEqual(const MemoryLocation &LHS, const MemoryLocation &RHS) {
+ return LHS == RHS;
+ }
+};
+}
+
+#endif
diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h
index 84bb9d8008b5..cbdbb88f7407 100644
--- a/include/llvm/Analysis/PHITransAddr.h
+++ b/include/llvm/Analysis/PHITransAddr.h
@@ -75,12 +75,12 @@ public:
bool IsPotentiallyPHITranslatable() const;
/// PHITranslateValue - PHI translate the current address up the CFG from
- /// CurBB to Pred, updating our state to reflect any needed changes. If the
- /// dominator tree DT is non-null, the translated value must dominate
+ /// CurBB to Pred, updating our state to reflect any needed changes. If
+ /// 'MustDominate' is true, the translated value must dominate
/// PredBB. This returns true on failure and sets Addr to null.
bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB,
- const DominatorTree *DT);
-
+ const DominatorTree *DT, bool MustDominate);
+
/// PHITranslateWithInsertion - PHI translate this value into the specified
/// predecessor block, inserting a computation of the value if it is
/// unavailable.
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index 86bf1549dc78..3700c9e4ac22 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -221,19 +221,21 @@ public:
/// Parameters that control the generic loop unrolling transformation.
struct UnrollingPreferences {
- /// The cost threshold for the unrolled loop, compared to
- /// CodeMetrics.NumInsts aggregated over all basic blocks in the loop body.
- /// The unrolling factor is set such that the unrolled loop body does not
- /// exceed this cost. Set this to UINT_MAX to disable the loop body cost
+ /// The cost threshold for the unrolled loop. Should be relative to the
+ /// getUserCost values returned by this API, and the expectation is that
+ /// the unrolled loop's instructions when run through that interface should
+ /// not exceed this cost. However, this is only an estimate. Also, specific
+ /// loops may be unrolled even with a cost above this threshold if deemed
+ /// profitable. Set this to UINT_MAX to disable the loop body cost
/// restriction.
unsigned Threshold;
- /// If complete unrolling could help other optimizations (e.g. InstSimplify)
- /// to remove N% of instructions, then we can go beyond unroll threshold.
- /// This value set the minimal percent for allowing that.
- unsigned MinPercentOfOptimized;
- /// The absolute cost threshold. We won't go beyond this even if complete
- /// unrolling could result in optimizing out 90% of instructions.
- unsigned AbsoluteThreshold;
+ /// If complete unrolling will reduce the cost of the loop below its
+ /// expected dynamic cost while rolled by this percentage, apply a discount
+ /// (below) to its unrolled cost.
+ unsigned PercentDynamicCostSavedThreshold;
+ /// The discount applied to the unrolled cost when the *dynamic* cost
+ /// savings of unrolling exceed the \c PercentDynamicCostSavedThreshold.
+ unsigned DynamicCostSavingsDiscount;
/// The cost threshold for the unrolled loop when optimizing for size (set
/// to UINT_MAX to disable).
unsigned OptSizeThreshold;
@@ -303,7 +305,8 @@ public:
/// mode is legal for a load/store of any legal type.
/// TODO: Handle pre/postinc as well.
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) const;
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace = 0) const;
/// \brief Return true if the target works with masked instruction
/// AVX2 allows masks for consecutive load and store for i32 and i64 elements.
@@ -319,7 +322,8 @@ public:
/// If the AM is not supported, it returns a negative value.
/// TODO: Handle pre/postinc as well.
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) const;
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace = 0) const;
/// \brief Return true if it's free to truncate a value of type Ty1 to type
/// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16
@@ -444,6 +448,20 @@ public:
unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
unsigned AddressSpace) const;
+ /// \return The cost of the interleaved memory operation.
+ /// \p Opcode is the memory operation code
+ /// \p VecTy is the vector type of the interleaved access.
+ /// \p Factor is the interleave factor
+ /// \p Indices is the indices for interleaved load members (as interleaved
+ /// load allows gaps)
+ /// \p Alignment is the alignment of the memory operation
+ /// \p AddressSpace is address space of the pointer.
+ unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
+ unsigned Factor,
+ ArrayRef<unsigned> Indices,
+ unsigned Alignment,
+ unsigned AddressSpace) const;
+
/// \brief Calculate the cost of performing a vector reduction.
///
/// This is the cost of reducing the vector value of type \p Ty to a scalar
@@ -539,12 +557,13 @@ public:
virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
- int64_t Scale) = 0;
+ int64_t Scale,
+ unsigned AddrSpace) = 0;
virtual bool isLegalMaskedStore(Type *DataType, int Consecutive) = 0;
virtual bool isLegalMaskedLoad(Type *DataType, int Consecutive) = 0;
virtual int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
- int64_t Scale) = 0;
+ int64_t Scale, unsigned AddrSpace) = 0;
virtual bool isTruncateFree(Type *Ty1, Type *Ty2) = 0;
virtual bool isProfitableToHoist(Instruction *I) = 0;
virtual bool isTypeLegal(Type *Ty) = 0;
@@ -582,6 +601,11 @@ public:
virtual unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
unsigned Alignment,
unsigned AddressSpace) = 0;
+ virtual unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
+ unsigned Factor,
+ ArrayRef<unsigned> Indices,
+ unsigned Alignment,
+ unsigned AddressSpace) = 0;
virtual unsigned getReductionCost(unsigned Opcode, Type *Ty,
bool IsPairwiseForm) = 0;
virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
@@ -648,9 +672,10 @@ public:
return Impl.isLegalICmpImmediate(Imm);
}
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) override {
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace) override {
return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
- Scale);
+ Scale, AddrSpace);
}
bool isLegalMaskedStore(Type *DataType, int Consecutive) override {
return Impl.isLegalMaskedStore(DataType, Consecutive);
@@ -659,8 +684,10 @@ public:
return Impl.isLegalMaskedLoad(DataType, Consecutive);
}
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) override {
- return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, Scale);
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace) override {
+ return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg,
+ Scale, AddrSpace);
}
bool isTruncateFree(Type *Ty1, Type *Ty2) override {
return Impl.isTruncateFree(Ty1, Ty2);
@@ -740,6 +767,14 @@ public:
unsigned AddressSpace) override {
return Impl.getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
}
+ unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
+ unsigned Factor,
+ ArrayRef<unsigned> Indices,
+ unsigned Alignment,
+ unsigned AddressSpace) override {
+ return Impl.getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
+ Alignment, AddressSpace);
+ }
unsigned getReductionCost(unsigned Opcode, Type *Ty,
bool IsPairwiseForm) override {
return Impl.getReductionCost(Opcode, Ty, IsPairwiseForm);
diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h
index 253319ccd441..e6a8a7690820 100644
--- a/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -207,7 +207,8 @@ public:
bool isLegalICmpImmediate(int64_t Imm) { return false; }
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) {
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace) {
// Guess that only reg and reg+reg addressing is allowed. This heuristic is
// taken from the implementation of LSR.
return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1);
@@ -218,9 +219,10 @@ public:
bool isLegalMaskedLoad(Type *DataType, int Consecutive) { return false; }
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) {
+ bool HasBaseReg, int64_t Scale, unsigned AddrSpace) {
// Guess that all legal addressing mode are free.
- if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale))
+ if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
+ Scale, AddrSpace))
return 0;
return -1;
}
@@ -300,6 +302,14 @@ public:
return 1;
}
+ unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
+ unsigned Factor,
+ ArrayRef<unsigned> Indices,
+ unsigned Alignment,
+ unsigned AddressSpace) {
+ return 1;
+ }
+
unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
ArrayRef<Type *> Tys) {
return 1;
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
index 46e64d112ea7..4c040a7f3e22 100644
--- a/include/llvm/Bitcode/BitstreamReader.h
+++ b/include/llvm/Bitcode/BitstreamReader.h
@@ -113,7 +113,7 @@ public:
return *const_cast<BlockInfo*>(BI);
// Otherwise, add a new record.
- BlockInfoRecords.push_back(BlockInfo());
+ BlockInfoRecords.emplace_back();
BlockInfoRecords.back().BlockID = BlockID;
return BlockInfoRecords.back();
}
diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h
index 9e2c2fa4a156..f7487a05bdb7 100644
--- a/include/llvm/Bitcode/BitstreamWriter.h
+++ b/include/llvm/Bitcode/BitstreamWriter.h
@@ -215,7 +215,7 @@ public:
// Push the outer block's abbrev set onto the stack, start out with an
// empty abbrev set.
- BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex));
+ BlockScope.emplace_back(OldCodeSize, BlockSizeWordIndex);
BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
// If there is a blockinfo for this BlockID, add all the predefined abbrevs
@@ -503,7 +503,7 @@ private:
return *BI;
// Otherwise, add a new record.
- BlockInfoRecords.push_back(BlockInfo());
+ BlockInfoRecords.emplace_back();
BlockInfoRecords.back().BlockID = BlockID;
return BlockInfoRecords.back();
}
diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h
index d07265560430..3e464f4f1e5a 100644
--- a/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/include/llvm/CodeGen/BasicTTIImpl.h
@@ -125,23 +125,24 @@ public:
}
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) {
+ bool HasBaseReg, int64_t Scale,
+ unsigned AddrSpace) {
TargetLoweringBase::AddrMode AM;
AM.BaseGV = BaseGV;
AM.BaseOffs = BaseOffset;
AM.HasBaseReg = HasBaseReg;
AM.Scale = Scale;
- return getTLI()->isLegalAddressingMode(AM, Ty);
+ return getTLI()->isLegalAddressingMode(AM, Ty, AddrSpace);
}
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale) {
+ bool HasBaseReg, int64_t Scale, unsigned AddrSpace) {
TargetLoweringBase::AddrMode AM;
AM.BaseGV = BaseGV;
AM.BaseOffs = BaseOffset;
AM.HasBaseReg = HasBaseReg;
AM.Scale = Scale;
- return getTLI()->getScalingFactorCost(AM, Ty);
+ return getTLI()->getScalingFactorCost(AM, Ty, AddrSpace);
}
bool isTruncateFree(Type *Ty1, Type *Ty2) {
@@ -522,6 +523,73 @@ public:
return Cost;
}
+ unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
+ unsigned Factor,
+ ArrayRef<unsigned> Indices,
+ unsigned Alignment,
+ unsigned AddressSpace) {
+ VectorType *VT = dyn_cast<VectorType>(VecTy);
+ assert(VT && "Expect a vector type for interleaved memory op");
+
+ unsigned NumElts = VT->getNumElements();
+ assert(Factor > 1 && NumElts % Factor == 0 && "Invalid interleave factor");
+
+ unsigned NumSubElts = NumElts / Factor;
+ VectorType *SubVT = VectorType::get(VT->getElementType(), NumSubElts);
+
+ // Firstly, the cost of load/store operation.
+ unsigned Cost = getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace);
+
+ // Then plus the cost of interleave operation.
+ if (Opcode == Instruction::Load) {
+ // The interleave cost is similar to extract sub vectors' elements
+ // from the wide vector, and insert them into sub vectors.
+ //
+ // E.g. An interleaved load of factor 2 (with one member of index 0):
+ // %vec = load <8 x i32>, <8 x i32>* %ptr
+ // %v0 = shuffle %vec, undef, <0, 2, 4, 6> ; Index 0
+ // The cost is estimated as extract elements at 0, 2, 4, 6 from the
+ // <8 x i32> vector and insert them into a <4 x i32> vector.
+
+ assert(Indices.size() <= Factor &&
+ "Interleaved memory op has too many members");
+ for (unsigned Index : Indices) {
+ assert(Index < Factor && "Invalid index for interleaved memory op");
+
+ // Extract elements from loaded vector for each sub vector.
+ for (unsigned i = 0; i < NumSubElts; i++)
+ Cost += getVectorInstrCost(Instruction::ExtractElement, VT,
+ Index + i * Factor);
+ }
+
+ unsigned InsSubCost = 0;
+ for (unsigned i = 0; i < NumSubElts; i++)
+ InsSubCost += getVectorInstrCost(Instruction::InsertElement, SubVT, i);
+
+ Cost += Indices.size() * InsSubCost;
+ } else {
+ // The interleave cost is extract all elements from sub vectors, and
+ // insert them into the wide vector.
+ //
+ // E.g. An interleaved store of factor 2:
+ // %v0_v1 = shuffle %v0, %v1, <0, 4, 1, 5, 2, 6, 3, 7>
+ // store <8 x i32> %interleaved.vec, <8 x i32>* %ptr
+ // The cost is estimated as extract all elements from both <4 x i32>
+ // vectors and insert into the <8 x i32> vector.
+
+ unsigned ExtSubCost = 0;
+ for (unsigned i = 0; i < NumSubElts; i++)
+ ExtSubCost += getVectorInstrCost(Instruction::ExtractElement, SubVT, i);
+
+ Cost += Factor * ExtSubCost;
+
+ for (unsigned i = 0; i < NumElts; i++)
+ Cost += getVectorInstrCost(Instruction::InsertElement, VT, i);
+ }
+
+ return Cost;
+ }
+
unsigned getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy,
ArrayRef<Type *> Tys) {
unsigned ISD = 0;
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
index a1b9b4e566a2..b824df3013d9 100644
--- a/include/llvm/CodeGen/CommandFlags.h
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -24,6 +24,7 @@
#include "llvm/Support/Host.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetRecip.h"
#include <string>
using namespace llvm;
@@ -152,6 +153,12 @@ FuseFPOps("fp-contract",
"Only fuse FP ops when the result won't be effected."),
clEnumValEnd));
+cl::list<std::string>
+ReciprocalOps("recip",
+ cl::CommaSeparated,
+ cl::desc("Choose reciprocal operation types and parameters."),
+ cl::value_desc("all,none,default,divf,!vec-sqrtd,vec-divd:0,sqrt:9..."));
+
cl::opt<bool>
DontPlaceZerosInBSS("nozero-initialized-in-bss",
cl::desc("Don't place zero-initialized symbols into bss section"),
@@ -230,6 +237,7 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
TargetOptions Options;
Options.LessPreciseFPMADOption = EnableFPMAD;
Options.AllowFPOpFusion = FuseFPOps;
+ Options.Reciprocals = TargetRecip(ReciprocalOps);
Options.UnsafeFPMath = EnableUnsafeFPMath;
Options.NoInfsFPMath = EnableNoInfsFPMath;
Options.NoNaNsFPMath = EnableNoNaNsFPMath;
diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h
index 8e40ef77d374..464e0faa0ed3 100644
--- a/include/llvm/CodeGen/DIE.h
+++ b/include/llvm/CodeGen/DIE.h
@@ -105,153 +105,13 @@ public:
};
//===--------------------------------------------------------------------===//
-/// DIE - A structured debug information entry. Has an abbreviation which
-/// describes its organization.
-class DIEValue;
-
-class DIE {
-protected:
- /// Offset - Offset in debug info section.
- ///
- unsigned Offset;
-
- /// Size - Size of instance + children.
- ///
- unsigned Size;
-
- /// Abbrev - Buffer for constructing abbreviation.
- ///
- DIEAbbrev Abbrev;
-
- /// Children DIEs.
- ///
- // This can't be a vector<DIE> because pointer validity is requirent for the
- // Parent pointer and DIEEntry.
- // It can't be a list<DIE> because some clients need pointer validity before
- // the object has been added to any child list
- // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may
- // be more convoluted than beneficial.
- std::vector<std::unique_ptr<DIE>> Children;
-
- DIE *Parent;
-
- /// Attribute values.
- ///
- SmallVector<DIEValue *, 12> Values;
-
-protected:
- DIE()
- : Offset(0), Size(0), Abbrev((dwarf::Tag)0, dwarf::DW_CHILDREN_no),
- Parent(nullptr) {}
-
-public:
- explicit DIE(dwarf::Tag Tag)
- : Offset(0), Size(0), Abbrev((dwarf::Tag)Tag, dwarf::DW_CHILDREN_no),
- Parent(nullptr) {}
-
- // Accessors.
- DIEAbbrev &getAbbrev() { return Abbrev; }
- const DIEAbbrev &getAbbrev() const { return Abbrev; }
- unsigned getAbbrevNumber() const { return Abbrev.getNumber(); }
- dwarf::Tag getTag() const { return Abbrev.getTag(); }
- unsigned getOffset() const { return Offset; }
- unsigned getSize() const { return Size; }
- const std::vector<std::unique_ptr<DIE>> &getChildren() const {
- return Children;
- }
- const SmallVectorImpl<DIEValue *> &getValues() const { return Values; }
- DIE *getParent() const { return Parent; }
- /// Climb up the parent chain to get the compile or type unit DIE this DIE
- /// belongs to.
- const DIE *getUnit() const;
- /// Similar to getUnit, returns null when DIE is not added to an
- /// owner yet.
- const DIE *getUnitOrNull() const;
- void setOffset(unsigned O) { Offset = O; }
- void setSize(unsigned S) { Size = S; }
-
- /// addValue - Add a value and attributes to a DIE.
- ///
- void addValue(dwarf::Attribute Attribute, dwarf::Form Form, DIEValue *Value) {
- Abbrev.AddAttribute(Attribute, Form);
- Values.push_back(Value);
- }
-
- /// addChild - Add a child to the DIE.
- ///
- void addChild(std::unique_ptr<DIE> Child) {
- assert(!Child->getParent());
- Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
- Child->Parent = this;
- Children.push_back(std::move(Child));
- }
-
- /// findAttribute - Find a value in the DIE with the attribute given,
- /// returns NULL if no such attribute exists.
- DIEValue *findAttribute(dwarf::Attribute Attribute) const;
-
-#ifndef NDEBUG
- void print(raw_ostream &O, unsigned IndentCount = 0) const;
- void dump();
-#endif
-};
-
-//===--------------------------------------------------------------------===//
-/// DIEValue - A debug information entry value. Some of these roughly correlate
-/// to DWARF attribute classes.
-///
-class DIEValue {
-public:
- enum Type {
- isInteger,
- isString,
- isExpr,
- isLabel,
- isDelta,
- isEntry,
- isTypeSignature,
- isBlock,
- isLoc,
- isLocList,
- };
-
-private:
- /// Ty - Type of data stored in the value.
- ///
- Type Ty;
-
-protected:
- explicit DIEValue(Type T) : Ty(T) {}
- ~DIEValue() {}
-
-public:
- // Accessors
- Type getType() const { return Ty; }
-
- /// EmitValue - Emit value via the Dwarf writer.
- ///
- void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
-
- /// SizeOf - Return the size of a value in bytes.
- ///
- unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
-
-#ifndef NDEBUG
- void print(raw_ostream &O) const;
- void dump() const;
-#endif
-};
-
-//===--------------------------------------------------------------------===//
/// DIEInteger - An integer value DIE.
///
-class DIEInteger : public DIEValue {
- friend DIEValue;
-
+class DIEInteger {
uint64_t Integer;
public:
- explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {}
+ explicit DIEInteger(uint64_t I) : Integer(I) {}
/// BestForm - Choose the best form for integer.
///
@@ -278,120 +138,91 @@ public:
uint64_t getValue() const { return Integer; }
void setValue(uint64_t Val) { Integer = Val; }
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *I) { return I->getType() == isInteger; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEExpr - An expression DIE.
//
-class DIEExpr : public DIEValue {
- friend class DIEValue;
-
+class DIEExpr {
const MCExpr *Expr;
public:
- explicit DIEExpr(const MCExpr *E) : DIEValue(isExpr), Expr(E) {}
+ explicit DIEExpr(const MCExpr *E) : Expr(E) {}
/// getValue - Get MCExpr.
///
const MCExpr *getValue() const { return Expr; }
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) { return E->getType() == isExpr; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIELabel - A label DIE.
//
-class DIELabel : public DIEValue {
- friend class DIEValue;
-
+class DIELabel {
const MCSymbol *Label;
public:
- explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {}
+ explicit DIELabel(const MCSymbol *L) : Label(L) {}
/// getValue - Get MCSymbol.
///
const MCSymbol *getValue() const { return Label; }
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *L) { return L->getType() == isLabel; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEDelta - A simple label difference DIE.
///
-class DIEDelta : public DIEValue {
- friend class DIEValue;
-
+class DIEDelta {
const MCSymbol *LabelHi;
const MCSymbol *LabelLo;
public:
- DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo)
- : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *D) { return D->getType() == isDelta; }
+ DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {}
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEString - A container for string values.
///
-class DIEString : public DIEValue {
- friend class DIEValue;
-
+class DIEString {
DwarfStringPoolEntryRef S;
public:
- DIEString(DwarfStringPoolEntryRef S) : DIEValue(isString), S(S) {}
+ DIEString(DwarfStringPoolEntryRef S) : S(S) {}
/// getString - Grab the string out of the object.
StringRef getString() const { return S.getString(); }
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *D) { return D->getType() == isString; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
@@ -399,72 +230,350 @@ private:
/// DIEEntry - A pointer to another debug information entry. An instance of
/// this class can also be used as a proxy for a debug information entry not
/// yet defined (ie. types.)
-class DIEEntry : public DIEValue {
- friend class DIEValue;
+class DIE;
+class DIEEntry {
+ DIE *Entry;
- DIE &Entry;
+ DIEEntry() = delete;
public:
- explicit DIEEntry(DIE &E) : DIEValue(isEntry), Entry(E) {
- }
+ explicit DIEEntry(DIE &E) : Entry(&E) {}
- DIE &getEntry() const { return Entry; }
+ DIE &getEntry() const { return *Entry; }
/// Returns size of a ref_addr entry.
static unsigned getRefAddrSize(const AsmPrinter *AP);
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) { return E->getType() == isEntry; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP)
: sizeof(int32_t);
}
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// \brief A signature reference to a type unit.
-class DIETypeSignature : public DIEValue {
- friend class DIEValue;
+class DIETypeSignature {
+ const DwarfTypeUnit *Unit;
- const DwarfTypeUnit &Unit;
+ DIETypeSignature() = delete;
public:
- explicit DIETypeSignature(const DwarfTypeUnit &Unit)
- : DIEValue(isTypeSignature), Unit(Unit) {}
+ explicit DIETypeSignature(const DwarfTypeUnit &Unit) : Unit(&Unit) {}
- // \brief Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) {
- return E->getType() == isTypeSignature;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
+ assert(Form == dwarf::DW_FORM_ref_sig8);
+ return 8;
}
+#ifndef NDEBUG
+ void print(raw_ostream &O) const;
+#endif
+};
+
+//===--------------------------------------------------------------------===//
+/// DIELocList - Represents a pointer to a location list in the debug_loc
+/// section.
+//
+class DIELocList {
+ // Index into the .debug_loc vector.
+ size_t Index;
+
+public:
+ DIELocList(size_t I) : Index(I) {}
+
+ /// getValue - Grab the current index out.
+ size_t getValue() const { return Index; }
+
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
+
+#ifndef NDEBUG
+ void print(raw_ostream &O) const;
+#endif
+};
+
+//===--------------------------------------------------------------------===//
+/// DIEValue - A debug information entry value. Some of these roughly correlate
+/// to DWARF attribute classes.
+///
+class DIEBlock;
+class DIELoc;
+class DIEValue {
+public:
+ enum Type {
+ isNone,
+#define HANDLE_DIEVALUE(T) is##T,
+#include "llvm/CodeGen/DIEValue.def"
+ };
+
private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
- assert(Form == dwarf::DW_FORM_ref_sig8);
- return 8;
+ /// Ty - Type of data stored in the value.
+ ///
+ Type Ty = isNone;
+ dwarf::Attribute Attribute = (dwarf::Attribute)0;
+ dwarf::Form Form = (dwarf::Form)0;
+
+ /// Storage for the value.
+ ///
+ /// All values that aren't standard layout (or are larger than 8 bytes)
+ /// should be stored by reference instead of by value.
+ typedef AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel,
+ DIEDelta *, DIEEntry, DIETypeSignature,
+ DIEBlock *, DIELoc *, DIELocList> ValTy;
+ static_assert(sizeof(ValTy) <= sizeof(uint64_t) ||
+ sizeof(ValTy) <= sizeof(void *),
+ "Expected all large types to be stored via pointer");
+
+ /// Underlying stored value.
+ ValTy Val;
+
+ template <class T> void construct(T V) {
+ static_assert(std::is_standard_layout<T>::value ||
+ std::is_pointer<T>::value,
+ "Expected standard layout or pointer");
+ new (reinterpret_cast<void *>(Val.buffer)) T(V);
+ }
+
+ template <class T> T *get() { return reinterpret_cast<T *>(Val.buffer); }
+ template <class T> const T *get() const {
+ return reinterpret_cast<const T *>(Val.buffer);
+ }
+ template <class T> void destruct() { get<T>()->~T(); }
+
+ /// Destroy the underlying value.
+ ///
+ /// This should get optimized down to a no-op. We could skip it if we could
+ /// add a static assert on \a std::is_trivially_copyable(), but we currently
+ /// support versions of GCC that don't understand that.
+ void destroyVal() {
+ switch (Ty) {
+ case isNone:
+ return;
+#define HANDLE_DIEVALUE_SMALL(T) \
+ case is##T: \
+ destruct<DIE##T>();
+ return;
+#define HANDLE_DIEVALUE_LARGE(T) \
+ case is##T: \
+ destruct<const DIE##T *>();
+ return;
+#include "llvm/CodeGen/DIEValue.def"
+ }
+ }
+
+ /// Copy the underlying value.
+ ///
+ /// This should get optimized down to a simple copy. We need to actually
+ /// construct the value, rather than calling memcpy, to satisfy strict
+ /// aliasing rules.
+ void copyVal(const DIEValue &X) {
+ switch (Ty) {
+ case isNone:
+ return;
+#define HANDLE_DIEVALUE_SMALL(T) \
+ case is##T: \
+ construct<DIE##T>(*X.get<DIE##T>()); \
+ return;
+#define HANDLE_DIEVALUE_LARGE(T) \
+ case is##T: \
+ construct<const DIE##T *>(*X.get<const DIE##T *>()); \
+ return;
+#include "llvm/CodeGen/DIEValue.def"
+ }
}
+public:
+ DIEValue() = default;
+ DIEValue(const DIEValue &X) : Ty(X.Ty), Attribute(X.Attribute), Form(X.Form) {
+ copyVal(X);
+ }
+ DIEValue &operator=(const DIEValue &X) {
+ destroyVal();
+ Ty = X.Ty;
+ Attribute = X.Attribute;
+ Form = X.Form;
+ copyVal(X);
+ return *this;
+ }
+ ~DIEValue() { destroyVal(); }
+
+#define HANDLE_DIEVALUE_SMALL(T) \
+ DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T &V) \
+ : Ty(is##T), Attribute(Attribute), Form(Form) { \
+ construct<DIE##T>(V); \
+ }
+#define HANDLE_DIEVALUE_LARGE(T) \
+ DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T *V) \
+ : Ty(is##T), Attribute(Attribute), Form(Form) { \
+ assert(V && "Expected valid value"); \
+ construct<const DIE##T *>(V); \
+ }
+#include "llvm/CodeGen/DIEValue.def"
+
+ // Accessors
+ Type getType() const { return Ty; }
+ dwarf::Attribute getAttribute() const { return Attribute; }
+ dwarf::Form getForm() const { return Form; }
+ explicit operator bool() const { return Ty; }
+
+#define HANDLE_DIEVALUE_SMALL(T) \
+ const DIE##T &getDIE##T() const { \
+ assert(getType() == is##T && "Expected " #T); \
+ return *get<DIE##T>(); \
+ }
+#define HANDLE_DIEVALUE_LARGE(T) \
+ const DIE##T &getDIE##T() const { \
+ assert(getType() == is##T && "Expected " #T); \
+ return **get<const DIE##T *>(); \
+ }
+#include "llvm/CodeGen/DIEValue.def"
+
+ /// EmitValue - Emit value via the Dwarf writer.
+ ///
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+
+ /// SizeOf - Return the size of a value in bytes.
+ ///
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
+
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
+ void dump() const;
+#endif
+};
+
+//===--------------------------------------------------------------------===//
+/// DIE - A structured debug information entry. Has an abbreviation which
+/// describes its organization.
+class DIE {
+protected:
+ /// Offset - Offset in debug info section.
+ ///
+ unsigned Offset;
+
+ /// Size - Size of instance + children.
+ ///
+ unsigned Size;
+
+ unsigned AbbrevNumber = ~0u;
+
+ /// Tag - Dwarf tag code.
+ ///
+ dwarf::Tag Tag = (dwarf::Tag)0;
+
+ /// Children DIEs.
+ ///
+ // This can't be a vector<DIE> because pointer validity is requirent for the
+ // Parent pointer and DIEEntry.
+ // It can't be a list<DIE> because some clients need pointer validity before
+ // the object has been added to any child list
+ // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may
+ // be more convoluted than beneficial.
+ std::vector<std::unique_ptr<DIE>> Children;
+
+ DIE *Parent;
+
+ /// Attribute values.
+ ///
+ SmallVector<DIEValue, 12> Values;
+
+protected:
+ DIE() : Offset(0), Size(0), Parent(nullptr) {}
+
+public:
+ explicit DIE(dwarf::Tag Tag)
+ : Offset(0), Size(0), Tag(Tag), Parent(nullptr) {}
+
+ // Accessors.
+ unsigned getAbbrevNumber() const { return AbbrevNumber; }
+ dwarf::Tag getTag() const { return Tag; }
+ unsigned getOffset() const { return Offset; }
+ unsigned getSize() const { return Size; }
+ bool hasChildren() const { return !Children.empty(); }
+
+ typedef std::vector<std::unique_ptr<DIE>>::const_iterator child_iterator;
+ typedef iterator_range<child_iterator> child_range;
+
+ child_range children() const {
+ return llvm::make_range(Children.begin(), Children.end());
+ }
+
+ typedef SmallVectorImpl<DIEValue>::const_iterator value_iterator;
+ typedef iterator_range<value_iterator> value_range;
+
+ value_iterator values_begin() const { return Values.begin(); }
+ value_iterator values_end() const { return Values.end(); }
+ value_range values() const {
+ return llvm::make_range(values_begin(), values_end());
+ }
+
+ void setValue(unsigned I, DIEValue New) {
+ assert(I < Values.size());
+ Values[I] = New;
+ }
+ DIE *getParent() const { return Parent; }
+
+ /// Generate the abbreviation for this DIE.
+ ///
+ /// Calculate the abbreviation for this, which should be uniqued and
+ /// eventually used to call \a setAbbrevNumber().
+ DIEAbbrev generateAbbrev() const;
+
+ /// Set the abbreviation number for this DIE.
+ void setAbbrevNumber(unsigned I) { AbbrevNumber = I; }
+
+ /// Climb up the parent chain to get the compile or type unit DIE this DIE
+ /// belongs to.
+ const DIE *getUnit() const;
+ /// Similar to getUnit, returns null when DIE is not added to an
+ /// owner yet.
+ const DIE *getUnitOrNull() const;
+ void setOffset(unsigned O) { Offset = O; }
+ void setSize(unsigned S) { Size = S; }
+
+ /// addValue - Add a value and attributes to a DIE.
+ ///
+ void addValue(DIEValue Value) { Values.push_back(Value); }
+ template <class T>
+ void addValue(dwarf::Attribute Attribute, dwarf::Form Form, T &&Value) {
+ Values.emplace_back(Attribute, Form, std::forward<T>(Value));
+ }
+
+ /// addChild - Add a child to the DIE.
+ ///
+ DIE &addChild(std::unique_ptr<DIE> Child) {
+ assert(!Child->getParent());
+ Child->Parent = this;
+ Children.push_back(std::move(Child));
+ return *Children.back();
+ }
+
+ /// Find a value in the DIE with the attribute given.
+ ///
+ /// Returns a default-constructed DIEValue (where \a DIEValue::getType()
+ /// gives \a DIEValue::isNone) if no such attribute exists.
+ DIEValue findAttribute(dwarf::Attribute Attribute) const;
+
+#ifndef NDEBUG
+ void print(raw_ostream &O, unsigned IndentCount = 0) const;
+ void dump();
#endif
};
//===--------------------------------------------------------------------===//
/// DIELoc - Represents an expression location.
//
-class DIELoc : public DIEValue, public DIE {
- friend class DIEValue;
-
+class DIELoc : public DIE {
mutable unsigned Size; // Size in bytes excluding size header.
+
public:
- DIELoc() : DIEValue(isLoc), Size(0) {}
+ DIELoc() : Size(0) {}
/// ComputeSize - Calculate the size of the location expression.
///
@@ -485,27 +594,22 @@ public:
return dwarf::DW_FORM_block;
}
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) { return E->getType() == isLoc; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEBlock - Represents a block of values.
//
-class DIEBlock : public DIEValue, public DIE {
- friend class DIEValue;
-
+class DIEBlock : public DIE {
mutable unsigned Size; // Size in bytes excluding size header.
+
public:
- DIEBlock() : DIEValue(isBlock), Size(0) {}
+ DIEBlock() : Size(0) {}
/// ComputeSize - Calculate the size of the location expression.
///
@@ -523,43 +627,11 @@ public:
return dwarf::DW_FORM_block;
}
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) { return E->getType() == isBlock; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
-
-#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
-#endif
-};
-
-//===--------------------------------------------------------------------===//
-/// DIELocList - Represents a pointer to a location list in the debug_loc
-/// section.
-//
-class DIELocList : public DIEValue {
- friend class DIEValue;
-
- // Index into the .debug_loc vector.
- size_t Index;
-
-public:
- DIELocList(size_t I) : DIEValue(isLocList), Index(I) {}
-
- /// getValue - Grab the current index out.
- size_t getValue() const { return Index; }
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *E) { return E->getType() == isLocList; }
-
-private:
- void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
- unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
- void printImpl(raw_ostream &O) const;
+ void print(raw_ostream &O) const;
#endif
};
diff --git a/include/llvm/CodeGen/DIEValue.def b/include/llvm/CodeGen/DIEValue.def
new file mode 100644
index 000000000000..2cfae7b608c6
--- /dev/null
+++ b/include/llvm/CodeGen/DIEValue.def
@@ -0,0 +1,47 @@
+//===- llvm/CodeGen/DIEValue.def - DIEValue types ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Macros for running through all types of DIEValue.
+//
+//===----------------------------------------------------------------------===//
+
+#if !(defined HANDLE_DIEVALUE || defined HANDLE_DIEVALUE_SMALL || \
+ defined HANDLE_DIEVALUE_LARGE)
+#error "Missing macro definition of HANDLE_DIEVALUE"
+#endif
+
+// Handler for all values.
+#ifndef HANDLE_DIEVALUE
+#define HANDLE_DIEVALUE(T)
+#endif
+
+// Handler for small values.
+#ifndef HANDLE_DIEVALUE_SMALL
+#define HANDLE_DIEVALUE_SMALL(T) HANDLE_DIEVALUE(T)
+#endif
+
+// Handler for large values.
+#ifndef HANDLE_DIEVALUE_LARGE
+#define HANDLE_DIEVALUE_LARGE(T) HANDLE_DIEVALUE(T)
+#endif
+
+HANDLE_DIEVALUE_SMALL(Integer)
+HANDLE_DIEVALUE_SMALL(String)
+HANDLE_DIEVALUE_SMALL(Expr)
+HANDLE_DIEVALUE_SMALL(Label)
+HANDLE_DIEVALUE_LARGE(Delta)
+HANDLE_DIEVALUE_SMALL(Entry)
+HANDLE_DIEVALUE_SMALL(TypeSignature)
+HANDLE_DIEVALUE_LARGE(Block)
+HANDLE_DIEVALUE_LARGE(Loc)
+HANDLE_DIEVALUE_SMALL(LocList)
+
+#undef HANDLE_DIEVALUE
+#undef HANDLE_DIEVALUE_SMALL
+#undef HANDLE_DIEVALUE_LARGE
diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h
index 357b2d8a7ca7..e883bd196ea3 100644
--- a/include/llvm/CodeGen/GCMetadata.h
+++ b/include/llvm/CodeGen/GCMetadata.h
@@ -121,7 +121,7 @@ public:
/// label just prior to the safe point (if the code generator is using
/// MachineModuleInfo).
void addSafePoint(GC::PointKind Kind, MCSymbol *Label, DebugLoc DL) {
- SafePoints.push_back(GCPoint(Kind, Label, DL));
+ SafePoints.emplace_back(Kind, Label, DL);
}
/// getFrameSize/setFrameSize - Records the function's frame size.
diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h
index de855f2fe7a0..c97c636abbb4 100644
--- a/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/include/llvm/CodeGen/LiveRangeEdit.h
@@ -102,6 +102,10 @@ private:
/// registers are created.
void MRI_NoteNewVirtualRegister(unsigned VReg) override;
+ /// \brief Check if MachineOperand \p MO is a last use/kill either in the
+ /// main live range of \p LI or in one of the matching subregister ranges.
+ bool useIsKill(const LiveInterval &LI, const MachineOperand &MO) const;
+
public:
/// Create a LiveRangeEdit for breaking down parent into smaller pieces.
/// @param parent The register being spilled or split.
diff --git a/include/llvm/CodeGen/MIRParser/MIRParser.h b/include/llvm/CodeGen/MIRParser/MIRParser.h
new file mode 100644
index 000000000000..710b2d4bef8e
--- /dev/null
+++ b/include/llvm/CodeGen/MIRParser/MIRParser.h
@@ -0,0 +1,52 @@
+//===- MIRParser.h - MIR serialization format parser ----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This MIR serialization library is currently a work in progress. It can't
+// serialize machine functions at this time.
+//
+// This file declares the functions that parse the MIR serialization format
+// files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
+#define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <memory>
+
+namespace llvm {
+
+class SMDiagnostic;
+
+/// This function is the main interface to the MIR serialization format parser.
+///
+/// It reads a YAML file that has an optional LLVM IR and returns an LLVM
+/// module.
+/// \param Filename - The name of the file to parse.
+/// \param Error - Error result info.
+/// \param Context - Context in which to allocate globals info.
+std::unique_ptr<Module> parseMIRFile(StringRef Filename, SMDiagnostic &Error,
+ LLVMContext &Context);
+
+/// This function is another interface to the MIR serialization format parser.
+///
+/// It parses the optional LLVM IR in the given buffer, and returns an LLVM
+/// module.
+/// \param Contents - The MemoryBuffer containing the machine level IR.
+/// \param Error - Error result info.
+/// \param Context - Context in which to allocate globals info.
+std::unique_ptr<Module> parseMIR(std::unique_ptr<MemoryBuffer> Contents,
+ SMDiagnostic &Error, LLVMContext &Context);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h
new file mode 100644
index 000000000000..f9d4c7471b93
--- /dev/null
+++ b/include/llvm/CodeGen/MIRYamlMapping.h
@@ -0,0 +1,40 @@
+//===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The MIR serialization library is currently a work in progress. It can't
+// serialize machine functions at this time.
+//
+// This file implements the mapping between various MIR data structures and
+// their corresponding YAML representation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
+#define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/YAMLTraits.h"
+
+namespace llvm {
+namespace yaml {
+
+struct MachineFunction {
+ StringRef Name;
+};
+
+template <> struct MappingTraits<MachineFunction> {
+ static void mapping(IO &YamlIO, MachineFunction &MF) {
+ YamlIO.mapRequired("name", MF.Name);
+ }
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 40f3b4944cc1..3889d471ccf3 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -256,11 +256,6 @@ class MachineFrameInfo {
/// Not null, if shrink-wrapping found a better place for the epilogue.
MachineBasicBlock *Restore;
- /// Check if it exists a path from \p MBB leading to the basic
- /// block with a SavePoint (a.k.a. prologue).
- bool isBeforeSavePoint(const MachineFunction &MF,
- const MachineBasicBlock &MBB) const;
-
public:
explicit MachineFrameInfo(unsigned StackAlign, bool isStackRealign,
bool RealignOpt)
@@ -627,16 +622,15 @@ public:
MachineBasicBlock *getRestorePoint() const { return Restore; }
void setRestorePoint(MachineBasicBlock *NewRestore) { Restore = NewRestore; }
- /// getPristineRegs - Return a set of physical registers that are pristine on
- /// entry to the MBB.
+ /// Return a set of physical registers that are pristine.
///
/// Pristine registers hold a value that is useless to the current function,
- /// but that must be preserved - they are callee saved registers that have not
- /// been saved yet.
+ /// but that must be preserved - they are callee saved registers that are not
+ /// saved.
///
/// Before the PrologueEpilogueInserter has placed the CSR spill code, this
/// method always returns an empty set.
- BitVector getPristineRegs(const MachineBasicBlock *MBB) const;
+ BitVector getPristineRegs(const MachineFunction &MF) const;
/// print - Used by the MachineFunction printer to print information about
/// stack objects. Implemented in MachineFunction.cpp
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index e57257c76bc7..edda03fe3685 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -331,6 +331,11 @@ public:
operands_begin() + getDesc().getNumDefs(), operands_end());
}
+ /// Returns the number of the operand iterator \p I points to.
+ unsigned getOperandNo(const_mop_iterator I) const {
+ return I - operands_begin();
+ }
+
/// Access to memory operands of the instruction
mmo_iterator memoperands_begin() const { return MemRefs; }
mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; }
@@ -483,6 +488,13 @@ public:
return hasProperty(MCID::NotDuplicable, Type);
}
+ /// Return true if this instruction is convergent.
+ /// Convergent instructions can only be moved to locations that are
+ /// control-equivalent to their initial position.
+ bool isConvergent(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::Convergent, Type);
+ }
+
/// Returns true if the specified instruction has a delay slot
/// which must be filled by the code generator.
bool hasDelaySlot(QueryType Type = AnyInBundle) const {
@@ -924,7 +936,7 @@ public:
/// For normal instructions, this is derived from the MCInstrDesc.
/// For inline assembly it is derived from the flag words.
///
- /// Returns NULL if the static register classs constraint cannot be
+ /// Returns NULL if the static register class constraint cannot be
/// determined.
///
const TargetRegisterClass*
@@ -936,10 +948,10 @@ public:
/// the given \p CurRC.
/// If \p ExploreBundle is set and MI is part of a bundle, all the
/// instructions inside the bundle will be taken into account. In other words,
- /// this method accumulates all the constrains of the operand of this MI and
+ /// this method accumulates all the constraints of the operand of this MI and
/// the related bundle if MI is a bundle or inside a bundle.
///
- /// Returns the register class that statisfies both \p CurRC and the
+ /// Returns the register class that satisfies both \p CurRC and the
/// constraints set by MI. Returns NULL if such a register class does not
/// exist.
///
@@ -952,7 +964,7 @@ public:
/// \brief Applies the constraints (def/use) implied by the \p OpIdx operand
/// to the given \p CurRC.
///
- /// Returns the register class that statisfies both \p CurRC and the
+ /// Returns the register class that satisfies both \p CurRC and the
/// constraints set by \p OpIdx MI. Returns NULL if such a register class
/// does not exist.
///
diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h
index f7bcf45d93c5..438ef2e37255 100644
--- a/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/include/llvm/CodeGen/MachineLoopInfo.h
@@ -114,7 +114,7 @@ public:
}
// isLoopHeader - True if the block is a loop header node
- inline bool isLoopHeader(MachineBasicBlock *BB) const {
+ inline bool isLoopHeader(const MachineBasicBlock *BB) const {
return LI.isLoopHeader(BB);
}
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 39f69549d7cf..9c7e7b4001a4 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -17,11 +17,11 @@
#include "llvm/Pass.h"
#include "llvm/Target/TargetMachine.h"
+#include <functional>
#include <string>
namespace llvm {
-class FunctionPass;
class MachineFunctionPass;
class PassConfigImpl;
class PassInfo;
@@ -374,6 +374,10 @@ namespace llvm {
createMachineFunctionPrinterPass(raw_ostream &OS,
const std::string &Banner ="");
+ /// MIRPrinting pass - this pass prints out the LLVM IR into the given stream
+ /// using the MIR serialization format.
+ MachineFunctionPass *createPrintMIRPass(raw_ostream &OS);
+
/// createCodeGenPreparePass - Transform the code to expose more pattern
/// matching during instruction selection.
FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = nullptr);
@@ -488,6 +492,10 @@ namespace llvm {
/// MachineFunctionPrinterPass - This pass prints out MachineInstr's.
extern char &MachineFunctionPrinterPassID;
+ /// MIRPrintingPass - this pass prints out the LLVM IR using the MIR
+ /// serialization format.
+ extern char &MIRPrintingPassID;
+
/// TailDuplicate - Duplicate blocks with unconditional branches
/// into tails of their predecessors.
extern char &TailDuplicateID;
@@ -511,6 +519,8 @@ namespace llvm {
/// IfConverter - This pass performs machine code if conversion.
extern char &IfConverterID;
+ FunctionPass *createIfConverter(std::function<bool(const Function &)> Ftor);
+
/// MachineBlockPlacement - This pass places basic blocks based on branch
/// probabilities.
extern char &MachineBlockPlacementID;
@@ -605,6 +615,9 @@ namespace llvm {
/// UnpackMachineBundles - This pass unpack machine instruction bundles.
extern char &UnpackMachineBundlesID;
+ FunctionPass *
+ createUnpackMachineBundles(std::function<bool(const Function &)> Ftor);
+
/// FinalizeMachineBundles - This pass finalize machine instruction
/// bundles (created earlier, e.g. during pre-RA scheduling).
extern char &FinalizeMachineBundlesID;
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 1196783e820b..b56d5ec8ce63 100644
--- a/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -260,7 +260,7 @@ namespace llvm {
#ifndef NDEBUG
const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0];
#endif
- SUnits.push_back(SUnit(MI, (unsigned)SUnits.size()));
+ SUnits.emplace_back(MI, (unsigned)SUnits.size());
assert((Addr == nullptr || Addr == &SUnits[0]) &&
"SUnits std::vector reallocated on the fly!");
SUnits.back().OrigNode = &SUnits.back();
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 89f9005b8b21..78fdd040773e 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -878,6 +878,10 @@ public:
/// Return an MDNodeSDNode which holds an MDNode.
SDValue getMDNode(const MDNode *MD);
+ /// Return a bitcast using the SDLoc of the value operand, and casting to the
+ /// provided type. Use getNode to set a custom SDLoc.
+ SDValue getBitcast(EVT VT, SDValue V);
+
/// Return an AddrSpaceCastSDNode.
SDValue getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr,
unsigned SrcAS, unsigned DestAS);
diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h
index e2644edd4d12..1cff3203f2bb 100644
--- a/include/llvm/CodeGen/WinEHFuncInfo.h
+++ b/include/llvm/CodeGen/WinEHFuncInfo.h
@@ -23,6 +23,7 @@ class BasicBlock;
class Constant;
class Function;
class GlobalVariable;
+class InvokeInst;
class IntrinsicInst;
class LandingPadInst;
class MCSymbol;
@@ -153,5 +154,11 @@ struct WinEHFuncInfo {
NumIPToStateFuncsVisited(0) {}
};
+/// Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which
+/// describes the state numbers and tables used by __CxxFrameHandler3. This
+/// analysis assumes that WinEHPrepare has already been run.
+void calculateWinCXXEHStateNumbers(const Function *ParentFn,
+ WinEHFuncInfo &FuncInfo);
+
}
#endif // LLVM_CODEGEN_WINEHFUNCINFO_H
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index 67d7c8485a40..211e1d0fad01 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -6,6 +6,9 @@
/* Bug report URL. */
#undef BUG_REPORT_URL
+/* Default OpenMP runtime used by -fopenmp. */
+#undef CLANG_DEFAULT_OPENMP_RUNTIME
+
/* Define if we have libxml2 */
#undef CLANG_HAVE_LIBXML
diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h
index dddc7faa73e8..871e60c56b13 100644
--- a/include/llvm/DebugInfo/DIContext.h
+++ b/include/llvm/DebugInfo/DIContext.h
@@ -141,8 +141,7 @@ private:
/// on the fly.
class LoadedObjectInfo {
public:
- LoadedObjectInfo() {}
- virtual ~LoadedObjectInfo() {}
+ virtual ~LoadedObjectInfo() = default;
/// Obtain the Load Address of a section by Name.
///
@@ -170,7 +169,7 @@ public:
/// Obtain a copy of this LoadedObjectInfo.
///
/// The caller is responsible for deallocation once the copy is no longer required.
- virtual LoadedObjectInfo *clone() const = 0;
+ virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0;
};
}
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index 37b22c2e82f6..93e7c790ccf9 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -38,12 +38,12 @@ public:
// The size in bytes of the statement information for this compilation unit
// (not including the total_length field itself).
- uint32_t TotalLength;
+ uint64_t TotalLength;
// Version identifier for the statement information format.
uint16_t Version;
// The number of bytes following the prologue_length field to the beginning
// of the first byte of the statement program itself.
- uint32_t PrologueLength;
+ uint64_t PrologueLength;
// The size in bytes of the smallest target machine instruction. Statement
// program opcodes that alter the address register first multiply their
// operands by this value.
@@ -63,14 +63,22 @@ public:
std::vector<const char*> IncludeDirectories;
std::vector<FileNameEntry> FileNames;
+ bool IsDWARF64;
+ uint32_t sizeofTotalLength() const {
+ return IsDWARF64 ? 12 : 4;
+ }
+ uint32_t sizeofPrologueLength() const {
+ return IsDWARF64 ? 8 : 4;
+ }
+
// Length of the prologue in bytes.
uint32_t getLength() const {
- return PrologueLength + sizeof(TotalLength) + sizeof(Version) +
- sizeof(PrologueLength);
+ return PrologueLength + sizeofTotalLength() + sizeof(Version) +
+ sizeofPrologueLength();
}
// Length of the line table data in bytes (not including the prologue).
uint32_t getStatementTableLength() const {
- return TotalLength + sizeof(TotalLength) - getLength();
+ return TotalLength + sizeofTotalLength() - getLength();
}
int32_t getMaxLineIncrementForSpecialOpcode() const {
return LineBase + (int8_t)LineRange - 1;
@@ -163,6 +171,9 @@ public:
struct LineTable {
LineTable();
+ // Represents an invalid row
+ const uint32_t UnknownRowIndex = UINT32_MAX;
+
void appendRow(const DWARFDebugLine::Row &R) {
Rows.push_back(R);
}
@@ -171,7 +182,7 @@ public:
}
// Returns the index of the row with file/line info for a given address,
- // or -1 if there is no such row.
+ // or UnknownRowIndex if there is no such row.
uint32_t lookupAddress(uint64_t address) const;
bool lookupAddressRange(uint64_t address, uint64_t size,
@@ -203,6 +214,10 @@ public:
typedef SequenceVector::const_iterator SequenceIter;
RowVector Rows;
SequenceVector Sequences;
+
+ private:
+ uint32_t findRowInSeq(const DWARFDebugLine::Sequence &seq,
+ uint64_t address) const;
};
const LineTable *getLineTable(uint32_t offset) const;
diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 719adbc562c2..074d55e5034e 100644
--- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -390,8 +390,7 @@ public:
for (auto &F : *M) {
if (F.isDeclaration())
continue;
- Partitioning.push_back(std::vector<Function*>());
- Partitioning.back().push_back(&F);
+ Partitioning.emplace_back(1, &F);
}
addLogicalModule(*LogicalDylibs.back(),
std::shared_ptr<Module>(std::move(M)),
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index ac0151aa7ec1..94c4038e8183 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -15,6 +15,7 @@
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
#include "JITSymbolFlags.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Memory.h"
#include "llvm/DebugInfo/DIContext.h"
@@ -62,8 +63,6 @@ public:
unsigned EndIdx)
: RTDyld(RTDyld), BeginIdx(BeginIdx), EndIdx(EndIdx) { }
- virtual ~LoadedObjectInfo() = default;
-
virtual object::OwningBinary<object::ObjectFile>
getObjectForDebug(const object::ObjectFile &Obj) const = 0;
@@ -80,8 +79,8 @@ public:
LoadedObjectInfoHelper(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
unsigned EndIdx)
: LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {}
- llvm::LoadedObjectInfo *clone() const override {
- return new Derived(static_cast<const Derived &>(*this));
+ std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
+ return llvm::make_unique<Derived>(static_cast<const Derived &>(*this));
}
};
diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h
index 15942f16e67e..08b51021116c 100644
--- a/include/llvm/IR/InlineAsm.h
+++ b/include/llvm/IR/InlineAsm.h
@@ -248,6 +248,13 @@ public:
Constraint_R,
Constraint_S,
Constraint_T,
+ Constraint_Um,
+ Constraint_Un,
+ Constraint_Uq,
+ Constraint_Us,
+ Constraint_Ut,
+ Constraint_Uv,
+ Constraint_Uy,
Constraint_X,
Constraint_Z,
Constraint_ZC,
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index 9f5e244f0021..8d8c530d2c6b 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -810,6 +810,7 @@ inline Type *checkGEPType(Type *Ty) {
///
class GetElementPtrInst : public Instruction {
Type *SourceElementType;
+ Type *ResultElementType;
GetElementPtrInst(const GetElementPtrInst &GEPI);
void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
@@ -903,9 +904,12 @@ public:
Type *getSourceElementType() const { return SourceElementType; }
void setSourceElementType(Type *Ty) { SourceElementType = Ty; }
+ void setResultElementType(Type *Ty) { ResultElementType = Ty; }
Type *getResultElementType() const {
- return cast<PointerType>(getType()->getScalarType())->getElementType();
+ assert(ResultElementType ==
+ cast<PointerType>(getType()->getScalarType())->getElementType());
+ return ResultElementType;
}
/// \brief Returns the address space of this instruction's pointer type.
@@ -1028,7 +1032,10 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
: Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr,
OperandTraits<GetElementPtrInst>::op_end(this) - Values,
Values, InsertBefore),
- SourceElementType(PointeeType) {
+ SourceElementType(PointeeType),
+ ResultElementType(getIndexedType(PointeeType, IdxList)) {
+ assert(ResultElementType ==
+ cast<PointerType>(getType()->getScalarType())->getElementType());
init(Ptr, IdxList, NameStr);
}
GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
@@ -1038,7 +1045,10 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
: Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr,
OperandTraits<GetElementPtrInst>::op_end(this) - Values,
Values, InsertAtEnd),
- SourceElementType(PointeeType) {
+ SourceElementType(PointeeType),
+ ResultElementType(getIndexedType(PointeeType, IdxList)) {
+ assert(ResultElementType ==
+ cast<PointerType>(getType()->getScalarType())->getElementType());
init(Ptr, IdxList, NameStr);
}
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index 8f6cdebb0491..beeffde9f65a 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -537,7 +537,8 @@ def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty],
def int_experimental_gc_statepoint : Intrinsic<[llvm_i32_ty],
[llvm_i64_ty, llvm_i32_ty,
llvm_anyptr_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_vararg_ty]>;
+ llvm_i32_ty, llvm_vararg_ty],
+ [Throws]>;
def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_i32_ty]>;
def int_experimental_gc_relocate : Intrinsic<[llvm_anyptr_ty],
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 3a8a4a643a43..0826aa2287e9 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -3372,10 +3372,40 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_avx512_sqrt_pd_512 : GCCBuiltin<"__builtin_ia32_sqrtpd512_mask">,
+ def int_x86_avx512_mask_sqrt_pd_128 : GCCBuiltin<"__builtin_ia32_sqrtpd128_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sqrt_pd_256 : GCCBuiltin<"__builtin_ia32_sqrtpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sqrt_pd_512 : GCCBuiltin<"__builtin_ia32_sqrtpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sqrt_ps_128 : GCCBuiltin<"__builtin_ia32_sqrtps128_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sqrt_ps_256 : GCCBuiltin<"__builtin_ia32_sqrtps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sqrt_ps_512 : GCCBuiltin<"__builtin_ia32_sqrtps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_getexp_pd_128 : GCCBuiltin<"__builtin_ia32_getexppd128_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_getexp_pd_256 : GCCBuiltin<"__builtin_ia32_getexppd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_getexp_pd_512 : GCCBuiltin<"__builtin_ia32_getexppd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_sqrt_ps_512 : GCCBuiltin<"__builtin_ia32_sqrtps512_mask">,
+ def int_x86_avx512_mask_getexp_ps_128 : GCCBuiltin<"__builtin_ia32_getexpps128_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_getexp_ps_256 : GCCBuiltin<"__builtin_ia32_getexpps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_getexp_ps_512 : GCCBuiltin<"__builtin_ia32_getexpps512_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h
index ba14457f7185..ceb1c736e5c7 100644
--- a/include/llvm/IR/MDBuilder.h
+++ b/include/llvm/IR/MDBuilder.h
@@ -153,7 +153,7 @@ public:
/// \brief Return metadata for a TBAA tag node with the given
/// base type, access type and offset relative to the base type.
MDNode *createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType,
- uint64_t Offset);
+ uint64_t Offset, bool IsConstant = false);
};
} // end namespace llvm
diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
index 3bf2943a8980..19a1d6cd91da 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -69,9 +69,8 @@ class Value {
Type *VTy;
Use *UseList;
- friend class ValueAsMetadata; // Allow access to NameAndIsUsedByMD.
+ friend class ValueAsMetadata; // Allow access to IsUsedByMD.
friend class ValueHandleBase;
- PointerIntPair<ValueName *, 1> NameAndIsUsedByMD;
const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast)
unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this?
@@ -101,7 +100,10 @@ protected:
/// This is stored here to save space in User on 64-bit hosts. Since most
/// instances of Value have operands, 32-bit hosts aren't significantly
/// affected.
- unsigned NumOperands;
+ unsigned NumOperands : 30;
+
+ bool IsUsedByMD : 1;
+ bool HasName : 1;
private:
template <typename UseT> // UseT == 'Use' or 'const Use'
@@ -210,9 +212,9 @@ public:
LLVMContext &getContext() const;
// \brief All values can potentially be named.
- bool hasName() const { return getValueName() != nullptr; }
- ValueName *getValueName() const { return NameAndIsUsedByMD.getPointer(); }
- void setValueName(ValueName *VN) { NameAndIsUsedByMD.setPointer(VN); }
+ bool hasName() const { return HasName; }
+ ValueName *getValueName() const;
+ void setValueName(ValueName *VN);
private:
void destroyValueName();
@@ -394,7 +396,7 @@ public:
bool hasValueHandle() const { return HasValueHandle; }
/// \brief Return true if there is metadata referencing this value.
- bool isUsedByMetadata() const { return NameAndIsUsedByMD.getInt(); }
+ bool isUsedByMetadata() const { return IsUsedByMD; }
/// \brief Strip off pointer casts, all-zero GEPs, and aliases.
///
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 497ac55da4b4..4f95c886800f 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -289,6 +289,7 @@ void initializeLoopVectorizePass(PassRegistry&);
void initializeSLPVectorizerPass(PassRegistry&);
void initializeBBVectorizePass(PassRegistry&);
void initializeMachineFunctionPrinterPassPass(PassRegistry&);
+void initializeMIRPrintingPassPass(PassRegistry&);
void initializeStackMapLivenessPass(PassRegistry&);
void initializeMachineCombinerPass(PassRegistry &);
void initializeLoadCombinePass(PassRegistry&);
diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h
index 3b4be81b223c..0c46fc048a43 100644
--- a/include/llvm/LTO/LTOCodeGenerator.h
+++ b/include/llvm/LTO/LTOCodeGenerator.h
@@ -82,7 +82,7 @@ struct LTOCodeGenerator {
void setShouldInternalize(bool Value) { ShouldInternalize = Value; }
void setShouldEmbedUselists(bool Value) { ShouldEmbedUselists = Value; }
- void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; }
+ void addMustPreserveSymbol(StringRef sym) { MustPreserveSymbols[sym] = 1; }
// To pass options to the driver and optimization passes. These options are
// not necessarily for debugging purpose (The function name is misleading).
@@ -117,11 +117,10 @@ struct LTOCodeGenerator {
// (linker), it brings the object to a buffer, and return the buffer to the
// caller. This function should delete intermediate object file once its content
// is brought to memory. Return NULL if the compilation was not successful.
- const void *compile(size_t *length,
- bool disableInline,
- bool disableGVNLoadPRE,
- bool disableVectorization,
- std::string &errMsg);
+ std::unique_ptr<MemoryBuffer> compile(bool disableInline,
+ bool disableGVNLoadPRE,
+ bool disableVectorization,
+ std::string &errMsg);
// Optimizes the merged module. Returns true on success.
bool optimize(bool disableInline,
@@ -132,7 +131,7 @@ struct LTOCodeGenerator {
// Compiles the merged optimized module into a single object file. It brings
// the object to a buffer, and returns the buffer to the caller. Return NULL
// if the compilation was not successful.
- const void *compileOptimized(size_t *length, std::string &errMsg);
+ std::unique_ptr<MemoryBuffer> compileOptimized(std::string &errMsg);
void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
@@ -166,7 +165,6 @@ private:
lto_codegen_model CodeModel = LTO_CODEGEN_PIC_MODEL_DEFAULT;
StringSet MustPreserveSymbols;
StringSet AsmUndefinedRefs;
- std::unique_ptr<MemoryBuffer> NativeObjectFile;
std::vector<char *> CodegenOptions;
std::string MCpu;
std::string MAttr;
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h
index c0a95d48e370..2bfad2d355b8 100644
--- a/include/llvm/MC/MCAsmBackend.h
+++ b/include/llvm/MC/MCAsmBackend.h
@@ -97,6 +97,12 @@ public:
/// Target specific predicate for whether a given fixup requires the
/// associated instruction to be relaxed.
+ virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
+ uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout) const;
+
+ /// Simple predicate for targets where !Resolved implies requiring relaxation
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const = 0;
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 0335f3188fc3..9bb0fa63c523 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -155,6 +155,10 @@ protected:
/// Defaults to false.
bool AllowAtInName;
+ /// If this is true, symbol names with invalid characters will be printed in
+ /// quotes.
+ bool SupportsQuotedNames;
+
/// This is true if data region markers should be printed as
/// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels
/// instead.
@@ -406,6 +410,10 @@ public:
unsigned Encoding,
MCStreamer &Streamer) const;
+ /// Return true if the identifier \p Name does not need quotes to be
+ /// syntactically correct.
+ virtual bool isValidUnquotedName(StringRef Name) const;
+
bool usesSunStyleELFSectionSwitchSyntax() const {
return SunStyleELFSectionSwitchSyntax;
}
@@ -456,6 +464,7 @@ public:
const char *getCode64Directive() const { return Code64Directive; }
unsigned getAssemblerDialect() const { return AssemblerDialect; }
bool doesAllowAtInName() const { return AllowAtInName; }
+ bool supportsNameQuoting() const { return SupportsQuotedNames; }
bool doesSupportDataRegionDirectives() const {
return UseDataRegionDirectives;
}
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index fb28420e0fa3..1b20d5b804a4 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -18,7 +18,6 @@ class MCAssembler;
class MCFragment;
class MCSection;
class MCSymbol;
-class MCSymbolData;
/// Encapsulates the layout of an assembly file at a particular point in time.
///
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 593504ce0607..a6178c214d47 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -12,7 +12,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/ilist.h"
@@ -24,7 +23,6 @@
#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include <algorithm>
@@ -60,7 +58,8 @@ public:
FT_Org,
FT_Dwarf,
FT_DwarfFrame,
- FT_LEB
+ FT_LEB,
+ FT_SafeSEH
};
private:
@@ -531,6 +530,28 @@ public:
}
};
+class MCSafeSEHFragment : public MCFragment {
+ virtual void anchor();
+
+ const MCSymbol *Sym;
+
+public:
+ MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
+ : MCFragment(FT_SafeSEH, Sec), Sym(Sym) {}
+
+ /// \name Accessors
+ /// @{
+
+ const MCSymbol *getSymbol() { return Sym; }
+ const MCSymbol *getSymbol() const { return Sym; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_SafeSEH;
+ }
+};
+
// FIXME: This really doesn't belong here. See comments below.
struct IndirectSymbolData {
MCSymbol *Symbol;
@@ -551,7 +572,7 @@ class MCAssembler {
friend class MCAsmLayout;
public:
- typedef SetVector<MCSection *> SectionListType;
+ typedef std::vector<MCSection *> SectionListType;
typedef std::vector<const MCSymbol *> SymbolDataListType;
typedef pointee_iterator<SectionListType::const_iterator> const_iterator;
@@ -564,9 +585,6 @@ public:
typedef iterator_range<symbol_iterator> symbol_range;
typedef iterator_range<const_symbol_iterator> const_symbol_range;
- typedef std::vector<std::string> FileNameVectorType;
- typedef FileNameVectorType::const_iterator const_file_name_iterator;
-
typedef std::vector<IndirectSymbolData>::const_iterator
const_indirect_symbol_iterator;
typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
@@ -613,7 +631,7 @@ private:
std::vector<std::vector<std::string>> LinkerOptions;
/// List of declared file names
- FileNameVectorType FileNames;
+ std::vector<std::string> FileNames;
/// The set of function symbols for which a .thumb_func directive has
/// been seen.
@@ -883,39 +901,21 @@ public:
/// \name Backend Data Access
/// @{
- bool registerSection(MCSection &Section) { return Sections.insert(&Section); }
-
- bool hasSymbolData(const MCSymbol &Symbol) const { return Symbol.hasData(); }
-
- MCSymbolData &getSymbolData(const MCSymbol &Symbol) {
- return const_cast<MCSymbolData &>(
- static_cast<const MCAssembler &>(*this).getSymbolData(Symbol));
- }
-
- const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
- return Symbol.getData();
- }
-
- MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
- bool *Created = nullptr) {
- if (Created)
- *Created = !hasSymbolData(Symbol);
- if (!hasSymbolData(Symbol)) {
- Symbol.initializeData();
- Symbols.push_back(&Symbol);
- }
- return Symbol.getData();
+ bool registerSection(MCSection &Section) {
+ if (Section.isRegistered())
+ return false;
+ Sections.push_back(&Section);
+ Section.setIsRegistered(true);
+ return true;
}
- const_file_name_iterator file_names_begin() const {
- return FileNames.begin();
- }
+ void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr);
- const_file_name_iterator file_names_end() const { return FileNames.end(); }
+ ArrayRef<std::string> getFileNames() { return FileNames; }
void addFileName(StringRef FileName) {
- if (std::find(file_names_begin(), file_names_end(), FileName) ==
- file_names_end())
+ if (std::find(FileNames.begin(), FileNames.end(), FileName) ==
+ FileNames.end())
FileNames.push_back(FileName);
}
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 5b57b9d448e8..1790905a1245 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -30,6 +30,7 @@ namespace llvm {
class MCExpr;
class MCSection;
class MCSymbol;
+ class MCSymbolELF;
class MCLabel;
struct MCDwarfFile;
class MCDwarfLoc;
@@ -75,7 +76,7 @@ namespace llvm {
/// ELF sections can have a corresponding symbol. This maps one to the
/// other.
- DenseMap<const MCSectionELF *, MCSymbol *> SectionSymbols;
+ DenseMap<const MCSectionELF *, MCSymbolELF *> SectionSymbols;
/// A mapping from a local label number and an instance count to a symbol.
/// For example, in the assembly
@@ -205,7 +206,10 @@ namespace llvm {
/// Do automatic reset in destructor
bool AutoReset;
- MCSymbol *CreateSymbol(StringRef Name, bool AlwaysAddSuffix);
+ MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name,
+ bool IsTemporary);
+ MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix,
+ bool IsTemporary);
MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
unsigned Instance);
@@ -263,7 +267,7 @@ namespace llvm {
/// \param Name - The symbol name, which must be unique across all symbols.
MCSymbol *getOrCreateSymbol(const Twine &Name);
- MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section);
+ MCSymbolELF *getOrCreateSectionSymbol(const MCSectionELF &Section);
/// Gets a symbol that will be defined to the final stack offset of a local
/// variable after codegen.
@@ -340,18 +344,18 @@ namespace llvm {
MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
- const MCSymbol *Group, unsigned UniqueID,
+ const MCSymbolELF *Group, unsigned UniqueID,
const char *BeginSymName,
const MCSectionELF *Associated);
MCSectionELF *createELFRelSection(StringRef Name, unsigned Type,
unsigned Flags, unsigned EntrySize,
- const MCSymbol *Group,
+ const MCSymbolELF *Group,
const MCSectionELF *Associated);
void renameELFSection(MCSectionELF *Section, StringRef Name);
- MCSectionELF *createELFGroupSection(const MCSymbol *Group);
+ MCSectionELF *createELFGroupSection(const MCSymbolELF *Group);
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind, StringRef COMDATSymName,
diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h
deleted file mode 100644
index f409988d5726..000000000000
--- a/include/llvm/MC/MCELF.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains some support functions used by the ELF Streamer and
-// ObjectWriter.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MC_MCELF_H
-#define LLVM_MC_MCELF_H
-
-namespace llvm {
-class MCSymbolData;
-
-class MCELF {
- public:
- static void SetBinding(MCSymbolData &SD, unsigned Binding);
- static unsigned GetBinding(const MCSymbolData &SD);
- static void SetType(MCSymbolData &SD, unsigned Type);
- static unsigned GetType(const MCSymbolData &SD);
- static void SetVisibility(MCSymbolData &SD, unsigned Visibility);
- static unsigned GetVisibility(const MCSymbolData &SD);
- static void setOther(MCSymbolData &SD, unsigned Other);
- static unsigned getOther(const MCSymbolData &SD);
-};
-
-}
-
-#endif
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index cf73eca340d7..01f694d3b756 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -21,17 +21,17 @@ class MCFixup;
class MCFragment;
class MCObjectWriter;
class MCSymbol;
-class MCSymbolData;
+class MCSymbolELF;
class MCValue;
class raw_pwrite_stream;
struct ELFRelocationEntry {
uint64_t Offset; // Where is the relocation.
- const MCSymbol *Symbol; // The symbol to relocate with.
+ const MCSymbolELF *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,
+ ELFRelocationEntry(uint64_t Offset, const MCSymbolELF *Symbol, unsigned Type,
uint64_t Addend)
: Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {}
};
@@ -69,7 +69,7 @@ public:
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel) const = 0;
- virtual bool needsRelocateWithSymbol(const MCSymbolData &SD,
+ virtual bool needsRelocateWithSymbol(const MCSymbol &Sym,
unsigned Type) const;
virtual void sortRelocs(const MCAssembler &Asm,
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
index 97058f5e9981..241db0dc9cde 100644
--- a/include/llvm/MC/MCELFStreamer.h
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -23,8 +23,6 @@ class MCAssembler;
class MCCodeEmitter;
class MCExpr;
class MCInst;
-class MCSymbol;
-class MCSymbolData;
class raw_ostream;
class MCELFStreamer : public MCObjectStreamer {
@@ -39,7 +37,6 @@ public:
void reset() override {
SeenIdent = false;
LocalCommons.clear();
- BindingExplicitlySet.clear();
BundleGroups.clear();
MCObjectStreamer::reset();
}
@@ -62,7 +59,7 @@ public:
void EmitCOFFSymbolType(int Type) override;
void EndCOFFSymbolDef() override;
- void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
+ void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) override;
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
@@ -108,8 +105,6 @@ private:
std::vector<LocalCommon> LocalCommons;
- SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
-
/// BundleGroups - The stack of fragments holding the bundle-locked
/// instructions.
llvm::SmallVector<MCDataFragment *, 4> BundleGroups;
diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h
deleted file mode 100644
index 297c44269a8f..000000000000
--- a/include/llvm/MC/MCELFSymbolFlags.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===- MCELFSymbolFlags.h - ELF Symbol Flags ----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the SymbolFlags used for the ELF target.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MC_MCELFSYMBOLFLAGS_H
-#define LLVM_MC_MCELFSYMBOLFLAGS_H
-
-#include "llvm/Support/ELF.h"
-
-// Because all the symbol flags need to be stored in the MCSymbolData
-// 'flags' variable we need to provide shift constants per flag type.
-
-namespace llvm {
- enum {
- ELF_STT_Shift = 0, // Shift value for STT_* flags.
- ELF_STB_Shift = 4, // Shift value for STB_* flags.
- ELF_STV_Shift = 8, // Shift value for STV_* flags.
- ELF_STO_Shift = 10 // Shift value for STO_* flags.
- };
-
- enum ELFSymbolFlags {
- ELF_STB_Local = (ELF::STB_LOCAL << ELF_STB_Shift),
- ELF_STB_Global = (ELF::STB_GLOBAL << ELF_STB_Shift),
- ELF_STB_Weak = (ELF::STB_WEAK << ELF_STB_Shift),
- ELF_STB_Loproc = (ELF::STB_LOPROC << ELF_STB_Shift),
- ELF_STB_Hiproc = (ELF::STB_HIPROC << ELF_STB_Shift),
-
- ELF_STT_Notype = (ELF::STT_NOTYPE << ELF_STT_Shift),
- ELF_STT_Object = (ELF::STT_OBJECT << ELF_STT_Shift),
- ELF_STT_Func = (ELF::STT_FUNC << ELF_STT_Shift),
- ELF_STT_Section = (ELF::STT_SECTION << ELF_STT_Shift),
- ELF_STT_File = (ELF::STT_FILE << ELF_STT_Shift),
- ELF_STT_Common = (ELF::STT_COMMON << ELF_STT_Shift),
- ELF_STT_Tls = (ELF::STT_TLS << ELF_STT_Shift),
- ELF_STT_GnuIFunc = (ELF::STT_GNU_IFUNC << ELF_STT_Shift),
- ELF_STT_Loproc = (ELF::STT_LOPROC << ELF_STT_Shift),
- ELF_STT_Hiproc = (ELF::STT_HIPROC << ELF_STT_Shift),
-
- ELF_STV_Default = (ELF::STV_DEFAULT << ELF_STV_Shift),
- ELF_STV_Internal = (ELF::STV_INTERNAL << ELF_STV_Shift),
- ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift),
- ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift)
- };
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index b38ad7daee3e..b3a607351a82 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -46,7 +46,7 @@ private:
MCExpr(const MCExpr&) = delete;
void operator=(const MCExpr&) = delete;
- bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
+ bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const SectionAddrMap *Addrs) const;
@@ -57,7 +57,7 @@ private:
protected:
explicit MCExpr(ExprKind Kind) : Kind(Kind) {}
- bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
+ bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const MCFixup *Fixup,
const SectionAddrMap *Addrs, bool InSet) const;
@@ -72,7 +72,7 @@ public:
/// \name Utility Methods
/// @{
- void print(raw_ostream &OS) const;
+ void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
void dump() const;
/// @}
@@ -86,11 +86,11 @@ public:
/// values. If not given, then only non-symbolic expressions will be
/// evaluated.
/// \return - True on success.
- bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
+ bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
const SectionAddrMap &Addrs) const;
- bool EvaluateAsAbsolute(int64_t &Res) const;
- bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
- bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
+ bool evaluateAsAbsolute(int64_t &Res) const;
+ bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
+ bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
@@ -101,13 +101,13 @@ public:
/// \param Layout - The assembler layout object to use for evaluating values.
/// \param Fixup - The Fixup object if available.
/// \return - True on success.
- bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout,
+ bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout,
const MCFixup *Fixup) const;
/// \brief Try to evaluate the expression to the form (a - b + constant) where
/// neither a nor b are variables.
///
- /// This is a more aggressive variant of EvaluateAsRelocatable. The intended
+ /// This is a more aggressive variant of evaluateAsRelocatable. The intended
/// use is for when relocations are not available, like the .size directive.
bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const;
@@ -115,13 +115,13 @@ public:
/// currently defined as the absolute section for constants, or
/// otherwise the section associated with the first defined symbol in the
/// expression.
- MCSection *FindAssociatedSection() const;
+ MCSection *findAssociatedSection() const;
/// @}
};
inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
- E.print(OS);
+ E.print(OS, nullptr);
return OS;
}
@@ -136,7 +136,7 @@ public:
/// \name Construction
/// @{
- static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx);
+ static const MCConstantExpr *create(int64_t Value, MCContext &Ctx);
/// @}
/// \name Accessors
@@ -312,13 +312,13 @@ public:
/// \name Construction
/// @{
- static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) {
- return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx);
+ static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) {
+ return MCSymbolRefExpr::create(Symbol, VK_None, Ctx);
}
- static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind,
+ static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind,
MCContext &Ctx);
- static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind,
+ static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind,
MCContext &Ctx);
/// @}
@@ -369,19 +369,19 @@ public:
/// \name Construction
/// @{
- static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr,
+ static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr,
MCContext &Ctx);
- static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) {
- return Create(LNot, Expr, Ctx);
+ static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx) {
+ return create(LNot, Expr, Ctx);
}
- static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) {
- return Create(Minus, Expr, Ctx);
+ static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx) {
+ return create(Minus, Expr, Ctx);
}
- static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) {
- return Create(Not, Expr, Ctx);
+ static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx) {
+ return create(Not, Expr, Ctx);
}
- static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) {
- return Create(Plus, Expr, Ctx);
+ static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx) {
+ return create(Plus, Expr, Ctx);
}
/// @}
@@ -441,83 +441,83 @@ public:
/// \name Construction
/// @{
- static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS,
+ static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS,
const MCExpr *RHS, MCContext &Ctx);
- static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(Add, LHS, RHS, Ctx);
+ return create(Add, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(And, LHS, RHS, Ctx);
+ return create(And, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(Div, LHS, RHS, Ctx);
+ return create(Div, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(EQ, LHS, RHS, Ctx);
+ return create(EQ, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(GT, LHS, RHS, Ctx);
+ return create(GT, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(GTE, LHS, RHS, Ctx);
+ return create(GTE, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(LAnd, LHS, RHS, Ctx);
+ return create(LAnd, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(LOr, LHS, RHS, Ctx);
+ return create(LOr, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(LT, LHS, RHS, Ctx);
+ return create(LT, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(LTE, LHS, RHS, Ctx);
+ return create(LTE, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(Mod, LHS, RHS, Ctx);
+ return create(Mod, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(Mul, LHS, RHS, Ctx);
+ return create(Mul, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(NE, LHS, RHS, Ctx);
+ return create(NE, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(Or, LHS, RHS, Ctx);
+ return create(Or, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(Shl, LHS, RHS, Ctx);
+ return create(Shl, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateAShr(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(AShr, LHS, RHS, Ctx);
+ return create(AShr, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateLShr(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(LShr, LHS, RHS, Ctx);
+ return create(LShr, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(Sub, LHS, RHS, Ctx);
+ return create(Sub, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(Xor, LHS, RHS, Ctx);
+ return create(Xor, LHS, RHS, Ctx);
}
/// @}
@@ -551,13 +551,12 @@ protected:
MCTargetExpr() : MCExpr(Target) {}
virtual ~MCTargetExpr() {}
public:
-
- virtual void PrintImpl(raw_ostream &OS) const = 0;
- virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
+ virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0;
+ virtual bool evaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout,
const MCFixup *Fixup) const = 0;
virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
- virtual MCSection *FindAssociatedSection() const = 0;
+ virtual MCSection *findAssociatedSection() const = 0;
virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h
index 2fc509148403..4688b5f2b6e9 100644
--- a/include/llvm/MC/MCInst.h
+++ b/include/llvm/MC/MCInst.h
@@ -32,12 +32,12 @@ class MCInst;
/// This is a simple discriminated union.
class MCOperand {
enum MachineOperandType : unsigned char {
- kInvalid, ///< Uninitialized.
- kRegister, ///< Register operand.
- kImmediate, ///< Immediate operand.
- kFPImmediate, ///< Floating-point immediate operand.
- kExpr, ///< Relocatable immediate operand.
- kInst ///< Sub-instruction operand.
+ kInvalid, ///< Uninitialized.
+ kRegister, ///< Register operand.
+ kImmediate, ///< Immediate operand.
+ kFPImmediate, ///< Floating-point immediate operand.
+ kExpr, ///< Relocatable immediate operand.
+ kInst ///< Sub-instruction operand.
};
MachineOperandType Kind;
@@ -48,8 +48,8 @@ class MCOperand {
const MCExpr *ExprVal;
const MCInst *InstVal;
};
-public:
+public:
MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
bool isValid() const { return Kind != kInvalid; }
@@ -151,6 +151,7 @@ class MCInst {
unsigned Opcode;
SMLoc Loc;
SmallVector<MCOperand, 8> Operands;
+
public:
MCInst() : Opcode(0) {}
@@ -164,18 +165,16 @@ public:
MCOperand &getOperand(unsigned i) { return Operands[i]; }
unsigned getNumOperands() const { return Operands.size(); }
- void addOperand(const MCOperand &Op) {
- Operands.push_back(Op);
- }
-
- void clear() { Operands.clear(); }
- size_t size() const { return Operands.size(); }
+ void addOperand(const MCOperand &Op) { Operands.push_back(Op); }
typedef SmallVectorImpl<MCOperand>::iterator iterator;
typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator;
+ void clear() { Operands.clear(); }
+ void erase(iterator I) { Operands.erase(I); }
+ size_t size() const { return Operands.size(); }
iterator begin() { return Operands.begin(); }
const_iterator begin() const { return Operands.begin(); }
- iterator end() { return Operands.end(); }
+ iterator end() { return Operands.end(); }
const_iterator end() const { return Operands.end(); }
iterator insert(iterator I, const MCOperand &Op) {
return Operands.insert(I, Op);
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
index 7e8563a195d0..0eafd02c51c6 100644
--- a/include/llvm/MC/MCInstPrinter.h
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -10,6 +10,7 @@
#ifndef LLVM_MC_MCINSTPRINTER_H
#define LLVM_MC_MCINSTPRINTER_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Format.h"
@@ -22,11 +23,14 @@ class MCRegisterInfo;
class MCSubtargetInfo;
class StringRef;
+/// Convert `Bytes' to a hex string and output to `OS'
+void dumpBytes(ArrayRef<uint8_t> Bytes, raw_ostream &OS);
+
namespace HexStyle {
- enum Style {
- C, ///< 0xff
- Asm ///< 0ffh
- };
+enum Style {
+ C, ///< 0xff
+ Asm ///< 0ffh
+};
}
/// \brief This is an instance of a target assembly language printer that
@@ -52,12 +56,12 @@ protected:
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
+
public:
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
const MCRegisterInfo &mri)
- : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri),
- UseMarkup(0), PrintImmHex(0),
- PrintHexStyle(HexStyle::C) {}
+ : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri), UseMarkup(0),
+ PrintImmHex(0), PrintHexStyle(HexStyle::C) {}
virtual ~MCInstPrinter();
@@ -65,8 +69,8 @@ public:
void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
/// \brief Print the specified MCInst to the specified raw_ostream.
- virtual void printInst(const MCInst *MI, raw_ostream &OS,
- StringRef Annot, const MCSubtargetInfo &STI) = 0;
+ virtual void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot,
+ const MCSubtargetInfo &STI) = 0;
/// \brief Return the name of the specified opcode enum (e.g. "MOV32ri") or
/// empty if we can't resolve it.
@@ -85,8 +89,8 @@ public:
bool getPrintImmHex() const { return PrintImmHex; }
void setPrintImmHex(bool Value) { PrintImmHex = Value; }
- HexStyle::Style getPrintHexStyleHex() const { return PrintHexStyle; }
- void setPrintImmHex(HexStyle::Style Value) { PrintHexStyle = Value; }
+ HexStyle::Style getPrintHexStyle() const { return PrintHexStyle; }
+ void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; }
/// Utility function to print immediates in decimal or hex.
format_object<int64_t> formatImm(int64_t Value) const {
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index de3a1959e05c..3209a2ce0408 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -125,7 +125,8 @@ enum Flag {
ExtraDefRegAllocReq,
RegSequence,
ExtractSubreg,
- InsertSubreg
+ InsertSubreg,
+ Convergent
};
}
@@ -138,10 +139,10 @@ class MCInstrDesc {
public:
unsigned short Opcode; // The opcode number
unsigned short NumOperands; // Num of args (may be more if variable_ops)
- unsigned short NumDefs; // Num of args that are definitions
+ unsigned char NumDefs; // Num of args that are definitions
+ unsigned char Size; // Number of bytes in encoding.
unsigned short SchedClass; // enum identifying instr sched class
- unsigned short Size; // Number of bytes in encoding.
- unsigned Flags; // Flags identifying machine instr class
+ uint64_t Flags; // Flags identifying machine instr class
uint64_t TSFlags; // Target Specific Flag values
const uint16_t *ImplicitUses; // Registers implicitly read by this instr
const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr
@@ -331,6 +332,13 @@ public:
/// override accordingly.
bool isInsertSubregLike() const { return Flags & (1 << MCID::InsertSubreg); }
+
+ /// \brief Return true if this instruction is convergent.
+ ///
+ /// Convergent instructions may only be moved to locations that are
+ /// control-equivalent to their original positions.
+ bool isConvergent() const { return Flags & (1 << MCID::Convergent); }
+
//===--------------------------------------------------------------------===//
// Side Effect Analysis
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h
index de2d0af1423a..a12473fdad02 100644
--- a/include/llvm/MC/MCLabel.h
+++ b/include/llvm/MC/MCLabel.h
@@ -17,41 +17,41 @@
#include "llvm/Support/Compiler.h"
namespace llvm {
- class MCContext;
- class raw_ostream;
-
- /// \brief Instances of this class represent a label name in the MC file,
- /// and MCLabel are created and uniqued by the MCContext class. MCLabel
- /// should only be constructed for valid instances in the object file.
- class MCLabel {
- // \brief The instance number of this Directional Local Label.
- unsigned Instance;
-
- private: // MCContext creates and uniques these.
- friend class MCContext;
- MCLabel(unsigned instance)
- : Instance(instance) {}
-
- MCLabel(const MCLabel&) = delete;
- void operator=(const MCLabel&) = delete;
- public:
- /// \brief Get the current instance of this Directional Local Label.
- unsigned getInstance() const { return Instance; }
-
- /// \brief Increment the current instance of this Directional Local Label.
- unsigned incInstance() { return ++Instance; }
-
- /// \brief Print the value to the stream \p OS.
- void print(raw_ostream &OS) const;
-
- /// \brief Print the value to stderr.
- void dump() const;
- };
-
- inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) {
- Label.print(OS);
- return OS;
- }
+class MCContext;
+class raw_ostream;
+
+/// \brief Instances of this class represent a label name in the MC file,
+/// and MCLabel are created and uniqued by the MCContext class. MCLabel
+/// should only be constructed for valid instances in the object file.
+class MCLabel {
+ // \brief The instance number of this Directional Local Label.
+ unsigned Instance;
+
+private: // MCContext creates and uniques these.
+ friend class MCContext;
+ MCLabel(unsigned instance) : Instance(instance) {}
+
+ MCLabel(const MCLabel &) = delete;
+ void operator=(const MCLabel &) = delete;
+
+public:
+ /// \brief Get the current instance of this Directional Local Label.
+ unsigned getInstance() const { return Instance; }
+
+ /// \brief Increment the current instance of this Directional Local Label.
+ unsigned incInstance() { return ++Instance; }
+
+ /// \brief Print the value to the stream \p OS.
+ void print(raw_ostream &OS) const;
+
+ /// \brief Print the value to stderr.
+ void dump() const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) {
+ Label.print(OS);
+ return OS;
+}
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h
index a186a14b8001..4b6f7ecc9fba 100644
--- a/include/llvm/MC/MCLinkerOptimizationHint.h
+++ b/include/llvm/MC/MCLinkerOptimizationHint.h
@@ -106,7 +106,7 @@ class MCLOHDirective {
/// Emit this directive in \p OutStream using the information available
/// in the given \p ObjWriter and \p Layout to get the address of the
/// arguments within the object file.
- void Emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,
+ void emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,
const MCAsmLayout &Layout) const;
public:
@@ -123,9 +123,9 @@ public:
/// Emit this directive as:
/// <kind, numArgs, addr1, ..., addrN>
- void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
+ void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
raw_ostream &OutStream = ObjWriter.getStream();
- Emit_impl(OutStream, ObjWriter, Layout);
+ emit_impl(OutStream, ObjWriter, Layout);
}
/// Get the size in bytes of this directive if emitted in \p ObjWriter with
@@ -145,7 +145,7 @@ public:
};
raw_counting_ostream OutStream;
- Emit_impl(OutStream, ObjWriter, Layout);
+ emit_impl(OutStream, ObjWriter, Layout);
return OutStream.tell();
}
};
@@ -184,10 +184,10 @@ public:
}
/// Emit all Linker Optimization Hint in one big table.
- /// Each line of the table is emitted by LOHDirective::Emit.
- void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
+ /// Each line of the table is emitted by LOHDirective::emit.
+ void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
for (const MCLOHDirective &D : Directives)
- D.Emit(ObjWriter, Layout);
+ D.emit(ObjWriter, Layout);
}
void reset() {
diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h
deleted file mode 100644
index 71f01fab2064..000000000000
--- a/include/llvm/MC/MCMachOSymbolFlags.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===- MCMachOSymbolFlags.h - MachO Symbol Flags ----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the SymbolFlags used for the MachO target.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MC_MCMACHOSYMBOLFLAGS_H
-#define LLVM_MC_MCMACHOSYMBOLFLAGS_H
-
-// These flags are mostly used in MCMachOStreamer.cpp but also needed in
-// MachObjectWriter.cpp to test for Weak Definitions of symbols to emit
-// the correct relocation information.
-
-namespace llvm {
- /// MachOSymbolFlags - We store the value for the 'desc' symbol field in the
- /// lowest 16 bits of the implementation defined flags.
- enum MachOSymbolFlags { // See <mach-o/nlist.h>.
- SF_DescFlagsMask = 0xFFFF,
-
- // Reference type flags.
- SF_ReferenceTypeMask = 0x0007,
- SF_ReferenceTypeUndefinedNonLazy = 0x0000,
- SF_ReferenceTypeUndefinedLazy = 0x0001,
- SF_ReferenceTypeDefined = 0x0002,
- SF_ReferenceTypePrivateDefined = 0x0003,
- SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
- SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
-
- // Other 'desc' flags.
- SF_ThumbFunc = 0x0008,
- SF_NoDeadStrip = 0x0020,
- SF_WeakReference = 0x0040,
- SF_WeakDefinition = 0x0080,
- SF_SymbolResolver = 0x0100
- };
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index 63c2a28a7c9c..175d73e72c10 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -27,15 +27,11 @@ class MCMachObjectTargetWriter {
const unsigned Is64Bit : 1;
const uint32_t CPUType;
const uint32_t CPUSubtype;
- // FIXME: Remove this, we should just always use it once we no longer care
- // about Darwin 'as' compatibility.
- const unsigned UseAggressiveSymbolFolding : 1;
unsigned LocalDifference_RIT;
protected:
MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_,
- uint32_t CPUSubtype_,
- bool UseAggressiveSymbolFolding_ = false);
+ uint32_t CPUSubtype_);
void setLocalDifferenceRelocationType(unsigned Type) {
LocalDifference_RIT = Type;
@@ -47,7 +43,7 @@ public:
/// \name Lifetime Management
/// @{
- virtual void reset() {};
+ virtual void reset() {}
/// @}
@@ -55,7 +51,6 @@ public:
/// @{
bool is64Bit() const { return Is64Bit; }
- bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; }
uint32_t getCPUType() const { return CPUType; }
uint32_t getCPUSubtype() const { return CPUSubtype; }
unsigned getLocalDifferenceRelocationType() const {
@@ -67,7 +62,7 @@ public:
/// \name API
/// @{
- virtual void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
+ virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
@@ -77,8 +72,7 @@ public:
};
class MachObjectWriter : public MCObjectWriter {
- /// MachSymbolData - Helper struct for containing some precomputed information
- /// on symbols.
+ /// Helper struct for containing some precomputed information on symbols.
struct MachSymbolData {
const MCSymbol *Symbol;
uint64_t StringIndex;
@@ -104,6 +98,8 @@ class MachObjectWriter : public MCObjectWriter {
llvm::DenseMap<const MCSection *, std::vector<RelAndSymbol>> Relocations;
llvm::DenseMap<const MCSection *, unsigned> IndirectSymBase;
+ SectionAddrMap SectionAddress;
+
/// @}
/// \name Symbol Table Data
/// @{
@@ -136,8 +132,6 @@ public:
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
- SectionAddrMap SectionAddress;
-
SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
uint64_t getSectionAddress(const MCSection *Sec) const {
@@ -165,41 +159,37 @@ public:
/// @}
- void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
+ void writeHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
bool SubsectionsViaSymbols);
- /// WriteSegmentLoadCommand - Write a segment load command.
+ /// Write a segment load command.
///
/// \param NumSections The number of sections in this segment.
/// \param SectionDataSize The total size of the sections.
- void WriteSegmentLoadCommand(unsigned NumSections,
- uint64_t VMSize,
+ void writeSegmentLoadCommand(unsigned NumSections, uint64_t VMSize,
uint64_t SectionDataStartOffset,
uint64_t SectionDataSize);
- void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ void writeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCSection &Sec, uint64_t FileOffset,
uint64_t RelocationsStart, unsigned NumRelocations);
- void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
+ void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
uint32_t StringTableOffset,
uint32_t StringTableSize);
- void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
- uint32_t NumLocalSymbols,
- uint32_t FirstExternalSymbol,
- uint32_t NumExternalSymbols,
- uint32_t FirstUndefinedSymbol,
- uint32_t NumUndefinedSymbols,
- uint32_t IndirectSymbolOffset,
- uint32_t NumIndirectSymbols);
+ void writeDysymtabLoadCommand(
+ uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols,
+ uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols,
+ uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols,
+ uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols);
- void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
+ void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
- void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
+ void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
uint32_t DataSize);
- void WriteLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
+ void writeLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
// FIXME: We really need to improve the relocation validation. Basically, we
// want to implement a separate computation which evaluates the relocation
@@ -226,29 +216,25 @@ public:
Relocations[Sec].push_back(P);
}
- void RecordScatteredRelocation(const MCAssembler &Asm,
+ void recordScatteredRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
- unsigned Log2Size,
- uint64_t &FixedValue);
+ unsigned Log2Size, uint64_t &FixedValue);
- void RecordTLVPRelocation(const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFragment *Fragment,
- const MCFixup &Fixup, MCValue Target,
- uint64_t &FixedValue);
+ void recordTLVPRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue);
- void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
+ void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, bool &IsPCRel,
uint64_t &FixedValue) override;
- void BindIndirectSymbols(MCAssembler &Asm);
+ void bindIndirectSymbols(MCAssembler &Asm);
- /// ComputeSymbolTable - Compute the symbol table data
- ///
- void ComputeSymbolTable(MCAssembler &Asm,
+ /// Compute the symbol table data.
+ void computeSymbolTable(MCAssembler &Asm,
std::vector<MachSymbolData> &LocalSymbolData,
std::vector<MachSymbolData> &ExternalSymbolData,
std::vector<MachSymbolData> &UndefinedSymbolData);
@@ -256,19 +242,18 @@ public:
void computeSectionAddresses(const MCAssembler &Asm,
const MCAsmLayout &Layout);
- void ExecutePostLayoutBinding(MCAssembler &Asm,
+ void executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) override;
- bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbol &SymA,
const MCFragment &FB, bool InSet,
bool IsPCRel) const override;
- void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
+ void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
};
-
-/// \brief Construct a new Mach-O writer instance.
+/// Construct a new Mach-O writer instance.
///
/// This routine takes ownership of the target writer subclass.
///
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index f28b9c668cdc..0515f1cd738d 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -18,28 +18,25 @@
#include "llvm/Support/CodeGen.h"
namespace llvm {
- class MCContext;
- class MCSection;
- class StringRef;
+class MCContext;
+class MCSection;
+class StringRef;
class MCObjectFileInfo {
protected:
- /// CommDirectiveSupportsAlignment - True if .comm supports alignment. This
- /// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't
- /// support alignment on comm.
+ /// True if .comm supports alignment. This is a hack for as long as we
+ /// support 10.4 Tiger, whose assembler doesn't support alignment on comm.
bool CommDirectiveSupportsAlignment;
- /// SupportsWeakEmptyEHFrame - True if target object file supports a
- /// weak_definition of constant 0 for an omitted EH frame.
+ /// True if target object file supports a weak_definition of constant 0 for an
+ /// omitted EH frame.
bool SupportsWeakOmittedEHFrame;
- /// SupportsCompactUnwindWithoutEHFrame - True if the target object file
- /// supports emitting a compact unwind section without an associated EH frame
- /// section.
+ /// True if the target object file supports emitting a compact unwind section
+ /// without an associated EH frame section.
bool SupportsCompactUnwindWithoutEHFrame;
- /// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values
- /// for EH.
+ /// Some encoding values for EH.
unsigned PersonalityEncoding;
unsigned LSDAEncoding;
unsigned FDECFIEncoding;
@@ -49,16 +46,13 @@ protected:
unsigned EHSectionType;
unsigned EHSectionFlags;
- /// CompactUnwindDwarfEHFrameOnly - Compact unwind encoding indicating that we
- /// should emit only an EH frame.
+ /// Compact unwind encoding indicating that we should emit only an EH frame.
unsigned CompactUnwindDwarfEHFrameOnly;
/// Section directive for standard text.
- ///
MCSection *TextSection;
/// Section directive for standard data.
- ///
MCSection *DataSection;
/// Section that is default initialized to zero.
@@ -101,7 +95,7 @@ protected:
// can be enabled by a compiler flag.
MCSection *DwarfPubNamesSection;
- // DWARF5 Experimental Debug Info Sections
+ /// DWARF5 Experimental Debug Info Sections
/// DwarfAccelNamesSection, DwarfAccelObjCSection,
/// DwarfAccelNamespaceSection, DwarfAccelTypesSection -
/// If we use the DWARF accelerated hash tables then we want to emit these
@@ -111,7 +105,7 @@ protected:
MCSection *DwarfAccelNamespaceSection;
MCSection *DwarfAccelTypesSection;
- /// These are used for the Fission separate debug information files.
+ // These are used for the Fission separate debug information files.
MCSection *DwarfInfoDWOSection;
MCSection *DwarfTypesDWOSection;
MCSection *DwarfAbbrevDWOSection;
@@ -121,32 +115,36 @@ protected:
MCSection *DwarfStrOffDWOSection;
MCSection *DwarfAddrSection;
- /// Sections for newer gnu pubnames and pubtypes.
+ /// Section for newer gnu pubnames.
MCSection *DwarfGnuPubNamesSection;
+ /// Section for newer gnu pubtypes.
MCSection *DwarfGnuPubTypesSection;
MCSection *COFFDebugSymbolsSection;
- // Extra TLS Variable Data section. If the target needs to put additional
- // information for a TLS variable, it'll go here.
+ /// Extra TLS Variable Data section.
+ ///
+ /// If the target needs to put additional information for a TLS variable,
+ /// it'll go here.
MCSection *TLSExtraDataSection;
/// Section directive for Thread Local data. ELF, MachO and COFF.
MCSection *TLSDataSection; // Defaults to ".tdata".
- /// Section directive for Thread Local uninitialized data. Null if this target
- /// doesn't support a BSS section. ELF and MachO only.
+ /// Section directive for Thread Local uninitialized data.
+ ///
+ /// Null if this target doesn't support a BSS section. ELF and MachO only.
MCSection *TLSBSSSection; // Defaults to ".tbss".
/// StackMap section.
MCSection *StackMapSection;
- /// EH frame section. It is initialized on demand so it can be overwritten
- /// (with uniquing).
+ /// EH frame section.
+ ///
+ /// It is initialized on demand so it can be overwritten (with uniquing).
MCSection *EHFrameSection;
- /// ELF specific sections.
- ///
+ // ELF specific sections.
MCSection *DataRelSection;
const MCSection *DataRelLocalSection;
MCSection *DataRelROSection;
@@ -155,17 +153,16 @@ protected:
MCSection *MergeableConst8Section;
MCSection *MergeableConst16Section;
- /// MachO specific sections.
- ///
+ // MachO specific sections.
- /// Section for thread local structure information. Contains the source code
- /// name of the variable, visibility and a pointer to the initial value
- /// (.tdata or .tbss).
+ /// Section for thread local structure information.
+ ///
+ /// Contains the source code name of the variable, visibility and a pointer to
+ /// the initial value (.tdata or .tbss).
MCSection *TLSTLVSection; // Defaults to ".tlv".
- /// TLSThreadInitSection - Section for thread local data initialization
- /// functions.
- const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func".
+ /// Section for thread local data initialization functions.
+ const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func".
MCSection *CStringSection;
MCSection *UStringSection;
@@ -182,10 +179,10 @@ protected:
MCSection *NonLazySymbolPointerSection;
/// COFF specific sections.
- ///
MCSection *DrectveSection;
MCSection *PDataSection;
MCSection *XDataSection;
+ MCSection *SXDataSection;
public:
void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
@@ -266,8 +263,7 @@ public:
MCSection *getStackMapSection() const { return StackMapSection; }
- /// ELF specific sections.
- ///
+ // ELF specific sections.
MCSection *getDataRelSection() const { return DataRelSection; }
const MCSection *getDataRelLocalSection() const {
return DataRelLocalSection;
@@ -284,8 +280,7 @@ public:
return MergeableConst16Section;
}
- /// MachO specific sections.
- ///
+ // MachO specific sections.
const MCSection *getTLSTLVSection() const { return TLSTLVSection; }
const MCSection *getTLSThreadInitSection() const {
return TLSThreadInitSection;
@@ -316,11 +311,11 @@ public:
return NonLazySymbolPointerSection;
}
- /// COFF specific sections.
- ///
+ // COFF specific sections.
MCSection *getDrectveSection() const { return DrectveSection; }
MCSection *getPDataSection() const { return PDataSection; }
MCSection *getXDataSection() const { return XDataSection; }
+ MCSection *getSXDataSection() const { return SXDataSection; }
MCSection *getEHFrameSection() {
if (!EHFrameSection)
@@ -329,13 +324,9 @@ public:
}
enum Environment { IsMachO, IsELF, IsCOFF };
- Environment getObjectFileType() const {
- return Env;
- }
+ Environment getObjectFileType() const { return Env; }
- Reloc::Model getRelocM() const {
- return RelocM;
- }
+ Reloc::Model getRelocM() const { return RelocM; }
private:
Environment Env;
@@ -344,12 +335,11 @@ private:
MCContext *Ctx;
Triple TT;
- void InitMachOMCObjectFileInfo(Triple T);
- void InitELFMCObjectFileInfo(Triple T);
- void InitCOFFMCObjectFileInfo(Triple T);
+ void initMachOMCObjectFileInfo(Triple T);
+ void initELFMCObjectFileInfo(Triple T);
+ void initCOFFMCObjectFileInfo(Triple T);
- /// InitEHFrameSection - Initialize EHFrameSection on demand.
- ///
+ /// Initialize EHFrameSection on demand.
void InitEHFrameSection();
public:
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index e75bc86cc131..462b3b484c58 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -35,11 +35,10 @@ class raw_pwrite_stream;
/// implementation.
class MCObjectStreamer : public MCStreamer {
MCAssembler *Assembler;
- MCSection *CurSectionData;
MCSection::iterator CurInsertionPoint;
bool EmitEHFrame;
bool EmitDebugFrame;
- SmallVector<MCSymbolData *, 2> PendingLabels;
+ SmallVector<MCSymbol *, 2> PendingLabels;
virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
@@ -57,21 +56,17 @@ public:
/// Object streamers require the integrated assembler.
bool isIntegratedAssemblerRequired() const override { return true; }
- MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) {
- return getAssembler().getOrCreateSymbolData(*Symbol);
- }
void EmitFrames(MCAsmBackend *MAB);
void EmitCFISections(bool EH, bool Debug) override;
protected:
- MCSection *getCurrentSectionData() const { return CurSectionData; }
-
MCFragment *getCurrentFragment() const;
void insert(MCFragment *F) {
flushPendingLabels(F);
- CurSectionData->getFragmentList().insert(CurInsertionPoint, F);
- F->setParent(CurSectionData);
+ MCSection *CurSection = getCurrentSectionOnly();
+ CurSection->getFragmentList().insert(CurInsertionPoint, F);
+ F->setParent(CurSection);
}
/// Get a data fragment to write into, creating a new one if the current
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 999d29471270..2211673efc31 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -22,18 +22,17 @@ class MCAsmLayout;
class MCAssembler;
class MCFixup;
class MCFragment;
-class MCSymbolData;
class MCSymbolRefExpr;
class MCValue;
-/// MCObjectWriter - Defines the object file and target independent interfaces
-/// used by the assembler backend to write native file format object files.
+/// Defines the object file and target independent interfaces used by the
+/// assembler backend to write native file format object files.
///
/// The object writer contains a few callbacks used by the assembler to allow
/// the object writer to modify the assembler data structures at appropriate
/// points. Once assembly is complete, the object writer is given the
/// MCAssembler instance, which contains all the symbol and section data which
-/// should be emitted as part of WriteObject().
+/// should be emitted as part of writeObject().
///
/// The object writer also contains a number of helper methods for writing
/// binary data to the output stream.
@@ -54,7 +53,7 @@ public:
virtual ~MCObjectWriter();
/// lifetime management
- virtual void reset() { }
+ virtual void reset() {}
bool isLittleEndian() const { return IsLittleEndian; }
@@ -63,109 +62,106 @@ public:
/// \name High-Level API
/// @{
- /// \brief Perform any late binding of symbols (for example, to assign symbol
+ /// Perform any late binding of symbols (for example, to assign symbol
/// indices for use when generating relocations).
///
/// This routine is called by the assembler after layout and relaxation is
/// complete.
- virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
+ virtual void executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) = 0;
- /// \brief Record a relocation entry.
+ /// Record a relocation entry.
///
/// This routine is called by the assembler after layout and relaxation, and
/// post layout binding. The implementation is responsible for storing
/// information about the relocation so that it can be emitted during
- /// WriteObject().
- virtual void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
+ /// writeObject().
+ virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
bool &IsPCRel, uint64_t &FixedValue) = 0;
- /// \brief Check whether the difference (A - B) between two symbol
- /// references is fully resolved.
+ /// Check whether the difference (A - B) between two symbol references is
+ /// fully resolved.
///
/// Clients are not required to answer precisely and may conservatively return
/// false, even when a difference is fully resolved.
- bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
+ bool isSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
const MCSymbolRefExpr *A,
const MCSymbolRefExpr *B,
bool InSet) const;
- virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbol &SymA,
const MCFragment &FB,
bool InSet,
bool IsPCRel) const;
- /// \brief True if this symbol (which is a variable) is weak. This is not
+ /// 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
/// past it.
virtual bool isWeak(const MCSymbol &Sym) const;
- /// \brief Write the object file.
+ /// Write the object file.
///
/// This routine is called by the assembler after layout and relaxation is
/// complete, fixups have been evaluated and applied, and relocations
/// generated.
- virtual void WriteObject(MCAssembler &Asm,
- const MCAsmLayout &Layout) = 0;
+ virtual void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0;
/// @}
/// \name Binary Output
/// @{
- void Write8(uint8_t Value) {
- OS << char(Value);
- }
+ void write8(uint8_t Value) { OS << char(Value); }
- void WriteLE16(uint16_t Value) {
+ void writeLE16(uint16_t Value) {
support::endian::Writer<support::little>(OS).write(Value);
}
- void WriteLE32(uint32_t Value) {
+ void writeLE32(uint32_t Value) {
support::endian::Writer<support::little>(OS).write(Value);
}
- void WriteLE64(uint64_t Value) {
+ void writeLE64(uint64_t Value) {
support::endian::Writer<support::little>(OS).write(Value);
}
- void WriteBE16(uint16_t Value) {
+ void writeBE16(uint16_t Value) {
support::endian::Writer<support::big>(OS).write(Value);
}
- void WriteBE32(uint32_t Value) {
+ void writeBE32(uint32_t Value) {
support::endian::Writer<support::big>(OS).write(Value);
}
- void WriteBE64(uint64_t Value) {
+ void writeBE64(uint64_t Value) {
support::endian::Writer<support::big>(OS).write(Value);
}
- void Write16(uint16_t Value) {
+ void write16(uint16_t Value) {
if (IsLittleEndian)
- WriteLE16(Value);
+ writeLE16(Value);
else
- WriteBE16(Value);
+ writeBE16(Value);
}
- void Write32(uint32_t Value) {
+ void write32(uint32_t Value) {
if (IsLittleEndian)
- WriteLE32(Value);
+ writeLE32(Value);
else
- WriteBE32(Value);
+ writeBE32(Value);
}
- void Write64(uint64_t Value) {
+ void write64(uint64_t Value) {
if (IsLittleEndian)
- WriteLE64(Value);
+ writeLE64(Value);
else
- WriteBE64(Value);
+ writeBE64(Value);
}
void WriteZeros(unsigned N) {
- const char Zeros[16] = { 0 };
+ const char Zeros[16] = {0};
for (unsigned i = 0, e = N / 16; i != e; ++i)
OS << StringRef(Zeros, 16);
@@ -173,22 +169,23 @@ public:
OS << StringRef(Zeros, N % 16);
}
- void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) {
- WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize);
+ void writeBytes(const SmallVectorImpl<char> &ByteVec,
+ unsigned ZeroFillSize = 0) {
+ writeBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize);
}
- void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
+ void writeBytes(StringRef Str, unsigned ZeroFillSize = 0) {
// TODO: this version may need to go away once all fragment contents are
// converted to SmallVector<char, N>
- assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
- "data size greater than fill size, unexpected large write will occur");
+ assert(
+ (ZeroFillSize == 0 || Str.size() <= ZeroFillSize) &&
+ "data size greater than fill size, unexpected large write will occur");
OS << Str;
if (ZeroFillSize)
WriteZeros(ZeroFillSize - Str.size());
}
/// @}
-
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index 96a4ef135f21..5f6e8ec1d506 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -73,11 +73,13 @@ private:
/// \brief We've seen a bundle_lock directive but not its first instruction
/// yet.
- bool BundleGroupBeforeFirstInst = false;
+ unsigned BundleGroupBeforeFirstInst : 1;
/// Whether this section has had instructions emitted into it.
unsigned HasInstructions : 1;
+ unsigned IsRegistered : 1;
+
FragmentListType Fragments;
/// Mapping from subsection number to insertion point for subsection numbers
@@ -130,6 +132,9 @@ public:
bool hasInstructions() const { return HasInstructions; }
void setHasInstructions(bool Value) { HasInstructions = Value; }
+ bool isRegistered() const { return IsRegistered; }
+ void setIsRegistered(bool Value) { IsRegistered = Value; }
+
MCSection::FragmentListType &getFragmentList() { return Fragments; }
const MCSection::FragmentListType &getFragmentList() const {
return const_cast<MCSection *>(this)->getFragmentList();
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 9efe1022f295..f6730371fe15 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -16,7 +16,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCSection.h"
-#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolELF.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.h"
@@ -46,7 +46,7 @@ class MCSectionELF : public MCSection {
/// section does not contain fixed-sized entries 'EntrySize' will be 0.
unsigned EntrySize;
- const MCSymbol *Group;
+ const MCSymbolELF *Group;
/// Depending on the type of the section this is sh_link or sh_info.
const MCSectionELF *Associated;
@@ -54,11 +54,14 @@ class MCSectionELF : public MCSection {
private:
friend class MCContext;
MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K,
- unsigned entrySize, const MCSymbol *group, unsigned UniqueID,
+ unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID,
MCSymbol *Begin, const MCSectionELF *Associated)
: MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type),
Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group),
- Associated(Associated) {}
+ Associated(Associated) {
+ if (Group)
+ Group->setIsSignature();
+ }
~MCSectionELF() override;
void setSectionName(StringRef Name) { SectionName = Name; }
@@ -73,7 +76,7 @@ public:
unsigned getType() const { return Type; }
unsigned getFlags() const { return Flags; }
unsigned getEntrySize() const { return EntrySize; }
- const MCSymbol *getGroup() const { return Group; }
+ const MCSymbolELF *getGroup() const { return Group; }
void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
const MCExpr *Subsection) const override;
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 957913e934c4..628fb768856e 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -34,6 +34,7 @@ class MCInstPrinter;
class MCSection;
class MCStreamer;
class MCSymbol;
+class MCSymbolELF;
class MCSymbolRefExpr;
class MCSubtargetInfo;
class StringRef;
@@ -272,6 +273,7 @@ public:
return SectionStack.back().first;
return MCSectionSubPair();
}
+ MCSection *getCurrentSectionOnly() const { return getCurrentSection().first; }
/// \brief Return the previous section that the streamer is emitting code to.
MCSectionSubPair getPreviousSection() const {
@@ -305,11 +307,15 @@ public:
bool PopSection() {
if (SectionStack.size() <= 1)
return false;
- MCSectionSubPair oldSection = SectionStack.pop_back_val().first;
- MCSectionSubPair curSection = SectionStack.back().first;
-
- if (oldSection != curSection)
- ChangeSection(curSection.first, curSection.second);
+ auto I = SectionStack.end();
+ --I;
+ MCSectionSubPair OldSection = I->first;
+ --I;
+ MCSectionSubPair NewSection = I->first;
+
+ if (OldSection != NewSection)
+ ChangeSection(NewSection.first, NewSection.second);
+ SectionStack.pop_back();
return true;
}
@@ -433,6 +439,8 @@ public:
/// \brief Marks the end of the symbol definition.
virtual void EndCOFFSymbolDef();
+ virtual void EmitCOFFSafeSEH(MCSymbol const *Symbol);
+
/// \brief Emits a COFF section index.
///
/// \param Symbol - Symbol the section number relocation should point to.
@@ -447,7 +455,7 @@ public:
///
/// This corresponds to an assembler statement such as:
/// .size symbol, expression
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+ virtual void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value);
/// \brief Emit a Linker Optimization Hint (LOH) directive.
/// \param Args - Arguments of the LOH.
diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h
index 1778a6d13fb8..ee5d56334a2f 100644
--- a/include/llvm/MC/MCSubtargetInfo.h
+++ b/include/llvm/MC/MCSubtargetInfo.h
@@ -73,7 +73,9 @@ public:
/// setFeatureBits - Set the feature bits.
///
- void setFeatureBits(FeatureBitset& FeatureBits_) { FeatureBits = FeatureBits_; }
+ void setFeatureBits(const FeatureBitset &FeatureBits_) {
+ FeatureBits = FeatureBits_;
+ }
/// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
/// feature string). Recompute feature bits and scheduling model.
@@ -94,6 +96,10 @@ public:
/// feature bits. This version will also change all implied bits.
FeatureBitset ToggleFeature(StringRef FS);
+ /// Apply a feature flag and return the re-computed feature bits, including
+ /// all feature bits implied by the flag.
+ FeatureBitset ApplyFeatureFlag(StringRef FS);
+
/// getSchedModelForCPU - Get the machine model of a CPU.
///
MCSchedModel getSchedModelForCPU(StringRef CPU) const;
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index cf99c919281e..078f3d77e55c 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -14,12 +14,14 @@
#ifndef LLVM_MC_MCSYMBOL_H
#define LLVM_MC_MCSYMBOL_H
-#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
+class MCAsmInfo;
class MCExpr;
class MCSymbol;
class MCFragment;
@@ -27,109 +29,6 @@ class MCSection;
class MCContext;
class raw_ostream;
-// TODO: Merge completely with MCSymbol.
-class MCSymbolData {
- /// Fragment - The fragment this symbol's value is relative to, if any. Also
- /// stores if this symbol is visible outside this translation unit (bit 0) or
- /// if it is private extern (bit 1).
- PointerIntPair<MCFragment *, 2> Fragment;
-
- union {
- /// Offset - The offset to apply to the fragment address to form this
- /// symbol's value.
- uint64_t Offset;
-
- /// CommonSize - The size of the symbol, if it is 'common'.
- uint64_t CommonSize;
- };
-
- /// SymbolSize - An expression describing how to calculate the size of
- /// a symbol. If a symbol has no size this field will be NULL.
- const MCExpr *SymbolSize = nullptr;
-
- /// CommonAlign - The alignment of the symbol, if it is 'common', or -1.
- //
- // FIXME: Pack this in with other fields?
- unsigned CommonAlign = -1U;
-
- /// Flags - The Flags field is used by object file implementations to store
- /// additional per symbol information which is not easily classified.
- uint32_t Flags = 0;
-
-public:
- MCSymbolData() { Offset = 0; }
-
- MCFragment *getFragment() const { return Fragment.getPointer(); }
- void setFragment(MCFragment *Value) { Fragment.setPointer(Value); }
-
- uint64_t getOffset() const {
- assert(!isCommon());
- return Offset;
- }
- void setOffset(uint64_t Value) {
- assert(!isCommon());
- Offset = Value;
- }
-
- /// @}
- /// \name Symbol Attributes
- /// @{
-
- bool isExternal() const { return Fragment.getInt() & 1; }
- void setExternal(bool Value) {
- Fragment.setInt((Fragment.getInt() & ~1) | unsigned(Value));
- }
-
- bool isPrivateExtern() const { return Fragment.getInt() & 2; }
- void setPrivateExtern(bool Value) {
- Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1));
- }
-
- /// isCommon - Is this a 'common' symbol.
- bool isCommon() const { return CommonAlign != -1U; }
-
- /// setCommon - Mark this symbol as being 'common'.
- ///
- /// \param Size - The size of the symbol.
- /// \param Align - The alignment of the symbol.
- void setCommon(uint64_t Size, unsigned Align) {
- assert(getOffset() == 0);
- CommonSize = Size;
- CommonAlign = Align;
- }
-
- /// getCommonSize - Return the size of a 'common' symbol.
- uint64_t getCommonSize() const {
- assert(isCommon() && "Not a 'common' symbol!");
- return CommonSize;
- }
-
- void setSize(const MCExpr *SS) { SymbolSize = SS; }
-
- const MCExpr *getSize() const { return SymbolSize; }
-
- /// getCommonAlignment - Return the alignment of a 'common' symbol.
- unsigned getCommonAlignment() const {
- assert(isCommon() && "Not a 'common' symbol!");
- return CommonAlign;
- }
-
- /// getFlags - Get the (implementation defined) symbol flags.
- uint32_t getFlags() const { return Flags; }
-
- /// setFlags - Set the (implementation defined) symbol flags.
- void setFlags(uint32_t Value) { Flags = Value; }
-
- /// modifyFlags - Modify the flags via a mask
- void modifyFlags(uint32_t Value, uint32_t Mask) {
- Flags = (Flags & ~Mask) | Value;
- }
-
- /// @}
-
- void dump() const;
-};
-
/// MCSymbol - Instances of this class represent a symbol name in the MC file,
/// and MCSymbols are created and uniqued by the MCContext class. MCSymbols
/// should only be constructed with valid names for the object file.
@@ -138,6 +37,16 @@ public:
/// Section member is set to indicate what section it lives in. Otherwise, if
/// it is a reference to an external entity, it has a null section.
class MCSymbol {
+protected:
+ /// The kind of the symbol. If it is any value other than unset then this
+ /// class is actually one of the appropriate subclasses of MCSymbol.
+ enum SymbolKind {
+ SymbolKindUnset,
+ SymbolKindCOFF,
+ SymbolKindELF,
+ SymbolKindMachO,
+ };
+
// Special sentinal value for the absolute pseudo section.
//
// FIXME: Use a PointerInt wrapper for this?
@@ -147,10 +56,18 @@ class MCSymbol {
/// held by the StringMap that lives in MCContext.
const StringMapEntry<bool> *Name;
- /// The section the symbol is defined in. This is null for undefined symbols,
- /// and the special AbsolutePseudoSection value for absolute symbols. If this
- /// is a variable symbol, this caches the variable value's section.
- mutable MCSection *Section;
+ /// If a symbol has a Fragment, the section is implied, so we only need
+ /// one pointer.
+ /// FIXME: We might be able to simplify this by having the asm streamer create
+ /// dummy fragments.
+ /// If this is a section, then it gives the symbol is defined in. This is null
+ /// for undefined symbols, and the special AbsolutePseudoSection value for
+ /// absolute symbols. If this is a variable symbol, this caches the variable
+ /// value's section.
+ ///
+ /// If this is a fragment, then it gives the fragment this symbol's value is
+ /// relative to, if any.
+ mutable PointerUnion<MCSection *, MCFragment *> SectionOrFragment;
/// Value - If non-null, the value for a variable symbol.
const MCExpr *Value;
@@ -166,46 +83,68 @@ class MCSymbol {
/// IsUsed - True if this symbol has been used.
mutable unsigned IsUsed : 1;
- mutable bool HasData : 1;
+ mutable bool IsRegistered : 1;
+
+ /// This symbol is visible outside this translation unit.
+ mutable unsigned IsExternal : 1;
+
+ /// This symbol is private extern.
+ mutable unsigned IsPrivateExtern : 1;
+
+ /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is
+ /// unsigned to avoid sign extension and achieve better bitpacking with MSVC.
+ unsigned Kind : 2;
/// Index field, for use by the object file implementation.
- mutable uint64_t Index : 60;
+ mutable uint32_t Index = 0;
+
+ union {
+ /// The offset to apply to the fragment address to form this symbol's value.
+ uint64_t Offset;
+
+ /// The size of the symbol, if it is 'common'.
+ uint64_t CommonSize;
+ };
- mutable MCSymbolData Data;
+ /// The alignment of the symbol, if it is 'common', or -1.
+ //
+ // FIXME: Pack this in with other fields?
+ unsigned CommonAlign = -1U;
+
+ /// The Flags field is used by object file implementations to store
+ /// additional per symbol information which is not easily classified.
+ mutable uint32_t Flags = 0;
-private: // MCContext creates and uniques these.
+protected: // MCContext creates and uniques these.
friend class MCExpr;
friend class MCContext;
- MCSymbol(const StringMapEntry<bool> *Name, bool isTemporary)
- : Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary),
- IsRedefinable(false), IsUsed(false), HasData(false), Index(0) {}
+ MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary)
+ : Name(Name), Value(nullptr), IsTemporary(isTemporary),
+ IsRedefinable(false), IsUsed(false), IsRegistered(false),
+ IsExternal(false), IsPrivateExtern(false),
+ Kind(Kind) {
+ Offset = 0;
+ }
+private:
MCSymbol(const MCSymbol &) = delete;
void operator=(const MCSymbol &) = delete;
MCSection *getSectionPtr() const {
+ if (MCFragment *F = getFragment())
+ return F->getParent();
+ assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected");
+ MCSection *Section = SectionOrFragment.dyn_cast<MCSection *>();
if (Section || !Value)
return Section;
- return Section = Value->FindAssociatedSection();
+ return Section = Value->findAssociatedSection();
}
public:
/// getName - Get the symbol name.
StringRef getName() const { return Name ? Name->first() : ""; }
- bool hasData() const { return HasData; }
-
- /// Get associated symbol data.
- MCSymbolData &getData() const {
- assert(HasData && "Missing symbol data!");
- return Data;
- }
-
- /// Initialize symbol data.
- ///
- /// Nothing really to do here, but this is enables an assertion that \a
- /// MCAssembler::getOrCreateSymbolData() has actually been called before
- /// anyone calls \a getData().
- void initializeData() const { HasData = true; }
+ bool isRegistered() const { return IsRegistered; }
+ void setIsRegistered(bool Value) const { IsRegistered = Value; }
/// \name Accessors
/// @{
@@ -225,7 +164,7 @@ public:
void redefineIfPossible() {
if (IsRedefinable) {
Value = nullptr;
- Section = nullptr;
+ SectionOrFragment = nullptr;
IsRedefinable = false;
}
}
@@ -258,11 +197,20 @@ public:
/// Mark the symbol as defined in the section \p S.
void setSection(MCSection &S) {
assert(!isVariable() && "Cannot set section of variable");
- Section = &S;
+ assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected");
+ SectionOrFragment = &S;
+ }
+
+ /// Mark the symbol as undefined.
+ void setUndefined() {
+ SectionOrFragment = nullptr;
}
- /// setUndefined - Mark the symbol as undefined.
- void setUndefined() { Section = nullptr; }
+ bool isELF() const { return Kind == SymbolKindELF; }
+
+ bool isCOFF() const { return Kind == SymbolKindCOFF; }
+
+ bool isMachO() const { return Kind == SymbolKindMachO; }
/// @}
/// \name Variable Symbols
@@ -283,27 +231,98 @@ public:
/// @}
/// Get the (implementation defined) index.
- uint64_t getIndex() const {
- assert(HasData && "Uninitialized symbol data");
+ uint32_t getIndex() const {
return Index;
}
/// Set the (implementation defined) index.
- void setIndex(uint64_t Value) const {
- assert(HasData && "Uninitialized symbol data");
- assert(!(Value >> 60) && "Not enough bits for value");
+ void setIndex(uint32_t Value) const {
Index = Value;
}
+ uint64_t getOffset() const {
+ assert(!isCommon());
+ return Offset;
+ }
+ void setOffset(uint64_t Value) {
+ assert(!isCommon());
+ Offset = Value;
+ }
+
+ /// Return the size of a 'common' symbol.
+ uint64_t getCommonSize() const {
+ assert(isCommon() && "Not a 'common' symbol!");
+ return CommonSize;
+ }
+
+ /// Mark this symbol as being 'common'.
+ ///
+ /// \param Size - The size of the symbol.
+ /// \param Align - The alignment of the symbol.
+ void setCommon(uint64_t Size, unsigned Align) {
+ assert(getOffset() == 0);
+ CommonSize = Size;
+ CommonAlign = Align;
+ }
+
+ /// Return the alignment of a 'common' symbol.
+ unsigned getCommonAlignment() const {
+ assert(isCommon() && "Not a 'common' symbol!");
+ return CommonAlign;
+ }
+
+ /// Declare this symbol as being 'common'.
+ ///
+ /// \param Size - The size of the symbol.
+ /// \param Align - The alignment of the symbol.
+ /// \return True if symbol was already declared as a different type
+ bool declareCommon(uint64_t Size, unsigned Align) {
+ assert(isCommon() || getOffset() == 0);
+ if(isCommon()) {
+ if(CommonSize != Size || CommonAlign != Align)
+ return true;
+ } else
+ setCommon(Size, Align);
+ return false;
+ }
+
+ /// Is this a 'common' symbol.
+ bool isCommon() const { return CommonAlign != -1U; }
+
+ MCFragment *getFragment() const {
+ return SectionOrFragment.dyn_cast<MCFragment *>();
+ }
+ void setFragment(MCFragment *Value) const {
+ SectionOrFragment = Value;
+ }
+
+ bool isExternal() const { return IsExternal; }
+ void setExternal(bool Value) const { IsExternal = Value; }
+
+ bool isPrivateExtern() const { return IsPrivateExtern; }
+ void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
+
/// print - Print the value to the stream \p OS.
- void print(raw_ostream &OS) const;
+ void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
/// dump - Print the value to stderr.
void dump() const;
+
+protected:
+ /// Get the (implementation defined) symbol flags.
+ uint32_t getFlags() const { return Flags; }
+
+ /// Set the (implementation defined) symbol flags.
+ void setFlags(uint32_t Value) const { Flags = Value; }
+
+ /// Modify the flags via a mask
+ void modifyFlags(uint32_t Value, uint32_t Mask) const {
+ Flags = (Flags & ~Mask) | Value;
+ }
};
inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
- Sym.print(OS);
+ Sym.print(OS, nullptr);
return OS;
}
} // end namespace llvm
diff --git a/include/llvm/MC/MCSymbolCOFF.h b/include/llvm/MC/MCSymbolCOFF.h
new file mode 100644
index 000000000000..2172c67981c0
--- /dev/null
+++ b/include/llvm/MC/MCSymbolCOFF.h
@@ -0,0 +1,64 @@
+//===- MCSymbolCOFF.h - ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCSYMBOLCOFF_H
+#define LLVM_MC_MCSYMBOLCOFF_H
+
+#include "llvm/MC/MCSymbol.h"
+
+namespace llvm {
+class MCSymbolCOFF : public MCSymbol {
+
+ /// This corresponds to the e_type field of the COFF symbol.
+ mutable uint16_t Type;
+
+ enum SymbolFlags : uint16_t {
+ SF_ClassMask = 0x00FF,
+ SF_ClassShift = 0,
+
+ SF_WeakExternal = 0x0100,
+ SF_SafeSEH = 0x0200,
+ };
+
+public:
+ MCSymbolCOFF(const StringMapEntry<bool> *Name, bool isTemporary)
+ : MCSymbol(SymbolKindCOFF, Name, isTemporary), Type(0) {}
+
+ uint16_t getType() const {
+ return Type;
+ }
+ void setType(uint16_t Ty) const {
+ Type = Ty;
+ }
+
+ uint16_t getClass() const {
+ return (getFlags() & SF_ClassMask) >> SF_ClassShift;
+ }
+ void setClass(uint16_t StorageClass) const {
+ modifyFlags(StorageClass << SF_ClassShift, SF_ClassMask);
+ }
+
+ bool isWeakExternal() const {
+ return getFlags() & SF_WeakExternal;
+ }
+ void setIsWeakExternal() const {
+ modifyFlags(SF_WeakExternal, SF_WeakExternal);
+ }
+
+ bool isSafeSEH() const {
+ return getFlags() & SF_SafeSEH;
+ }
+ void setIsSafeSEH() const {
+ modifyFlags(SF_SafeSEH, SF_SafeSEH);
+ }
+
+ static bool classof(const MCSymbol *S) { return S->isCOFF(); }
+};
+}
+
+#endif
diff --git a/include/llvm/MC/MCSymbolELF.h b/include/llvm/MC/MCSymbolELF.h
new file mode 100644
index 000000000000..0cc11156b5cd
--- /dev/null
+++ b/include/llvm/MC/MCSymbolELF.h
@@ -0,0 +1,57 @@
+//===- MCSymbolELF.h - -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCSYMBOLELF_H
+#define LLVM_MC_MCSYMBOLELF_H
+
+#include "llvm/MC/MCSymbol.h"
+
+namespace llvm {
+class MCSymbolELF : public MCSymbol {
+ /// An expression describing how to calculate the size of a symbol. If a
+ /// symbol has no size this field will be NULL.
+ const MCExpr *SymbolSize = nullptr;
+
+public:
+ MCSymbolELF(const StringMapEntry<bool> *Name, bool isTemporary)
+ : MCSymbol(SymbolKindELF, Name, isTemporary) {}
+ void setSize(const MCExpr *SS) { SymbolSize = SS; }
+
+ const MCExpr *getSize() const { return SymbolSize; }
+
+ void setVisibility(unsigned Visibility);
+ unsigned getVisibility() const;
+
+ void setOther(unsigned Other);
+ unsigned getOther() const;
+
+ void setType(unsigned Type) const;
+ unsigned getType() const;
+
+ void setBinding(unsigned Binding) const;
+ unsigned getBinding() const;
+
+ bool isBindingSet() const;
+
+ void setUsedInReloc() const;
+ bool isUsedInReloc() const;
+
+ void setIsWeakrefUsedInReloc() const;
+ bool isWeakrefUsedInReloc() const;
+
+ void setIsSignature() const;
+ bool isSignature() const;
+
+ static bool classof(const MCSymbol *S) { return S->isELF(); }
+
+private:
+ void setIsBindingSet() const;
+};
+}
+
+#endif
diff --git a/include/llvm/MC/MCSymbolMachO.h b/include/llvm/MC/MCSymbolMachO.h
new file mode 100644
index 000000000000..166ae9e755a1
--- /dev/null
+++ b/include/llvm/MC/MCSymbolMachO.h
@@ -0,0 +1,123 @@
+//===- MCSymbolMachO.h - ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCSYMBOLMACHO_H
+#define setIsWeakExternal
+
+#include "llvm/MC/MCSymbol.h"
+
+namespace llvm {
+class MCSymbolMachO : public MCSymbol {
+ /// \brief We store the value for the 'desc' symbol field in the
+ /// lowest 16 bits of the implementation defined flags.
+ enum MachOSymbolFlags : uint16_t { // See <mach-o/nlist.h>.
+ SF_DescFlagsMask = 0xFFFF,
+
+ // Reference type flags.
+ SF_ReferenceTypeMask = 0x0007,
+ SF_ReferenceTypeUndefinedNonLazy = 0x0000,
+ SF_ReferenceTypeUndefinedLazy = 0x0001,
+ SF_ReferenceTypeDefined = 0x0002,
+ SF_ReferenceTypePrivateDefined = 0x0003,
+ SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
+ SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
+
+ // Other 'desc' flags.
+ SF_ThumbFunc = 0x0008,
+ SF_NoDeadStrip = 0x0020,
+ SF_WeakReference = 0x0040,
+ SF_WeakDefinition = 0x0080,
+ SF_SymbolResolver = 0x0100,
+
+ // Common alignment
+ SF_CommonAlignmentMask = 0xF0FF,
+ SF_CommonAlignmentShift = 8
+ };
+
+public:
+ MCSymbolMachO(const StringMapEntry<bool> *Name, bool isTemporary)
+ : MCSymbol(SymbolKindMachO, Name, isTemporary) {}
+
+ // Reference type methods.
+
+ void clearReferenceType() const {
+ modifyFlags(0, SF_ReferenceTypeMask);
+ }
+
+ void setReferenceTypeUndefinedLazy(bool Value) const {
+ modifyFlags(Value ? SF_ReferenceTypeUndefinedLazy : 0,
+ SF_ReferenceTypeUndefinedLazy);
+ }
+
+ // Other 'desc' methods.
+
+ void setThumbFunc() const {
+ modifyFlags(SF_ThumbFunc, SF_ThumbFunc);
+ }
+
+ bool isNoDeadStrip() const {
+ return getFlags() & SF_NoDeadStrip;
+ }
+ void setNoDeadStrip() const {
+ modifyFlags(SF_NoDeadStrip, SF_NoDeadStrip);
+ }
+
+ bool isWeakReference() const {
+ return getFlags() & SF_WeakReference;
+ }
+ void setWeakReference() const {
+ modifyFlags(SF_WeakReference, SF_WeakReference);
+ }
+
+ bool isWeakDefinition() const {
+ return getFlags() & SF_WeakDefinition;
+ }
+ void setWeakDefinition() const {
+ modifyFlags(SF_WeakDefinition, SF_WeakDefinition);
+ }
+
+ bool isSymbolResolver() const {
+ return getFlags() & SF_SymbolResolver;
+ }
+ void setSymbolResolver() const {
+ modifyFlags(SF_SymbolResolver, SF_SymbolResolver);
+ }
+
+ void setDesc(unsigned Value) const {
+ assert(Value == (Value & SF_DescFlagsMask) &&
+ "Invalid .desc value!");
+ setFlags(Value & SF_DescFlagsMask);
+ }
+
+ /// \brief Get the encoded value of the flags as they will be emitted in to
+ /// the MachO binary
+ uint16_t getEncodedFlags() const {
+ uint16_t Flags = getFlags();
+
+ // Common alignment is packed into the 'desc' bits.
+ if (isCommon()) {
+ if (unsigned Align = getCommonAlignment()) {
+ unsigned Log2Size = Log2_32(Align);
+ assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
+ if (Log2Size > 15)
+ report_fatal_error("invalid 'common' alignment '" +
+ Twine(Align) + "' for '" + getName() + "'",
+ false);
+ Flags = (Flags & SF_CommonAlignmentMask) |
+ (Log2Size << SF_CommonAlignmentShift);
+ }
+ }
+
+ return Flags;
+ }
+
+ static bool classof(const MCSymbol *S) { return S->isMachO(); }
+};
+}
+
+#endif
diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h
index 6a83e02298ff..6fbc754f1125 100644
--- a/include/llvm/MC/MCWinCOFFStreamer.h
+++ b/include/llvm/MC/MCWinCOFFStreamer.h
@@ -50,9 +50,9 @@ public:
void EmitCOFFSymbolStorageClass(int StorageClass) override;
void EmitCOFFSymbolType(int Type) override;
void EndCOFFSymbolDef() override;
+ void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
- void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
index 6a631ffe79bd..2fb9b4ae2503 100644
--- a/include/llvm/MC/SubtargetFeature.h
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -103,6 +103,10 @@ public:
FeatureBitset ToggleFeature(FeatureBitset Bits, StringRef String,
ArrayRef<SubtargetFeatureKV> FeatureTable);
+ /// Apply the feature flag and return the newly updated feature bits.
+ FeatureBitset ApplyFeatureFlag(FeatureBitset Bits, StringRef Feature,
+ ArrayRef<SubtargetFeatureKV> FeatureTable);
+
/// Get feature bits of a CPU.
FeatureBitset getFeatureBits(StringRef CPU,
ArrayRef<SubtargetFeatureKV> CPUTable,
diff --git a/include/llvm/Object/ArchiveWriter.h b/include/llvm/Object/ArchiveWriter.h
new file mode 100644
index 000000000000..1616e46d3e6f
--- /dev/null
+++ b/include/llvm/Object/ArchiveWriter.h
@@ -0,0 +1,51 @@
+//===- ArchiveWriter.h - ar archive file format writer ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Declares the writeArchive function for writing an archive file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ARCHIVEWRITER_H
+#define LLVM_OBJECT_ARCHIVEWRITER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Support/FileSystem.h"
+
+namespace llvm {
+
+class NewArchiveIterator {
+ bool IsNewMember;
+ StringRef Name;
+
+ object::Archive::child_iterator OldI;
+
+ StringRef NewFilename;
+
+public:
+ NewArchiveIterator(object::Archive::child_iterator I, StringRef Name);
+ NewArchiveIterator(StringRef I, StringRef Name);
+ NewArchiveIterator();
+ bool isNewMember() const;
+ StringRef getName() const;
+
+ object::Archive::child_iterator getOld() const;
+
+ StringRef getNew() const;
+ llvm::ErrorOr<int> getFD(sys::fs::file_status &NewStatus) const;
+ const sys::fs::file_status &getStatus() const;
+};
+
+std::pair<StringRef, std::error_code>
+writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers,
+ bool WriteSymtab);
+
+}
+
+#endif
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
index ccac02036adc..564eb7a7a9c3 100644
--- a/include/llvm/Object/COFF.h
+++ b/include/llvm/Object/COFF.h
@@ -613,7 +613,7 @@ protected:
StringRef &Res) const override;
std::error_code getSymbolAddress(DataRefImpl Symb,
uint64_t &Res) const override;
- std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ uint64_t getSymbolSize(DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
std::error_code getSymbolType(DataRefImpl Symb,
SymbolRef::Type &Res) const override;
@@ -647,10 +647,6 @@ protected:
std::error_code
getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const override;
- std::error_code
- getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
-
public:
COFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
basic_symbol_iterator symbol_begin_impl() const override;
@@ -699,7 +695,7 @@ public:
return object_error::parse_failed;
Res = reinterpret_cast<coff_symbol_type *>(getSymbolTable()) + Index;
- return object_error::success;
+ return std::error_code();
}
ErrorOr<COFFSymbolRef> getSymbol(uint32_t index) const {
if (SymbolTable16) {
@@ -722,7 +718,7 @@ public:
if (std::error_code EC = s.getError())
return EC;
Res = reinterpret_cast<const T *>(s->getRawPtr());
- return object_error::success;
+ return std::error_code();
}
std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const;
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index ddabf59f309e..e87737dcce7a 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -318,7 +318,7 @@ public:
std::pair<const Elf_Shdr *, const Elf_Sym *>
getRelocationSymbol(const Elf_Shdr *RelSec, const RelT *Rel) const;
- ELFFile(StringRef Object, std::error_code &ec);
+ ELFFile(StringRef Object, std::error_code &EC);
bool isMipsELF64() const {
return Header->e_machine == ELF::EM_MIPS &&
@@ -423,12 +423,10 @@ public:
StringRef getLoadName() const;
};
-// Use an alignment of 2 for the typedefs since that is the worst case for
-// ELF files in archives.
-typedef ELFFile<ELFType<support::little, 2, false> > ELF32LEFile;
-typedef ELFFile<ELFType<support::little, 2, true> > ELF64LEFile;
-typedef ELFFile<ELFType<support::big, 2, false> > ELF32BEFile;
-typedef ELFFile<ELFType<support::big, 2, true> > ELF64BEFile;
+typedef ELFFile<ELFType<support::little, false>> ELF32LEFile;
+typedef ELFFile<ELFType<support::little, true>> ELF64LEFile;
+typedef ELFFile<ELFType<support::big, false>> ELF32BEFile;
+typedef ELFFile<ELFType<support::big, true>> ELF64BEFile;
// Iterate through the version definitions, and place each Elf_Verdef
// in the VersionMap according to its index.
@@ -622,7 +620,7 @@ typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const {
}
template <class ELFT>
-ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec)
+ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
: Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr),
dot_strtab_sec(nullptr), dot_symtab_sec(nullptr),
SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr),
@@ -630,9 +628,11 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec)
dt_soname(nullptr) {
const uint64_t FileSize = Buf.size();
- if (sizeof(Elf_Ehdr) > FileSize)
- // FIXME: Proper error handling.
- report_fatal_error("File too short!");
+ if (sizeof(Elf_Ehdr) > FileSize) {
+ // File too short!
+ EC = object_error::parse_failed;
+ return;
+ }
Header = reinterpret_cast<const Elf_Ehdr *>(base());
@@ -641,40 +641,50 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec)
const uint64_t SectionTableOffset = Header->e_shoff;
- if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
- // FIXME: Proper error handling.
- report_fatal_error("Section header table goes past end of file!");
+ if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) {
+ // Section header table goes past end of file!
+ EC = object_error::parse_failed;
+ return;
+ }
// The getNumSections() call below depends on SectionHeaderTable being set.
SectionHeaderTable =
reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
- if (SectionTableOffset + SectionTableSize > FileSize)
- // FIXME: Proper error handling.
- report_fatal_error("Section table goes past end of file!");
+ if (SectionTableOffset + SectionTableSize > FileSize) {
+ // Section table goes past end of file!
+ EC = object_error::parse_failed;
+ return;
+ }
// Scan sections for special sections.
for (const Elf_Shdr &Sec : sections()) {
switch (Sec.sh_type) {
case ELF::SHT_SYMTAB_SHNDX:
- if (SymbolTableSectionHeaderIndex)
- // FIXME: Proper error handling.
- report_fatal_error("More than one .symtab_shndx!");
+ if (SymbolTableSectionHeaderIndex) {
+ // More than one .symtab_shndx!
+ EC = object_error::parse_failed;
+ return;
+ }
SymbolTableSectionHeaderIndex = &Sec;
break;
case ELF::SHT_SYMTAB:
- if (dot_symtab_sec)
- // FIXME: Proper error handling.
- report_fatal_error("More than one .symtab!");
+ if (dot_symtab_sec) {
+ // More than one .symtab!
+ EC = object_error::parse_failed;
+ return;
+ }
dot_symtab_sec = &Sec;
dot_strtab_sec = getSection(Sec.sh_link);
break;
case ELF::SHT_DYNSYM: {
- if (DynSymRegion.Addr)
- // FIXME: Proper error handling.
- report_fatal_error("More than one .dynsym!");
+ if (DynSymRegion.Addr) {
+ // More than one .dynsym!
+ EC = object_error::parse_failed;
+ return;
+ }
DynSymRegion.Addr = base() + Sec.sh_offset;
DynSymRegion.Size = Sec.sh_size;
DynSymRegion.EntSize = Sec.sh_entsize;
@@ -685,29 +695,37 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec)
break;
}
case ELF::SHT_DYNAMIC:
- if (DynamicRegion.Addr)
- // FIXME: Proper error handling.
- report_fatal_error("More than one .dynamic!");
+ if (DynamicRegion.Addr) {
+ // More than one .dynamic!
+ EC = object_error::parse_failed;
+ return;
+ }
DynamicRegion.Addr = base() + Sec.sh_offset;
DynamicRegion.Size = Sec.sh_size;
DynamicRegion.EntSize = Sec.sh_entsize;
break;
case ELF::SHT_GNU_versym:
- if (dot_gnu_version_sec != nullptr)
- // FIXME: Proper error handling.
- report_fatal_error("More than one .gnu.version section!");
+ if (dot_gnu_version_sec != nullptr) {
+ // More than one .gnu.version section!
+ EC = object_error::parse_failed;
+ return;
+ }
dot_gnu_version_sec = &Sec;
break;
case ELF::SHT_GNU_verdef:
- if (dot_gnu_version_d_sec != nullptr)
- // FIXME: Proper error handling.
- report_fatal_error("More than one .gnu.version_d section!");
+ if (dot_gnu_version_d_sec != nullptr) {
+ // More than one .gnu.version_d section!
+ EC = object_error::parse_failed;
+ return;
+ }
dot_gnu_version_d_sec = &Sec;
break;
case ELF::SHT_GNU_verneed:
- if (dot_gnu_version_r_sec != nullptr)
- // FIXME: Proper error handling.
- report_fatal_error("More than one .gnu.version_r section!");
+ if (dot_gnu_version_r_sec != nullptr) {
+ // More than one .gnu.version_r section!
+ EC = object_error::parse_failed;
+ return;
+ }
dot_gnu_version_r_sec = &Sec;
break;
}
@@ -744,7 +762,7 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec)
}
}
- ec = std::error_code();
+ EC = std::error_code();
}
// Get the symbol table index in the symtab section given a symbol
@@ -898,11 +916,8 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(Elf_Sym_Iter Sym) const {
template <class ELFT>
ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Shdr *Section,
const Elf_Sym *Symb) const {
- if (Symb->st_name == 0) {
- const Elf_Shdr *ContainingSec = getSection(Symb);
- if (ContainingSec)
- return getSectionName(ContainingSec);
- }
+ if (Symb->st_name == 0)
+ return StringRef("");
const Elf_Shdr *StrTab = getSection(Section->sh_link);
if (Symb->st_name >= StrTab->sh_size)
diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h
index 9bd4c3241118..78d77be5be8d 100644
--- a/include/llvm/Object/ELFObjectFile.h
+++ b/include/llvm/Object/ELFObjectFile.h
@@ -79,9 +79,8 @@ protected:
StringRef &Res) const override;
std::error_code getSymbolAddress(DataRefImpl Symb,
uint64_t &Res) const override;
- std::error_code getSymbolAlignment(DataRefImpl Symb,
- uint32_t &Res) const override;
- std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
+ uint64_t getSymbolSize(DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override;
std::error_code getSymbolType(DataRefImpl Symb,
@@ -119,9 +118,6 @@ protected:
std::error_code
getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const override;
- std::error_code
- getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
uint64_t getROffset(DataRefImpl Rel) const;
StringRef getRelocationTypeName(uint32_t Type) const;
@@ -227,7 +223,7 @@ public:
std::error_code getPlatformFlags(unsigned &Result) const override {
Result = EF.getHeader()->e_flags;
- return object_error::success;
+ return std::error_code();
}
const ELFFile<ELFT> *getELFFile() const { return &EF; }
@@ -244,12 +240,10 @@ public:
bool isRelocatableObject() const override;
};
-// Use an alignment of 2 for the typedefs since that is the worst case for
-// ELF files in archives.
-typedef ELFObjectFile<ELFType<support::little, 2, false> > ELF32LEObjectFile;
-typedef ELFObjectFile<ELFType<support::little, 2, true> > ELF64LEObjectFile;
-typedef ELFObjectFile<ELFType<support::big, 2, false> > ELF32BEObjectFile;
-typedef ELFObjectFile<ELFType<support::big, 2, true> > ELF64BEObjectFile;
+typedef ELFObjectFile<ELFType<support::little, false>> ELF32LEObjectFile;
+typedef ELFObjectFile<ELFType<support::little, true>> ELF64LEObjectFile;
+typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile;
+typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile;
template <class ELFT>
void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const {
@@ -263,7 +257,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
if (!Name)
return Name.getError();
Result = *Name;
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -277,7 +271,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
if (!Ver)
return Ver.getError();
Version = *Ver;
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -300,10 +294,10 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
case ELF::SHN_COMMON:
case ELF::SHN_UNDEF:
Result = UnknownAddressOrSize;
- return object_error::success;
+ return std::error_code();
case ELF::SHN_ABS:
Result = ESym->st_value;
- return object_error::success;
+ return std::error_code();
default:
break;
}
@@ -322,32 +316,27 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
Result += Section->sh_addr;
}
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
- uint32_t &Res) const {
+uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
Elf_Sym_Iter Sym = toELFSymIter(Symb);
if (Sym->st_shndx == ELF::SHN_COMMON)
- Res = Sym->st_value;
- else
- Res = 0;
- return object_error::success;
+ return Sym->st_value;
+ return 0;
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
- uint64_t &Result) const {
- Result = toELFSymIter(Symb)->st_size;
- return object_error::success;
+uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb) const {
+ return toELFSymIter(Symb)->st_size;
}
template <class ELFT>
std::error_code ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb,
uint8_t &Result) const {
Result = toELFSymIter(Symb)->st_other;
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -378,7 +367,7 @@ ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
Result = SymbolRef::ST_Other;
break;
}
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -435,7 +424,7 @@ std::error_code
ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
section_iterator &Res) const {
Res = getSymbolSection(getSymbol(Symb));
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -450,7 +439,7 @@ std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
if (!Name)
return Name.getError();
Result = *Name;
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -469,7 +458,7 @@ ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
StringRef &Result) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -624,7 +613,7 @@ ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
Result = ROffset;
}
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -634,7 +623,7 @@ ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
assert(EF.getHeader()->e_type == ELF::ET_REL &&
"Only relocatable object files have relocation offsets");
Result = getROffset(Rel);
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -666,7 +655,7 @@ std::error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
break;
}
}
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -693,7 +682,7 @@ std::error_code ELFObjectFile<ELFT>::getRelocationTypeName(
}
EF.getRelocationTypeName(type, Result);
- return object_error::success;
+ return std::error_code();
}
template <class ELFT>
@@ -706,94 +695,13 @@ ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel,
report_fatal_error("Invalid section type in Rel!");
case ELF::SHT_REL: {
Result = 0;
- return object_error::success;
+ return std::error_code();
}
case ELF::SHT_RELA: {
Result = getRela(Rel)->r_addend;
- return object_error::success;
- }
+ return std::error_code();
}
-}
-
-template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::getRelocationValueString(
- DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
- const Elf_Shdr *sec = getRelSection(Rel);
- uint8_t type;
- StringRef res;
- int64_t addend = 0;
- uint16_t symbol_index = 0;
- switch (sec->sh_type) {
- default:
- return object_error::parse_failed;
- case ELF::SHT_REL: {
- type = getRel(Rel)->getType(EF.isMips64EL());
- symbol_index = getRel(Rel)->getSymbol(EF.isMips64EL());
- // TODO: Read implicit addend from section data.
- break;
- }
- case ELF::SHT_RELA: {
- type = getRela(Rel)->getType(EF.isMips64EL());
- symbol_index = getRela(Rel)->getSymbol(EF.isMips64EL());
- addend = getRela(Rel)->r_addend;
- break;
- }
- }
- const Elf_Sym *symb =
- EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index);
- ErrorOr<StringRef> SymName =
- EF.getSymbolName(EF.getSection(sec->sh_link), symb);
- if (!SymName)
- return SymName.getError();
- switch (EF.getHeader()->e_machine) {
- case ELF::EM_X86_64:
- switch (type) {
- case ELF::R_X86_64_PC8:
- case ELF::R_X86_64_PC16:
- case ELF::R_X86_64_PC32: {
- std::string fmtbuf;
- raw_string_ostream fmt(fmtbuf);
- fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P";
- fmt.flush();
- Result.append(fmtbuf.begin(), fmtbuf.end());
- } break;
- case ELF::R_X86_64_8:
- case ELF::R_X86_64_16:
- case ELF::R_X86_64_32:
- case ELF::R_X86_64_32S:
- case ELF::R_X86_64_64: {
- std::string fmtbuf;
- raw_string_ostream fmt(fmtbuf);
- fmt << *SymName << (addend < 0 ? "" : "+") << addend;
- fmt.flush();
- Result.append(fmtbuf.begin(), fmtbuf.end());
- } break;
- default:
- res = "Unknown";
- }
- break;
- case ELF::EM_AARCH64: {
- std::string fmtbuf;
- raw_string_ostream fmt(fmtbuf);
- fmt << *SymName;
- if (addend != 0)
- fmt << (addend < 0 ? "" : "+") << addend;
- fmt.flush();
- Result.append(fmtbuf.begin(), fmtbuf.end());
- break;
- }
- case ELF::EM_386:
- case ELF::EM_ARM:
- case ELF::EM_HEXAGON:
- case ELF::EM_MIPS:
- res = *SymName;
- break;
- default:
- res = "Unknown";
}
- if (Result.empty())
- Result.append(res.begin(), res.end());
- return object_error::success;
}
template <class ELFT>
diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h
index 287d3670678a..3f323b5b8200 100644
--- a/include/llvm/Object/ELFTypes.h
+++ b/include/llvm/Object/ELFTypes.h
@@ -10,7 +10,6 @@
#ifndef LLVM_OBJECT_ELFTYPES_H
#define LLVM_OBJECT_ELFTYPES_H
-#include "llvm/Support/AlignOf.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
@@ -20,95 +19,74 @@ namespace object {
using support::endianness;
-template <endianness target_endianness, std::size_t max_alignment,
- bool is64Bits>
-struct ELFType {
+template <endianness target_endianness, bool is64Bits> struct ELFType {
static const endianness TargetEndianness = target_endianness;
- static const std::size_t MaxAlignment = max_alignment;
static const bool Is64Bits = is64Bits;
};
-template <typename T, int max_align> struct MaximumAlignment {
- enum { value = AlignOf<T>::Alignment > max_align ? max_align
- : AlignOf<T>::Alignment
- };
-};
+// Use an alignment of 2 for the typedefs since that is the worst case for
+// ELF files in archives.
// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
-template <endianness target_endianness, std::size_t max_alignment>
-struct ELFDataTypeTypedefHelperCommon {
+template <endianness target_endianness> struct ELFDataTypeTypedefHelperCommon {
typedef support::detail::packed_endian_specific_integral<
- uint16_t, target_endianness,
- MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half;
+ uint16_t, target_endianness, 2> Elf_Half;
typedef support::detail::packed_endian_specific_integral<
- uint32_t, target_endianness,
- MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word;
+ uint32_t, target_endianness, 2> Elf_Word;
typedef support::detail::packed_endian_specific_integral<
- int32_t, target_endianness,
- MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword;
+ int32_t, target_endianness, 2> Elf_Sword;
typedef support::detail::packed_endian_specific_integral<
- uint64_t, target_endianness,
- MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword;
+ uint64_t, target_endianness, 2> Elf_Xword;
typedef support::detail::packed_endian_specific_integral<
- int64_t, target_endianness,
- MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword;
+ int64_t, target_endianness, 2> Elf_Sxword;
};
template <class ELFT> struct ELFDataTypeTypedefHelper;
/// ELF 32bit types.
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> >
- : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
+template <endianness TargetEndianness>
+struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, false>>
+ : ELFDataTypeTypedefHelperCommon<TargetEndianness> {
typedef uint32_t value_type;
typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness,
- MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
+ value_type, TargetEndianness, 2> Elf_Addr;
typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness,
- MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
+ value_type, TargetEndianness, 2> Elf_Off;
};
/// ELF 64bit types.
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> >
- : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
+template <endianness TargetEndianness>
+struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, true>>
+ : ELFDataTypeTypedefHelperCommon<TargetEndianness> {
typedef uint64_t value_type;
typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness,
- MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
+ value_type, TargetEndianness, 2> Elf_Addr;
typedef support::detail::packed_endian_specific_integral<
- value_type, TargetEndianness,
- MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
+ value_type, TargetEndianness, 2> Elf_Off;
};
// I really don't like doing this, but the alternative is copypasta.
-#define LLVM_ELF_IMPORT_TYPES(E, M, W) \
-typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Addr \
- Elf_Addr; \
-typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Off \
- Elf_Off; \
-typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Half \
- Elf_Half; \
-typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Word \
- Elf_Word; \
-typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sword \
- Elf_Sword; \
-typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Xword \
- Elf_Xword; \
-typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sxword \
- Elf_Sxword;
+#define LLVM_ELF_IMPORT_TYPES(E, W) \
+ typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Addr Elf_Addr; \
+ typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Off Elf_Off; \
+ typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Half Elf_Half; \
+ typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Word Elf_Word; \
+ typedef \
+ typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Sword Elf_Sword; \
+ typedef \
+ typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Xword Elf_Xword; \
+ typedef \
+ typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Sxword Elf_Sxword;
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
- LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, \
- ELFT::Is64Bits)
+ LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::Is64Bits)
// Section header.
template <class ELFT> struct Elf_Shdr_Base;
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+template <endianness TargetEndianness>
+struct Elf_Shdr_Base<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
Elf_Word sh_name; // Section name (index into string table)
Elf_Word sh_type; // Section type (SHT_*)
Elf_Word sh_flags; // Section flags (SHF_*)
@@ -121,9 +99,9 @@ struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > {
Elf_Word sh_entsize; // Size of records contained within the section
};
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+template <endianness TargetEndianness>
+struct Elf_Shdr_Base<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
Elf_Word sh_name; // Section name (index into string table)
Elf_Word sh_type; // Section type (SHT_*)
Elf_Xword sh_flags; // Section flags (SHF_*)
@@ -151,9 +129,9 @@ struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
template <class ELFT> struct Elf_Sym_Base;
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+template <endianness TargetEndianness>
+struct Elf_Sym_Base<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
Elf_Word st_name; // Symbol name (index into string table)
Elf_Addr st_value; // Value or address associated with the symbol
Elf_Word st_size; // Size of the symbol
@@ -162,9 +140,9 @@ struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > {
Elf_Half st_shndx; // Which section (header table index) it's defined in
};
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+template <endianness TargetEndianness>
+struct Elf_Sym_Base<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
Elf_Word st_name; // Symbol name (index into string table)
unsigned char st_info; // Symbol's type and binding attributes
unsigned char st_other; // Must be zero; reserved
@@ -176,6 +154,7 @@ struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > {
template <class ELFT>
struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
using Elf_Sym_Base<ELFT>::st_info;
+ using Elf_Sym_Base<ELFT>::st_shndx;
using Elf_Sym_Base<ELFT>::st_other;
// These accessors and mutators correspond to the ELF32_ST_BIND,
@@ -198,6 +177,25 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
assert(v < 4 && "Invalid value for visibility");
st_other = (st_other & ~0x3) | v;
}
+
+ bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
+ bool isCommon() const {
+ return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
+ }
+ bool isDefined() const {
+ return !isUndefined() &&
+ !(st_shndx >= ELF::SHN_LORESERVE && st_shndx < ELF::SHN_ABS);
+ }
+ bool isProcessorSpecific() const {
+ return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
+ }
+ bool isOSSpecific() const {
+ return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
+ }
+ bool isReserved() const {
+ return st_shndx > ELF::SHN_HIOS && st_shndx < ELF::SHN_ABS;
+ }
+ bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
};
/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
@@ -267,9 +265,9 @@ struct Elf_Vernaux_Impl {
/// table section (.dynamic) look like.
template <class ELFT> struct Elf_Dyn_Base;
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+template <endianness TargetEndianness>
+struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
Elf_Sword d_tag;
union {
Elf_Word d_val;
@@ -277,9 +275,9 @@ struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > {
} d_un;
};
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+template <endianness TargetEndianness>
+struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
Elf_Sxword d_tag;
union {
Elf_Xword d_val;
@@ -300,9 +298,9 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
// Elf_Rel: Elf Relocation
template <class ELFT, bool isRela> struct Elf_Rel_Base;
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+template <endianness TargetEndianness>
+struct Elf_Rel_Base<ELFType<TargetEndianness, false>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Word r_info; // Symbol table index and type of relocation to apply
@@ -316,9 +314,9 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> {
}
};
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+template <endianness TargetEndianness>
+struct Elf_Rel_Base<ELFType<TargetEndianness, true>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Xword r_info; // Symbol table index and type of relocation to apply
@@ -341,9 +339,9 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> {
}
};
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+template <endianness TargetEndianness>
+struct Elf_Rel_Base<ELFType<TargetEndianness, false>, true> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Word r_info; // Symbol table index and type of relocation to apply
Elf_Sword r_addend; // Compute value for relocatable field by adding this
@@ -358,9 +356,9 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> {
}
};
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+template <endianness TargetEndianness>
+struct Elf_Rel_Base<ELFType<TargetEndianness, true>, true> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Xword r_info; // Symbol table index and type of relocation to apply
Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
@@ -386,11 +384,10 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> {
template <class ELFT, bool isRela> struct Elf_Rel_Impl;
-template <endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
-struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>,
- isRela> : Elf_Rel_Base<
- ELFType<TargetEndianness, MaxAlign, true>, isRela> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+template <endianness TargetEndianness, bool isRela>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, isRela>
+ : Elf_Rel_Base<ELFType<TargetEndianness, true>, isRela> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
// and ELF64_R_INFO macros defined in the ELF specification:
@@ -411,11 +408,10 @@ struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>,
}
};
-template <endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
-struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>,
- isRela> : Elf_Rel_Base<
- ELFType<TargetEndianness, MaxAlign, false>, isRela> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+template <endianness TargetEndianness, bool isRela>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, isRela>
+ : Elf_Rel_Base<ELFType<TargetEndianness, false>, isRela> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
// These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
// and ELF32_R_INFO macros defined in the ELF specification:
@@ -463,9 +459,9 @@ struct Elf_Ehdr_Impl {
template <class ELFT> struct Elf_Phdr_Impl;
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+template <endianness TargetEndianness>
+struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
Elf_Word p_type; // Type of segment
Elf_Off p_offset; // FileOffset where segment is located, in bytes
Elf_Addr p_vaddr; // Virtual Address of beginning of segment
@@ -476,9 +472,9 @@ struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > {
Elf_Word p_align; // Segment alignment constraint
};
-template <endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+template <endianness TargetEndianness>
+struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
Elf_Word p_type; // Type of segment
Elf_Word p_flags; // Segment flags
Elf_Off p_offset; // FileOffset where segment is located, in bytes
@@ -493,17 +489,17 @@ struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > {
template <class ELFT>
struct Elf_Mips_RegInfo;
-template <llvm::support::endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Mips_RegInfo<ELFType<TargetEndianness, MaxAlign, false>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+template <llvm::support::endianness TargetEndianness>
+struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
Elf_Word ri_gprmask; // bit-mask of used general registers
Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
Elf_Addr ri_gp_value; // gp register value
};
-template <llvm::support::endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Mips_RegInfo<ELFType<TargetEndianness, MaxAlign, true>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+template <llvm::support::endianness TargetEndianness>
+struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
Elf_Word ri_gprmask; // bit-mask of used general registers
Elf_Word ri_pad; // unused padding field
Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h
index 90c2bd74b43c..c9db1b80b916 100644
--- a/include/llvm/Object/Error.h
+++ b/include/llvm/Object/Error.h
@@ -22,12 +22,15 @@ namespace object {
const std::error_category &object_category();
enum class object_error {
- success = 0,
- arch_not_found,
+ // Error code 0 is absent. Use std::error_code() instead.
+ arch_not_found = 1,
invalid_file_type,
parse_failed,
unexpected_eof,
bitcode_section_not_found,
+ macho_small_load_command,
+ macho_load_segment_too_many_sections,
+ macho_load_segment_too_small,
};
inline std::error_code make_error_code(object_error e) {
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index 0a9b62c9055f..b163534fd9df 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -190,6 +190,8 @@ public:
const char *Ptr; // Where in memory the load command is.
MachO::load_command C; // The command itself.
};
+ typedef SmallVector<LoadCommandInfo, 4> LoadCommandList;
+ typedef LoadCommandList::const_iterator load_command_iterator;
MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
std::error_code &EC);
@@ -204,9 +206,8 @@ public:
std::error_code getSymbolAddress(DataRefImpl Symb,
uint64_t &Res) const override;
- std::error_code getSymbolAlignment(DataRefImpl Symb,
- uint32_t &Res) const override;
- std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
+ uint64_t getSymbolSize(DataRefImpl Symb) const override;
std::error_code getSymbolType(DataRefImpl Symb,
SymbolRef::Type &Res) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
@@ -241,11 +242,9 @@ public:
std::error_code
getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const override;
- std::error_code
- getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
std::error_code getRelocationHidden(DataRefImpl Rel,
bool &Result) const override;
+ uint8_t getRelocationLength(DataRefImpl Rel) const;
// MachO specific.
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const;
@@ -273,10 +272,14 @@ public:
dice_iterator begin_dices() const;
dice_iterator end_dices() const;
-
+
+ load_command_iterator begin_load_commands() const;
+ load_command_iterator end_load_commands() const;
+ iterator_range<load_command_iterator> load_commands() const;
+
/// For use iterating over all exported symbols.
iterator_range<export_iterator> exports() const;
-
+
/// For use examining a trie not in a MachOObjectFile.
static iterator_range<export_iterator> exports(ArrayRef<uint8_t> Trie);
@@ -329,10 +332,6 @@ public:
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const;
SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const;
- // Walk load commands.
- LoadCommandInfo getFirstLoadCommandInfo() const;
- LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const;
-
// MachO specific structures.
MachO::section getSection(DataRefImpl DRI) const;
MachO::section_64 getSection64(DataRefImpl DRI) const;
@@ -386,8 +385,8 @@ public:
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
- MachO::mach_header getHeader() const;
- MachO::mach_header_64 getHeader64() const;
+ const MachO::mach_header &getHeader() const;
+ const MachO::mach_header_64 &getHeader64() const;
uint32_t
getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC,
unsigned Index) const;
@@ -430,10 +429,15 @@ public:
}
private:
+ union {
+ MachO::mach_header_64 Header64;
+ MachO::mach_header Header;
+ };
typedef SmallVector<const char*, 1> SectionList;
SectionList Sections;
typedef SmallVector<const char*, 1> LibraryList;
LibraryList Libraries;
+ LoadCommandList LoadCommands;
typedef SmallVector<StringRef, 1> LibraryShortName;
mutable LibraryShortName LibrariesShortNames;
const char *SymtabLoadCmd;
@@ -472,7 +476,7 @@ inline std::error_code DiceRef::getOffset(uint32_t &Result) const {
static_cast<const MachOObjectFile *>(OwningObject);
MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
Result = Dice.offset;
- return object_error::success;
+ return std::error_code();
}
inline std::error_code DiceRef::getLength(uint16_t &Result) const {
@@ -480,7 +484,7 @@ inline std::error_code DiceRef::getLength(uint16_t &Result) const {
static_cast<const MachOObjectFile *>(OwningObject);
MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
Result = Dice.length;
- return object_error::success;
+ return std::error_code();
}
inline std::error_code DiceRef::getKind(uint16_t &Result) const {
@@ -488,7 +492,7 @@ inline std::error_code DiceRef::getKind(uint16_t &Result) const {
static_cast<const MachOObjectFile *>(OwningObject);
MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
Result = Dice.kind;
- return object_error::success;
+ return std::error_code();
}
inline DataRefImpl DiceRef::getRawDataRefImpl() const {
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index 14cd082870b0..a1ae19ecdfed 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -66,11 +66,6 @@ public:
/// This is for display purposes only.
std::error_code getTypeName(SmallVectorImpl<char> &Result) const;
- /// @brief Get a string that represents the calculation of the value of this
- /// relocation.
- ///
- /// This is for display purposes only.
- std::error_code getValueString(SmallVectorImpl<char> &Result) const;
DataRefImpl getRawDataRefImpl() const;
const ObjectFile *getObjectFile() const;
@@ -146,8 +141,8 @@ public:
/// mapped).
std::error_code getAddress(uint64_t &Result) const;
/// @brief Get the alignment of this symbol as the actual value (not log 2).
- std::error_code getAlignment(uint32_t &Result) const;
- std::error_code getSize(uint64_t &Result) const;
+ uint32_t getAlignment() const;
+ uint64_t getSize() const;
std::error_code getType(SymbolRef::Type &Result) const;
std::error_code getOther(uint8_t &Result) const;
@@ -206,10 +201,8 @@ protected:
DataRefImpl Symb) const override;
virtual std::error_code getSymbolAddress(DataRefImpl Symb,
uint64_t &Res) const = 0;
- virtual std::error_code getSymbolAlignment(DataRefImpl Symb,
- uint32_t &Res) const;
- virtual std::error_code getSymbolSize(DataRefImpl Symb,
- uint64_t &Res) const = 0;
+ virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
+ virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
virtual std::error_code getSymbolType(DataRefImpl Symb,
SymbolRef::Type &Res) const = 0;
virtual std::error_code getSymbolSection(DataRefImpl Symb,
@@ -254,13 +247,10 @@ protected:
virtual std::error_code
getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const = 0;
- virtual std::error_code
- getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const = 0;
virtual std::error_code getRelocationHidden(DataRefImpl Rel,
bool &Result) const {
Result = false;
- return object_error::success;
+ return std::error_code();
}
public:
@@ -334,12 +324,12 @@ inline std::error_code SymbolRef::getAddress(uint64_t &Result) const {
return getObject()->getSymbolAddress(getRawDataRefImpl(), Result);
}
-inline std::error_code SymbolRef::getAlignment(uint32_t &Result) const {
- return getObject()->getSymbolAlignment(getRawDataRefImpl(), Result);
+inline uint32_t SymbolRef::getAlignment() const {
+ return getObject()->getSymbolAlignment(getRawDataRefImpl());
}
-inline std::error_code SymbolRef::getSize(uint64_t &Result) const {
- return getObject()->getSymbolSize(getRawDataRefImpl(), Result);
+inline uint64_t SymbolRef::getSize() const {
+ return getObject()->getSymbolSize(getRawDataRefImpl());
}
inline std::error_code SymbolRef::getSection(section_iterator &Result) const {
@@ -482,11 +472,6 @@ RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
}
-inline std::error_code
-RelocationRef::getValueString(SmallVectorImpl<char> &Result) const {
- return OwningObject->getRelocationValueString(RelocationPimpl, Result);
-}
-
inline std::error_code RelocationRef::getHidden(bool &Result) const {
return OwningObject->getRelocationHidden(RelocationPimpl, Result);
}
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index 91eafd55ad76..02ffda5642d5 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -19,9 +19,11 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
+#include "llvm/Support/MachO.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
@@ -52,6 +54,8 @@ public:
return visitELF(RelocType, R, Value);
if (isa<COFFObjectFile>(ObjToVisit))
return visitCOFF(RelocType, R, Value);
+ if (isa<MachOObjectFile>(ObjToVisit))
+ return visitMachO(RelocType, R, Value);
HasError = true;
return RelocToApply();
@@ -221,6 +225,20 @@ private:
return RelocToApply();
}
+ RelocToApply visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) {
+ switch (ObjToVisit.getArch()) {
+ default: break;
+ case Triple::x86_64:
+ switch (RelocType) {
+ default: break;
+ case MachO::X86_64_RELOC_UNSIGNED:
+ return visitMACHO_X86_64_UNSIGNED(R, Value);
+ }
+ }
+ HasError = true;
+ return RelocToApply();
+ }
+
int64_t getELFAddend32LE(RelocationRef R) {
const ELF32LEObjectFile *Obj = cast<ELF32LEObjectFile>(R.getObjectFile());
DataRefImpl DRI = R.getRawDataRefImpl();
@@ -252,6 +270,12 @@ private:
Obj->getRelocationAddend(DRI, Addend);
return Addend;
}
+
+ uint8_t getLengthMachO64(RelocationRef R) {
+ const MachOObjectFile *Obj = cast<MachOObjectFile>(R.getObjectFile());
+ return Obj->getRelocationLength(R.getRawDataRefImpl());
+ }
+
/// Operations
/// 386-ELF
@@ -413,6 +437,13 @@ private:
RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) {
return RelocToApply(Value, /*Width=*/8);
}
+
+ // X86_64 MachO
+ RelocToApply visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) {
+ uint8_t Length = getLengthMachO64(R);
+ Length = 1<<Length;
+ return RelocToApply(Value, Length);
+ }
};
}
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 7f54822d503f..b26af61a7c70 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -155,16 +155,6 @@ namespace COFF {
uint8_t NumberOfAuxSymbols;
};
- enum SymbolFlags {
- SF_TypeMask = 0x0000FFFF,
- SF_TypeShift = 0,
-
- SF_ClassMask = 0x00FF0000,
- SF_ClassShift = 16,
-
- SF_WeakExternal = 0x01000000
- };
-
enum SymbolSectionNumber : int32_t {
IMAGE_SYM_DEBUG = -2,
IMAGE_SYM_ABSOLUTE = -1,
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index bd1d1cb6dc97..1ad8a3bfd937 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -1284,24 +1284,81 @@ public:
}
};
-// Define how to hold a class type object, such as a string. Since we can
-// inherit from a class, we do so. This makes us exactly compatible with the
-// object in all cases that it is used.
+// Define how to hold a class type object, such as a string.
+// Originally this code inherited from std::vector. In transitioning to a new
+// API for command line options we should change this. The new implementation
+// of this list_storage specialization implements the minimum subset of the
+// std::vector API required for all the current clients.
//
-template <class DataType>
-class list_storage<DataType, bool> : public std::vector<DataType> {
+// FIXME: Reduce this API to a more narrow subset of std::vector
+//
+template <class DataType> class list_storage<DataType, bool> {
+ std::vector<DataType> Storage;
+
public:
- template <class T> void addValue(const T &V) {
- std::vector<DataType>::push_back(V);
+ typedef typename std::vector<DataType>::iterator iterator;
+
+ iterator begin() { return Storage.begin(); }
+ iterator end() { return Storage.end(); }
+
+ typedef typename std::vector<DataType>::const_iterator const_iterator;
+ const_iterator begin() const { return Storage.begin(); }
+ const_iterator end() const { return Storage.end(); }
+
+ typedef typename std::vector<DataType>::size_type size_type;
+ size_type size() const { return Storage.size(); }
+
+ bool empty() const { return Storage.empty(); }
+
+ void push_back(const DataType &value) { Storage.push_back(value); }
+ void push_back(DataType &&value) { Storage.push_back(value); }
+
+ typedef typename std::vector<DataType>::reference reference;
+ typedef typename std::vector<DataType>::const_reference const_reference;
+ reference operator[](size_type pos) { return Storage[pos]; }
+ const_reference operator[](size_type pos) const { return Storage[pos]; }
+
+ iterator erase(const_iterator pos) { return Storage.erase(pos); }
+ iterator erase(const_iterator first, const_iterator last) {
+ return Storage.erase(first, last);
+ }
+
+ iterator erase(iterator pos) { return Storage.erase(pos); }
+ iterator erase(iterator first, iterator last) {
+ return Storage.erase(first, last);
}
+
+ iterator insert(const_iterator pos, const DataType &value) {
+ return Storage.insert(pos, value);
+ }
+ iterator insert(const_iterator pos, DataType &&value) {
+ return Storage.insert(pos, value);
+ }
+
+ iterator insert(iterator pos, const DataType &value) {
+ return Storage.insert(pos, value);
+ }
+ iterator insert(iterator pos, DataType &&value) {
+ return Storage.insert(pos, value);
+ }
+
+ reference front() { return Storage.front(); }
+ const_reference front() const { return Storage.front(); }
+
+ operator std::vector<DataType>&() { return Storage; }
+ operator ArrayRef<DataType>() { return Storage; }
+ std::vector<DataType> *operator&() { return &Storage; }
+ const std::vector<DataType> *operator&() const { return &Storage; }
+
+ template <class T> void addValue(const T &V) { Storage.push_back(V); }
};
//===----------------------------------------------------------------------===//
// list - A list of command line options.
//
-template <class DataType, class Storage = bool,
+template <class DataType, class StorageClass = bool,
class ParserClass = parser<DataType>>
-class list : public Option, public list_storage<DataType, Storage> {
+class list : public Option, public list_storage<DataType, StorageClass> {
std::vector<unsigned> Positions;
ParserClass Parser;
@@ -1319,7 +1376,7 @@ class list : public Option, public list_storage<DataType, Storage> {
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
return true; // Parse Error!
- list_storage<DataType, Storage>::addValue(Val);
+ list_storage<DataType, StorageClass>::addValue(Val);
setPosition(pos);
Positions.push_back(pos);
return false;
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index c81fbaff9dba..67ef23d43c99 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -350,19 +350,6 @@
# define LLVM_ADDRESS_SANITIZER_BUILD 0
#endif
-/// \macro LLVM_IS_UNALIGNED_ACCESS_FAST
-/// \brief Is unaligned memory access fast on the host machine.
-///
-/// Don't specialize on alignment for platforms where unaligned memory accesses
-/// generates the same code as aligned memory accesses for common types.
-#if defined(_M_AMD64) || defined(_M_IX86) || defined(__amd64) || \
- defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || \
- defined(_X86_) || defined(__i386) || defined(__i386__)
-# define LLVM_IS_UNALIGNED_ACCESS_FAST 1
-#else
-# define LLVM_IS_UNALIGNED_ACCESS_FAST 0
-#endif
-
/// \brief Mark debug helper function definitions like dump() that should not be
/// stripped from debug builds.
// FIXME: Move this to a private config.h as it's not usable in public headers.
diff --git a/include/llvm/Support/ELFRelocs/Hexagon.def b/include/llvm/Support/ELFRelocs/Hexagon.def
index c9d35b8bd75e..a698ecb89e16 100644
--- a/include/llvm/Support/ELFRelocs/Hexagon.def
+++ b/include/llvm/Support/ELFRelocs/Hexagon.def
@@ -90,3 +90,11 @@ ELF_RELOC(R_HEX_IE_GOT_11_X, 82)
ELF_RELOC(R_HEX_TPREL_32_6_X, 83)
ELF_RELOC(R_HEX_TPREL_16_X, 84)
ELF_RELOC(R_HEX_TPREL_11_X, 85)
+ELF_RELOC(R_HEX_LD_PLT_B22_PCREL, 86)
+ELF_RELOC(R_HEX_LD_GOT_LO16, 87)
+ELF_RELOC(R_HEX_LD_GOT_HI16, 88)
+ELF_RELOC(R_HEX_LD_GOT_32, 89)
+ELF_RELOC(R_HEX_LD_GOT_16, 90)
+ELF_RELOC(R_HEX_LD_GOT_32_6_X, 91)
+ELF_RELOC(R_HEX_LD_GOT_16_X, 92)
+ELF_RELOC(R_HEX_LD_GOT_11_X, 93)
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index e3166165a483..2cf7e0e5d0b3 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -562,7 +562,7 @@ inline uint64_t MinAlign(uint64_t A, uint64_t B) {
///
/// Alignment should be a power of two. This method rounds up, so
/// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8.
-inline uintptr_t alignAddr(void *Addr, size_t Alignment) {
+inline uintptr_t alignAddr(const void *Addr, size_t Alignment) {
assert(Alignment && isPowerOf2_64((uint64_t)Alignment) &&
"Alignment is not a power of two!");
@@ -573,7 +573,7 @@ inline uintptr_t alignAddr(void *Addr, size_t Alignment) {
/// \brief Returns the necessary adjustment for aligning \c Ptr to \c Alignment
/// bytes, rounding up.
-inline size_t alignmentAdjustment(void *Ptr, size_t Alignment) {
+inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) {
return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr;
}
diff --git a/include/llvm/Support/TargetParser.h b/include/llvm/Support/TargetParser.h
index ca626f271d51..777ee2075d61 100644
--- a/include/llvm/Support/TargetParser.h
+++ b/include/llvm/Support/TargetParser.h
@@ -15,6 +15,10 @@
#ifndef LLVM_SUPPORT_TARGETPARSER_H
#define LLVM_SUPPORT_TARGETPARSER_H
+// FIXME: vector is used because that's what clang uses for subtarget feature
+// lists, but SmallVector would probably be better
+#include <vector>
+
namespace llvm {
class StringRef;
@@ -28,13 +32,16 @@ namespace ARM {
// FPU names.
enum FPUKind {
FK_INVALID = 0,
+ FK_NONE,
FK_VFP,
FK_VFPV2,
FK_VFPV3,
FK_VFPV3_D16,
FK_VFPV4,
FK_VFPV4_D16,
+ FK_FPV4_SP_D16,
FK_FPV5_D16,
+ FK_FPV5_SP_D16,
FK_FP_ARMV8,
FK_NEON,
FK_NEON_VFPV4,
@@ -44,6 +51,20 @@ namespace ARM {
FK_LAST
};
+ // An FPU name implies one of three levels of Neon support:
+ enum NeonSupportLevel {
+ NS_None = 0, ///< No Neon
+ NS_Neon, ///< Neon
+ NS_Crypto ///< Neon with Crypto
+ };
+
+ // An FPU name restricts the FPU in one of three ways:
+ enum FPURestriction {
+ FR_None = 0, ///< No restriction
+ FR_D16, ///< Only 16 D registers
+ FR_SP_D16 ///< Only single-precision instructions, with 16 D registers
+ };
+
// Arch names.
enum ArchKind {
AK_INVALID = 0,
@@ -53,34 +74,34 @@ namespace ARM {
AK_ARMV3M,
AK_ARMV4,
AK_ARMV4T,
- AK_ARMV5,
AK_ARMV5T,
AK_ARMV5TE,
+ AK_ARMV5TEJ,
AK_ARMV6,
- AK_ARMV6J,
AK_ARMV6K,
AK_ARMV6T2,
AK_ARMV6Z,
AK_ARMV6ZK,
AK_ARMV6M,
- AK_ARMV7,
+ AK_ARMV6SM,
AK_ARMV7A,
AK_ARMV7R,
AK_ARMV7M,
+ AK_ARMV7EM,
AK_ARMV8A,
AK_ARMV8_1A,
// Non-standard Arch names.
AK_IWMMXT,
AK_IWMMXT2,
AK_XSCALE,
+ AK_ARMV5,
AK_ARMV5E,
- AK_ARMV5TEJ,
- AK_ARMV6SM,
+ AK_ARMV6J,
AK_ARMV6HL,
+ AK_ARMV7,
AK_ARMV7L,
AK_ARMV7HL,
AK_ARMV7S,
- AK_ARMV7EM,
AK_LAST
};
@@ -92,8 +113,15 @@ namespace ARM {
AEK_FP,
AEK_HWDIV,
AEK_MP,
+ AEK_SIMD,
AEK_SEC,
AEK_VIRT,
+ // Unsupported extensions.
+ AEK_OS,
+ AEK_IWMMXT,
+ AEK_IWMMXT2,
+ AEK_MAVERICK,
+ AEK_XSCALE,
AEK_LAST
};
@@ -132,9 +160,16 @@ public:
// Information by ID
static const char * getFPUName(unsigned FPUKind);
+ static unsigned getFPUVersion(unsigned FPUKind);
+ static unsigned getFPUNeonSupportLevel(unsigned FPUKind);
+ static unsigned getFPURestriction(unsigned FPUKind);
+ // FIXME: This should be moved to TargetTuple once it exists
+ static bool getFPUFeatures(unsigned FPUKind,
+ std::vector<const char*> &Features);
static const char * getArchName(unsigned ArchKind);
- static unsigned getArchDefaultCPUArch(unsigned ArchKind);
- static const char * getArchDefaultCPUName(unsigned ArchKind);
+ static unsigned getArchAttr(unsigned ArchKind);
+ static const char * getCPUAttr(unsigned ArchKind);
+ static const char * getSubArch(unsigned ArchKind);
static const char * getArchExtName(unsigned ArchExtKind);
static const char * getDefaultCPU(StringRef Arch);
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index 408e908aa04c..837fc66f38af 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -91,7 +91,7 @@ public:
typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
- StringRef TT);
+ const Triple &TT);
typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL);
@@ -287,15 +287,15 @@ public:
/// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
/// target triple.
///
- /// \param Triple This argument is used to determine the target machine
+ /// \param TheTriple This argument is used to determine the target machine
/// feature set; it should always be provided. Generally this should be
/// either the target triple from the module, or the target triple of the
/// host if that does not exist.
MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI,
- StringRef Triple) const {
+ StringRef TheTriple) const {
if (!MCAsmInfoCtorFn)
return nullptr;
- return MCAsmInfoCtorFn(MRI, Triple);
+ return MCAsmInfoCtorFn(MRI, Triple(TheTriple));
}
/// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
@@ -889,7 +889,8 @@ template <class MCAsmInfoImpl> struct RegisterMCAsmInfo {
}
private:
- static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, StringRef TT) {
+ static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/,
+ const Triple &TT) {
return new MCAsmInfoImpl(TT);
}
};
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 3bdff2091809..c04294a5e87a 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -1090,6 +1090,9 @@ public:
bool setCurrentDocument();
bool nextDocument();
+ /// Returns the current node that's being parsed by the YAML Parser.
+ const Node *getCurrentNode() const;
+
private:
llvm::SourceMgr SrcMgr; // must be before Strm
std::unique_ptr<llvm::yaml::Stream> Strm;
@@ -1111,7 +1114,7 @@ private:
///
class Output : public IO {
public:
- Output(llvm::raw_ostream &, void *Ctxt=nullptr);
+ Output(llvm::raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
~Output() override;
bool outputting() override;
@@ -1167,6 +1170,7 @@ private:
};
llvm::raw_ostream &Out;
+ int WrapColumn;
SmallVector<InState, 8> StateStack;
int Column;
int ColumnAtFlowStart;
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index 75765557a776..14ad63603358 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -17,48 +17,20 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/SMLoc.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
namespace llvm {
-// RecTy subclasses.
-class BitRecTy;
-class BitsRecTy;
-class IntRecTy;
-class StringRecTy;
class ListRecTy;
-class DagRecTy;
-class RecordRecTy;
-
-// Init subclasses.
-class Init;
-class UnsetInit;
-class BitInit;
-class BitsInit;
-class IntInit;
-class StringInit;
-class ListInit;
-class UnOpInit;
-class BinOpInit;
-class TernOpInit;
-class DefInit;
-class DagInit;
-class TypedInit;
-class VarInit;
-class FieldInit;
-class VarBitInit;
-class VarListElementInit;
-
-// Other classes.
+struct MultiClass;
class Record;
class RecordVal;
-struct MultiClass;
class RecordKeeper;
//===----------------------------------------------------------------------===//
@@ -81,12 +53,11 @@ public:
private:
RecTyKind Kind;
std::unique_ptr<ListRecTy> ListTy;
- virtual void anchor();
public:
RecTyKind getRecTyKind() const { return Kind; }
- RecTy(RecTyKind K) : Kind(K), ListTy(nullptr) {}
+ RecTy(RecTyKind K) : Kind(K) {}
virtual ~RecTy() {}
virtual std::string getAsString() const = 0;
@@ -95,40 +66,10 @@ public:
/// typeIsConvertibleTo - Return true if all values of 'this' type can be
/// converted to the specified type.
- virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0;
+ virtual bool typeIsConvertibleTo(const RecTy *RHS) const;
/// getListTy - Returns the type representing list<this>.
ListRecTy *getListTy();
-
-public: // These methods should only be called from subclasses of Init
- virtual Init *convertValue( UnsetInit *UI) { return nullptr; }
- virtual Init *convertValue( BitInit *BI) { return nullptr; }
- virtual Init *convertValue( BitsInit *BI) { return nullptr; }
- virtual Init *convertValue( IntInit *II) { return nullptr; }
- virtual Init *convertValue(StringInit *SI) { return nullptr; }
- virtual Init *convertValue( ListInit *LI) { return nullptr; }
- virtual Init *convertValue( UnOpInit *UO) {
- return convertValue((TypedInit*)UO);
- }
- virtual Init *convertValue( BinOpInit *BO) {
- return convertValue((TypedInit*)BO);
- }
- virtual Init *convertValue( TernOpInit *TO) {
- return convertValue((TypedInit*)TO);
- }
- virtual Init *convertValue(VarBitInit *VB) { return nullptr; }
- virtual Init *convertValue( DefInit *DI) { return nullptr; }
- virtual Init *convertValue( DagInit *DI) { return nullptr; }
- virtual Init *convertValue( TypedInit *TI) { return nullptr; }
- virtual Init *convertValue( VarInit *VI) {
- return convertValue((TypedInit*)VI);
- }
- virtual Init *convertValue( FieldInit *FI) {
- return convertValue((TypedInit*)FI);
- }
-
-public:
- virtual bool baseClassOf(const RecTy*) const;
};
inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
@@ -149,20 +90,9 @@ public:
static BitRecTy *get() { return &Shared; }
- using RecTy::convertValue;
- Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
- Init *convertValue( BitInit *BI) override { return (Init*)BI; }
- Init *convertValue( BitsInit *BI) override;
- Init *convertValue( IntInit *II) override;
- Init *convertValue(VarBitInit *VB) override { return (Init*)VB; }
- Init *convertValue( TypedInit *TI) override;
-
std::string getAsString() const override { return "bit"; }
- bool typeIsConvertibleTo(const RecTy *RHS) const override {
- return RHS->baseClassOf(this);
- }
- bool baseClassOf(const RecTy*) const override;
+ bool typeIsConvertibleTo(const RecTy *RHS) const override;
};
/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
@@ -180,19 +110,9 @@ public:
unsigned getNumBits() const { return Size; }
- using RecTy::convertValue;
- Init *convertValue( UnsetInit *UI) override;
- Init *convertValue( BitInit *UI) override;
- Init *convertValue( BitsInit *BI) override;
- Init *convertValue( IntInit *II) override;
- Init *convertValue( TypedInit *TI) override;
-
std::string getAsString() const override;
- bool typeIsConvertibleTo(const RecTy *RHS) const override {
- return RHS->baseClassOf(this);
- }
- bool baseClassOf(const RecTy*) const override;
+ bool typeIsConvertibleTo(const RecTy *RHS) const override;
};
/// IntRecTy - 'int' - Represent an integer value of no particular size
@@ -208,20 +128,9 @@ public:
static IntRecTy *get() { return &Shared; }
- using RecTy::convertValue;
- Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
- Init *convertValue( BitInit *BI) override;
- Init *convertValue( BitsInit *BI) override;
- Init *convertValue( IntInit *II) override { return (Init*)II; }
- Init *convertValue( TypedInit *TI) override;
-
std::string getAsString() const override { return "int"; }
- bool typeIsConvertibleTo(const RecTy *RHS) const override {
- return RHS->baseClassOf(this);
- }
-
- bool baseClassOf(const RecTy*) const override;
+ bool typeIsConvertibleTo(const RecTy *RHS) const override;
};
/// StringRecTy - 'string' - Represent an string value
@@ -237,18 +146,7 @@ public:
static StringRecTy *get() { return &Shared; }
- using RecTy::convertValue;
- Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
- Init *convertValue(StringInit *SI) override { return (Init*)SI; }
- Init *convertValue( UnOpInit *UO) override;
- Init *convertValue( BinOpInit *BO) override;
- Init *convertValue( TypedInit *TI) override;
-
- std::string getAsString() const override { return "string"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const override {
- return RHS->baseClassOf(this);
- }
+ std::string getAsString() const override;
};
/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
@@ -267,18 +165,9 @@ public:
static ListRecTy *get(RecTy *T) { return T->getListTy(); }
RecTy *getElementType() const { return Ty; }
- using RecTy::convertValue;
- Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
- Init *convertValue( ListInit *LI) override;
- Init *convertValue( TypedInit *TI) override;
-
std::string getAsString() const override;
- bool typeIsConvertibleTo(const RecTy *RHS) const override {
- return RHS->baseClassOf(this);
- }
-
- bool baseClassOf(const RecTy*) const override;
+ bool typeIsConvertibleTo(const RecTy *RHS) const override;
};
/// DagRecTy - 'dag' - Represent a dag fragment
@@ -294,18 +183,7 @@ public:
static DagRecTy *get() { return &Shared; }
- using RecTy::convertValue;
- Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
- Init *convertValue( UnOpInit *UO) override;
- Init *convertValue( BinOpInit *BO) override;
- Init *convertValue( DagInit *DI) override { return (Init*)DI; }
- Init *convertValue( TypedInit *TI) override;
-
- std::string getAsString() const override { return "dag"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const override {
- return RHS->baseClassOf(this);
- }
+ std::string getAsString() const override;
};
/// RecordRecTy - '[classname]' - Represent an instance of a class, such as:
@@ -325,17 +203,9 @@ public:
Record *getRecord() const { return Rec; }
- using RecTy::convertValue;
- Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
- Init *convertValue( DefInit *DI) override;
- Init *convertValue( TypedInit *TI) override;
-
std::string getAsString() const override;
- bool typeIsConvertibleTo(const RecTy *RHS) const override {
- return RHS->baseClassOf(this);
- }
- bool baseClassOf(const RecTy*) const override;
+ bool typeIsConvertibleTo(const RecTy *RHS) const override;
};
/// resolveTypes - Find a common type that T1 and T2 convert to.
@@ -418,10 +288,8 @@ public:
/// invokes print on stderr.
void dump() const;
- /// convertInitializerTo - This virtual function is a simple call-back
- /// function that should be overridden to call the appropriate
- /// RecTy::convertValue method.
- ///
+ /// convertInitializerTo - This virtual function converts to the appropriate
+ /// Init based on the passed in type.
virtual Init *convertInitializerTo(RecTy *Ty) const = 0;
/// convertInitializerBitRange - This method is used to implement the bitrange
@@ -511,6 +379,8 @@ public:
}
RecTy *getType() const { return Ty; }
+ Init *convertInitializerTo(RecTy *Ty) const override;
+
Init *
convertInitializerBitRange(const std::vector<unsigned> &Bits) const override;
Init *
@@ -535,7 +405,6 @@ class UnsetInit : public Init {
UnsetInit() : Init(IK_UnsetInit) {}
UnsetInit(const UnsetInit &) = delete;
UnsetInit &operator=(const UnsetInit &Other) = delete;
- void anchor() override;
public:
static bool classof(const Init *I) {
@@ -543,9 +412,7 @@ public:
}
static UnsetInit *get();
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<UnsetInit *>(this));
- }
+ Init *convertInitializerTo(RecTy *Ty) const override;
Init *getBit(unsigned Bit) const override {
return const_cast<UnsetInit*>(this);
@@ -563,7 +430,6 @@ class BitInit : public Init {
explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {}
BitInit(const BitInit &Other) = delete;
BitInit &operator=(BitInit &Other) = delete;
- void anchor() override;
public:
static bool classof(const Init *I) {
@@ -573,9 +439,7 @@ public:
bool getValue() const { return Value; }
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<BitInit *>(this));
- }
+ Init *convertInitializerTo(RecTy *Ty) const override;
Init *getBit(unsigned Bit) const override {
assert(Bit < 1 && "Bit index out of range!");
@@ -608,9 +472,7 @@ public:
unsigned getNumBits() const { return Bits.size(); }
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<BitsInit *>(this));
- }
+ Init *convertInitializerTo(RecTy *Ty) const override;
Init *
convertInitializerBitRange(const std::vector<unsigned> &Bits) const override;
@@ -661,9 +523,7 @@ public:
int64_t getValue() const { return Value; }
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<IntInit *>(this));
- }
+ Init *convertInitializerTo(RecTy *Ty) const override;
Init *
convertInitializerBitRange(const std::vector<unsigned> &Bits) const override;
@@ -692,7 +552,6 @@ class StringInit : public TypedInit {
StringInit(const StringInit &Other) = delete;
StringInit &operator=(const StringInit &Other) = delete;
- void anchor() override;
public:
static bool classof(const Init *I) {
@@ -702,9 +561,7 @@ public:
const std::string &getValue() const { return Value; }
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<StringInit *>(this));
- }
+ Init *convertInitializerTo(RecTy *Ty) const override;
std::string getAsString() const override { return "\"" + Value + "\""; }
std::string getAsUnquotedString() const override { return Value; }
@@ -746,7 +603,6 @@ public:
void Profile(FoldingSetNodeID &ID) const;
- unsigned getSize() const { return Values.size(); }
Init *getElement(unsigned i) const {
assert(i < Values.size() && "List element index out of range!");
return Values[i];
@@ -757,9 +613,7 @@ public:
Init *
convertInitListSlice(const std::vector<unsigned> &Elements) const override;
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<ListInit *>(this));
- }
+ Init *convertInitializerTo(RecTy *Ty) const override;
/// resolveReferences - This method is used by classes that refer to other
/// variables which may not be defined at the time they expression is formed.
@@ -772,10 +626,11 @@ public:
ArrayRef<Init*> getValues() const { return Values; }
- inline const_iterator begin() const { return Values.begin(); }
- inline const_iterator end () const { return Values.end(); }
+ const_iterator begin() const { return Values.begin(); }
+ const_iterator end () const { return Values.end(); }
- inline bool empty() const { return Values.empty(); }
+ size_t size () const { return Values.size(); }
+ bool empty() const { return Values.empty(); }
/// resolveListElementReference - This method is used to implement
/// VarListElementInit::resolveReferences. If the list element is resolvable
@@ -805,17 +660,13 @@ public:
// Clone - Clone this operator, replacing arguments with the new list
virtual OpInit *clone(std::vector<Init *> &Operands) const = 0;
- virtual int getNumOperands() const = 0;
- virtual Init *getOperand(int i) const = 0;
+ virtual unsigned getNumOperands() const = 0;
+ virtual Init *getOperand(unsigned i) const = 0;
// Fold - If possible, fold this to a simpler init. Return this if not
// possible to fold.
virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0;
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<OpInit *>(this));
- }
-
Init *resolveListElementReference(Record &R, const RecordVal *RV,
unsigned Elt) const override;
@@ -851,8 +702,8 @@ public:
return UnOpInit::get(getOpcode(), *Operands.begin(), getType());
}
- int getNumOperands() const override { return 1; }
- Init *getOperand(int i) const override {
+ unsigned getNumOperands() const override { return 1; }
+ Init *getOperand(unsigned i) const override {
assert(i == 0 && "Invalid operand id for unary operator");
return getOperand();
}
@@ -899,13 +750,12 @@ public:
return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType());
}
- int getNumOperands() const override { return 2; }
- Init *getOperand(int i) const override {
- assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
- if (i == 0) {
- return getLHS();
- } else {
- return getRHS();
+ unsigned getNumOperands() const override { return 2; }
+ Init *getOperand(unsigned i) const override {
+ switch (i) {
+ default: llvm_unreachable("Invalid operand id for binary operator");
+ case 0: return getLHS();
+ case 1: return getRHS();
}
}
@@ -955,16 +805,13 @@ public:
getType());
}
- int getNumOperands() const override { return 3; }
- Init *getOperand(int i) const override {
- assert((i == 0 || i == 1 || i == 2) &&
- "Invalid operand id for ternary operator");
- if (i == 0) {
- return getLHS();
- } else if (i == 1) {
- return getMHS();
- } else {
- return getRHS();
+ unsigned getNumOperands() const override { return 3; }
+ Init *getOperand(unsigned i) const override {
+ switch (i) {
+ default: llvm_unreachable("Invalid operand id for ternary operator");
+ case 0: return getLHS();
+ case 1: return getMHS();
+ case 2: return getRHS();
}
}
@@ -1004,10 +851,6 @@ public:
static VarInit *get(const std::string &VN, RecTy *T);
static VarInit *get(Init *VN, RecTy *T);
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<VarInit *>(this));
- }
-
const std::string &getName() const;
Init *getNameInit() const { return VarName; }
std::string getNameInitAsString() const {
@@ -1056,9 +899,7 @@ public:
}
static VarBitInit *get(TypedInit *T, unsigned B);
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<VarBitInit *>(this));
- }
+ Init *convertInitializerTo(RecTy *Ty) const override;
Init *getBitVar() const override { return TI; }
unsigned getBitNum() const override { return Bit; }
@@ -1095,10 +936,6 @@ public:
}
static VarListElementInit *get(TypedInit *T, unsigned E);
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<VarListElementInit *>(this));
- }
-
TypedInit *getVariable() const { return TI; }
unsigned getElementNum() const { return Element; }
@@ -1131,9 +968,7 @@ public:
}
static DefInit *get(Record*);
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<DefInit *>(this));
- }
+ Init *convertInitializerTo(RecTy *Ty) const override;
Record *getDef() const { return Def; }
@@ -1179,10 +1014,6 @@ public:
static FieldInit *get(Init *R, const std::string &FN);
static FieldInit *get(Init *R, const Init *FN);
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<FieldInit *>(this));
- }
-
Init *getBit(unsigned Bit) const override;
Init *resolveListElementReference(Record &R, const RecordVal *RV,
@@ -1228,9 +1059,7 @@ public:
void Profile(FoldingSetNodeID &ID) const;
- Init *convertInitializerTo(RecTy *Ty) const override {
- return Ty->convertValue(const_cast<DagInit *>(this));
- }
+ Init *convertInitializerTo(RecTy *Ty) const override;
Init *getOperator() const { return Val; }
@@ -1280,22 +1109,21 @@ public:
//===----------------------------------------------------------------------===//
class RecordVal {
- Init *Name;
+ PointerIntPair<Init *, 1, bool> NameAndPrefix;
RecTy *Ty;
- unsigned Prefix;
Init *Value;
public:
- RecordVal(Init *N, RecTy *T, unsigned P);
- RecordVal(const std::string &N, RecTy *T, unsigned P);
+ RecordVal(Init *N, RecTy *T, bool P);
+ RecordVal(const std::string &N, RecTy *T, bool P);
const std::string &getName() const;
- const Init *getNameInit() const { return Name; }
+ const Init *getNameInit() const { return NameAndPrefix.getPointer(); }
std::string getNameInitAsString() const {
return getNameInit()->getAsUnquotedString();
}
- unsigned getPrefix() const { return Prefix; }
+ bool getPrefix() const { return NameAndPrefix.getInt(); }
RecTy *getType() const { return Ty; }
Init *getValue() const { return Value; }
@@ -1344,7 +1172,7 @@ class Record {
// def Def : Class<Struct<i>>;
//
// These need to get fully resolved before instantiating any other
- // definitions that usie them (e.g. Def). However, inside a multiclass they
+ // definitions that use them (e.g. Def). However, inside a multiclass they
// can't be immediately resolved so we mark them ResolveFirst to fully
// resolve them later as soon as the multiclass is instantiated.
bool ResolveFirst;
@@ -1354,13 +1182,6 @@ class Record {
public:
// Constructs a record.
- explicit Record(const std::string &N, ArrayRef<SMLoc> locs,
- RecordKeeper &records, bool Anonymous = false) :
- ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()),
- TrackedRecords(records), TheInit(nullptr), IsAnonymous(Anonymous),
- ResolveFirst(false) {
- init();
- }
explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
bool Anonymous = false) :
ID(LastID++), Name(N), Locs(locs.begin(), locs.end()),
@@ -1368,6 +1189,10 @@ public:
ResolveFirst(false) {
init();
}
+ explicit Record(const std::string &N, ArrayRef<SMLoc> locs,
+ RecordKeeper &records, bool Anonymous = false)
+ : Record(StringInit::get(N), locs, records, Anonymous) {}
+
// When copy-constructing a Record, we must still guarantee a globally unique
// ID number. All other fields can be copied normally.
@@ -1406,8 +1231,8 @@ public:
ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; }
bool isTemplateArg(Init *Name) const {
- for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
- if (TemplateArgs[i] == Name) return true;
+ for (Init *TA : TemplateArgs)
+ if (TA == Name) return true;
return false;
}
bool isTemplateArg(StringRef Name) const {
@@ -1415,16 +1240,16 @@ public:
}
const RecordVal *getValue(const Init *Name) const {
- for (unsigned i = 0, e = Values.size(); i != e; ++i)
- if (Values[i].getNameInit() == Name) return &Values[i];
+ for (const RecordVal &Val : Values)
+ if (Val.getNameInit() == Name) return &Val;
return nullptr;
}
const RecordVal *getValue(StringRef Name) const {
return getValue(StringInit::get(Name));
}
RecordVal *getValue(const Init *Name) {
- for (unsigned i = 0, e = Values.size(); i != e; ++i)
- if (Values[i].getNameInit() == Name) return &Values[i];
+ for (RecordVal &Val : Values)
+ if (Val.getNameInit() == Name) return &Val;
return nullptr;
}
RecordVal *getValue(StringRef Name) {
@@ -1465,15 +1290,15 @@ public:
}
bool isSubClassOf(const Record *R) const {
- for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
- if (SuperClasses[i] == R)
+ for (const Record *SC : SuperClasses)
+ if (SC == R)
return true;
return false;
}
bool isSubClassOf(StringRef Name) const {
- for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
- if (SuperClasses[i]->getNameInitAsString() == Name)
+ for (const Record *SC : SuperClasses)
+ if (SC->getNameInitAsString() == Name)
return true;
return false;
}
@@ -1523,7 +1348,7 @@ public:
/// Return true if the named field is unset.
bool isValueUnset(StringRef FieldName) const {
- return getValueInit(FieldName) == UnsetInit::get();
+ return isa<UnsetInit>(getValueInit(FieldName));
}
/// getValueAsString - This method looks up the specified field and returns
@@ -1675,7 +1500,6 @@ struct LessRecordFieldName {
};
struct LessRecordRegister {
- static size_t min(size_t a, size_t b) { return a < b ? a : b; }
static bool ascii_isdigit(char x) { return x >= '0' && x <= '9'; }
struct RecordParts {
diff --git a/include/llvm/TableGen/SetTheory.h b/include/llvm/TableGen/SetTheory.h
index 595c29f2ee1d..d4e0f53d3efa 100644
--- a/include/llvm/TableGen/SetTheory.h
+++ b/include/llvm/TableGen/SetTheory.h
@@ -47,9 +47,10 @@
#ifndef LLVM_TABLEGEN_SETTHEORY_H
#define LLVM_TABLEGEN_SETTHEORY_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/SMLoc.h"
#include <map>
#include <vector>
@@ -58,7 +59,6 @@ namespace llvm {
class DagInit;
class Init;
class Record;
-class RecordKeeper;
class SetTheory {
public:
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index ec8a12df9fc6..d99f0e1c5dc5 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -381,6 +381,7 @@ class Instruction {
bit hasPostISelHook = 0; // To be *adjusted* after isel by target hook.
bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains?
bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction?
+ bit isConvergent = 0; // Is this instruction convergent?
bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction.
bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement?
bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement?
@@ -506,7 +507,7 @@ class Requires<list<Predicate> preds> {
/// ops definition - This is just a simple marker used to identify the operand
/// list for an instruction. outs and ins are identical both syntactically and
-/// semanticallyr; they are used to define def operands and use operands to
+/// semantically; they are used to define def operands and use operands to
/// improve readibility. This should be used like this:
/// (outs R32:$dst), (ins R32:$src1, R32:$src2) or something similar.
def ops;
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 5ec15658b696..902b99c61044 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -711,20 +711,22 @@ protected:
/// Target-dependent implementation for foldMemoryOperand.
/// Target-independent code in foldMemoryOperand will
/// take care of adding a MachineMemOperand to the newly created instruction.
- virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF,
- MachineInstr *MI,
- ArrayRef<unsigned> Ops,
- int FrameIndex) const {
+ /// The instruction and any auxiliary instructions necessary will be inserted
+ /// at InsertPt.
+ virtual MachineInstr *foldMemoryOperandImpl(
+ MachineFunction &MF, MachineInstr *MI, ArrayRef<unsigned> Ops,
+ MachineBasicBlock::iterator InsertPt, int FrameIndex) const {
return nullptr;
}
/// Target-dependent implementation for foldMemoryOperand.
/// Target-independent code in foldMemoryOperand will
/// take care of adding a MachineMemOperand to the newly created instruction.
- virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF,
- MachineInstr *MI,
- ArrayRef<unsigned> Ops,
- MachineInstr *LoadMI) const {
+ /// The instruction and any auxiliary instructions necessary will be inserted
+ /// at InsertPt.
+ virtual MachineInstr *foldMemoryOperandImpl(
+ MachineFunction &MF, MachineInstr *MI, ArrayRef<unsigned> Ops,
+ MachineBasicBlock::iterator InsertPt, MachineInstr *LoadMI) const {
return nullptr;
}
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index e2fe9e85fc92..616edd8c2480 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -1431,7 +1431,8 @@ public:
/// load/store.
virtual bool GetAddrModeArguments(IntrinsicInst * /*I*/,
SmallVectorImpl<Value*> &/*Ops*/,
- Type *&/*AccessTy*/) const {
+ Type *&/*AccessTy*/,
+ unsigned AddrSpace = 0) const {
return false;
}
@@ -1456,7 +1457,12 @@ public:
/// The type may be VoidTy, in which case only return true if the addressing
/// mode is legal for a load/store of any legal type. TODO: Handle
/// pre/postinc as well.
- virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const;
+ ///
+ /// If the address space cannot be determined, it will be -1.
+ ///
+ /// TODO: Remove default argument
+ virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty,
+ unsigned AddrSpace) const;
/// \brief Return the cost of the scaling factor used in the addressing mode
/// represented by AM for this target, for a load/store of the specified type.
@@ -1464,9 +1470,12 @@ public:
/// If the AM is supported, the return value must be >= 0.
/// If the AM is not supported, it returns a negative value.
/// TODO: Handle pre/postinc as well.
- virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty) const {
+ /// TODO: Remove default argument
+ virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty,
+ unsigned AS = 0) const {
// Default: assume that any scaling factor used in a legal AM is free.
- if (isLegalAddressingMode(AM, Ty)) return 0;
+ if (isLegalAddressingMode(AM, Ty, AS))
+ return 0;
return -1;
}
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index 07a8f6d3d4cd..8f8b78d9b0b1 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -15,6 +15,7 @@
#ifndef LLVM_TARGET_TARGETOPTIONS_H
#define LLVM_TARGET_TARGETOPTIONS_H
+#include "llvm/Target/TargetRecip.h"
#include "llvm/MC/MCTargetOptions.h"
#include <string>
@@ -72,7 +73,8 @@ namespace llvm {
CompressDebugSections(false), FunctionSections(false),
DataSections(false), UniqueSectionNames(true), TrapUnreachable(false),
TrapFuncName(), FloatABIType(FloatABI::Default),
- AllowFPOpFusion(FPOpFusion::Standard), JTType(JumpTable::Single),
+ AllowFPOpFusion(FPOpFusion::Standard), Reciprocals(TargetRecip()),
+ JTType(JumpTable::Single),
ThreadModel(ThreadModel::POSIX) {}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
@@ -206,6 +208,9 @@ namespace llvm {
/// the value of this option.
FPOpFusion::FPOpFusionMode AllowFPOpFusion;
+ /// This class encapsulates options for reciprocal-estimate code generation.
+ TargetRecip Reciprocals;
+
/// JTType - This flag specifies the type of jump-instruction table to
/// create for functions that have the jumptable attribute.
JumpTable::JumpTableType JTType;
@@ -240,6 +245,7 @@ inline bool operator==(const TargetOptions &LHS,
ARE_EQUAL(TrapFuncName) &&
ARE_EQUAL(FloatABIType) &&
ARE_EQUAL(AllowFPOpFusion) &&
+ ARE_EQUAL(Reciprocals) &&
ARE_EQUAL(JTType) &&
ARE_EQUAL(ThreadModel) &&
ARE_EQUAL(MCOptions);
diff --git a/include/llvm/Target/TargetRecip.h b/include/llvm/Target/TargetRecip.h
new file mode 100644
index 000000000000..4cc3672d758d
--- /dev/null
+++ b/include/llvm/Target/TargetRecip.h
@@ -0,0 +1,73 @@
+//===--------------------- llvm/Target/TargetRecip.h ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class is used to customize machine-specific reciprocal estimate code
+// generation in a target-independent way.
+// If a target does not support operations in this specification, then code
+// generation will default to using supported operations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETRECIP_H
+#define LLVM_TARGET_TARGETRECIP_H
+
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+#include <string>
+#include <map>
+
+namespace llvm {
+
+struct TargetRecip {
+public:
+ TargetRecip();
+
+ /// Initialize all or part of the operations from command-line options or
+ /// a front end.
+ TargetRecip(const std::vector<std::string> &Args);
+
+ /// Set whether a particular reciprocal operation is enabled and how many
+ /// refinement steps are needed when using it. Use "all" to set enablement
+ /// and refinement steps for all operations.
+ void setDefaults(const StringRef &Key, bool Enable, unsigned RefSteps);
+
+ /// Return true if the reciprocal operation has been enabled by default or
+ /// from the command-line. Return false if the operation has been disabled
+ /// by default or from the command-line.
+ bool isEnabled(const StringRef &Key) const;
+
+ /// Return the number of iterations necessary to refine the
+ /// the result of a machine instruction for the given reciprocal operation.
+ unsigned getRefinementSteps(const StringRef &Key) const;
+
+ bool operator==(const TargetRecip &Other) const;
+
+private:
+ enum {
+ Uninitialized = -1
+ };
+
+ struct RecipParams {
+ int8_t Enabled;
+ int8_t RefinementSteps;
+
+ RecipParams() : Enabled(Uninitialized), RefinementSteps(Uninitialized) {}
+ };
+
+ std::map<StringRef, RecipParams> RecipMap;
+ typedef std::map<StringRef, RecipParams>::iterator RecipIter;
+ typedef std::map<StringRef, RecipParams>::const_iterator ConstRecipIter;
+
+ bool parseGlobalParams(const std::string &Arg);
+ void parseIndividualParams(const std::vector<std::string> &Args);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index c4669f121e6a..4676c95d7cd4 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -16,10 +16,12 @@
#define LLVM_TRANSFORMS_SCALAR_H
#include "llvm/ADT/StringRef.h"
+#include <functional>
namespace llvm {
class BasicBlockPass;
+class Function;
class FunctionPass;
class ModulePass;
class Pass;
@@ -152,7 +154,14 @@ Pass *createLoopInterchangePass();
//
Pass *createLoopStrengthReducePass();
-Pass *createGlobalMergePass(const TargetMachine *TM, unsigned MaximalOffset);
+//===----------------------------------------------------------------------===//
+//
+// GlobalMerge - This pass merges internal (by default) globals into structs
+// to enable reuse of a base pointer by indexed addressing modes.
+// It can also be configured to focus on size optimizations only.
+//
+Pass *createGlobalMergePass(const TargetMachine *TM, unsigned MaximalOffset,
+ bool OnlyOptimizeForSize = false);
//===----------------------------------------------------------------------===//
//
@@ -238,7 +247,8 @@ FunctionPass *createJumpThreadingPass(int Threshold = -1);
// CFGSimplification - Merge basic blocks, eliminate unreachable blocks,
// simplify terminator instructions, etc...
//
-FunctionPass *createCFGSimplificationPass(int Threshold = -1);
+FunctionPass *createCFGSimplificationPass(
+ int Threshold = -1, std::function<bool(const Function &)> Ftor = nullptr);
//===----------------------------------------------------------------------===//
//
@@ -456,7 +466,7 @@ FunctionPass *createPlaceSafepointsPass();
// RewriteStatepointsForGC - Rewrite any gc.statepoints which do not yet have
// explicit relocations to include explicit relocations.
//
-FunctionPass *createRewriteStatepointsForGCPass();
+ModulePass *createRewriteStatepointsForGCPass();
//===----------------------------------------------------------------------===//
//