aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-08-07 15:07:10 -0700
committerStephen Hines <srhines@google.com>2013-08-07 15:07:10 -0700
commitfab2daa4a1127ecb217abe2b07c1769122b6fee1 (patch)
tree268ebfd1963fd98ba412e76819afdf95a7d4267b /include
parent8197ac1c1a0a91baa70c4dea8cb488f254ef974c (diff)
parent10251753b6897adcd22cc981c0cc42f348c109de (diff)
downloadexternal_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.zip
external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.tar.gz
external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.tar.bz2
Merge commit '10251753b6897adcd22cc981c0cc42f348c109de' into merge-20130807
Conflicts: lib/Archive/ArchiveReader.cpp lib/Support/Unix/PathV2.inc Change-Id: I29d8c1e321a4a380b6013f00bac6a8e4b593cc4e
Diffstat (limited to 'include')
-rw-r--r--include/llvm/ADT/APFloat.h51
-rw-r--r--include/llvm/ADT/APInt.h8
-rw-r--r--include/llvm/ADT/IntervalMap.h4
-rw-r--r--include/llvm/ADT/NullablePtr.h52
-rw-r--r--include/llvm/ADT/SmallBitVector.h34
-rw-r--r--include/llvm/ADT/StringRef.h6
-rw-r--r--include/llvm/ADT/Triple.h9
-rw-r--r--include/llvm/Analysis/BlockFrequencyImpl.h115
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfo.h10
-rw-r--r--include/llvm/Analysis/CFG.h69
-rw-r--r--include/llvm/Analysis/DependenceAnalysis.h38
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h2
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h14
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h4
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h12
-rw-r--r--include/llvm/AutoUpgrade.h14
-rw-r--r--include/llvm/Bitcode/Archive.h539
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h41
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h17
-rw-r--r--include/llvm/CodeGen/CalcSpillWeights.h7
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h4
-rw-r--r--include/llvm/CodeGen/CommandFlags.h14
-rw-r--r--include/llvm/CodeGen/FastISel.h275
-rw-r--r--include/llvm/CodeGen/FunctionLoweringInfo.h8
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h14
-rw-r--r--include/llvm/CodeGen/LexicalScopes.h18
-rw-r--r--include/llvm/CodeGen/LiveInterval.h2
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h3
-rw-r--r--include/llvm/CodeGen/LiveRangeEdit.h11
-rw-r--r--include/llvm/CodeGen/LiveVariables.h4
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h5
-rw-r--r--include/llvm/CodeGen/MachineConstantPool.h10
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h13
-rw-r--r--include/llvm/CodeGen/MachineInstr.h5
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h45
-rw-r--r--include/llvm/CodeGen/MachineOperand.h2
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h21
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h1
-rw-r--r--include/llvm/CodeGen/Passes.h11
-rw-r--r--include/llvm/CodeGen/RegAllocPBQP.h6
-rw-r--r--include/llvm/CodeGen/RegisterClassInfo.h15
-rw-r--r--include/llvm/CodeGen/RegisterPressure.h41
-rw-r--r--include/llvm/CodeGen/RegisterScavenging.h4
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h31
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h2
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h27
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h10
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h15
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h11
-rw-r--r--include/llvm/CodeGen/TargetSchedule.h28
-rw-r--r--include/llvm/CodeGen/ValueTypes.h6
-rw-r--r--include/llvm/Config/config.h.cmake116
-rw-r--r--include/llvm/Config/config.h.in83
-rw-r--r--include/llvm/DIBuilder.h53
-rw-r--r--include/llvm/DebugInfo.h326
-rw-r--r--include/llvm/DebugInfo/DIContext.h10
-rw-r--r--include/llvm/ExecutionEngine/ObjectCache.h20
-rw-r--r--include/llvm/IR/Argument.h5
-rw-r--r--include/llvm/IR/Attributes.h4
-rw-r--r--include/llvm/IR/CallingConv.h18
-rw-r--r--include/llvm/IR/Constants.h2
-rw-r--r--include/llvm/IR/DataLayout.h19
-rw-r--r--include/llvm/IR/Function.h48
-rw-r--r--include/llvm/IR/IRBuilder.h25
-rw-r--r--include/llvm/IR/InstrTypes.h18
-rw-r--r--include/llvm/IR/Instructions.h36
-rw-r--r--include/llvm/IR/Intrinsics.td22
-rw-r--r--include/llvm/IR/IntrinsicsAArch64.td41
-rw-r--r--include/llvm/IR/IntrinsicsARM.td33
-rw-r--r--include/llvm/IR/IntrinsicsNVVM.td2
-rw-r--r--include/llvm/IR/IntrinsicsX86.td39
-rw-r--r--include/llvm/IR/IntrinsicsXCore.td12
-rw-r--r--include/llvm/IR/Metadata.h5
-rw-r--r--include/llvm/IR/Module.h17
-rw-r--r--include/llvm/IR/TypeBuilder.h2
-rw-r--r--include/llvm/InitializePasses.h3
-rw-r--r--include/llvm/LinkAllPasses.h2
-rw-r--r--include/llvm/MC/MCAsmInfo.h27
-rw-r--r--include/llvm/MC/MCContext.h28
-rw-r--r--include/llvm/MC/MCELFStreamer.h3
-rw-r--r--include/llvm/MC/MCExpr.h64
-rw-r--r--include/llvm/MC/MCInstPrinter.h22
-rw-r--r--include/llvm/MC/MCInstrDesc.h16
-rw-r--r--include/llvm/MC/MCInstrItineraries.h10
-rw-r--r--include/llvm/MC/MCObjectStreamer.h13
-rw-r--r--include/llvm/MC/MCSchedule.h66
-rw-r--r--include/llvm/MC/MCSectionCOFF.h26
-rw-r--r--include/llvm/MC/MCStreamer.h32
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h2
-rw-r--r--include/llvm/Object/Archive.h109
-rw-r--r--include/llvm/Object/Binary.h5
-rw-r--r--include/llvm/Object/COFF.h15
-rw-r--r--include/llvm/Object/ELF.h97
-rw-r--r--include/llvm/Object/ELFYAML.h71
-rw-r--r--include/llvm/Object/Error.h25
-rw-r--r--include/llvm/Object/MachO.h3
-rw-r--r--include/llvm/Object/MachOFormat.h18
-rw-r--r--include/llvm/Object/MachOUniversal.h102
-rw-r--r--include/llvm/Object/RelocVisitor.h6
-rw-r--r--include/llvm/Option/ArgList.h9
-rw-r--r--include/llvm/Option/OptParser.td6
-rw-r--r--include/llvm/Option/OptTable.h28
-rw-r--r--include/llvm/Option/Option.h10
-rw-r--r--include/llvm/Support/BlockFrequency.h20
-rw-r--r--include/llvm/Support/CFG.h4
-rw-r--r--include/llvm/Support/COFF.h18
-rw-r--r--include/llvm/Support/CallSite.h15
-rw-r--r--include/llvm/Support/Casting.h27
-rw-r--r--include/llvm/Support/CommandLine.h53
-rw-r--r--include/llvm/Support/Compiler.h56
-rw-r--r--include/llvm/Support/ConstantRange.h12
-rw-r--r--include/llvm/Support/ConvertUTF.h24
-rw-r--r--include/llvm/Support/DataTypes.h.cmake9
-rw-r--r--include/llvm/Support/DataTypes.h.in10
-rw-r--r--include/llvm/Support/Dwarf.h2
-rw-r--r--include/llvm/Support/ELF.h114
-rw-r--r--include/llvm/Support/FileSystem.h348
-rw-r--r--include/llvm/Support/FileUtilities.h5
-rw-r--r--include/llvm/Support/GraphWriter.h45
-rw-r--r--include/llvm/Support/IntegersSubset.h6
-rw-r--r--include/llvm/Support/LEB128.h18
-rw-r--r--include/llvm/Support/MathExtras.h16
-rw-r--r--include/llvm/Support/MemoryBuffer.h23
-rw-r--r--include/llvm/Support/Path.h1
-rw-r--r--include/llvm/Support/PathV1.h557
-rw-r--r--include/llvm/Support/PatternMatch.h9
-rw-r--r--include/llvm/Support/Program.h161
-rw-r--r--include/llvm/Support/Regex.h4
-rw-r--r--include/llvm/Support/Registry.h2
-rw-r--r--include/llvm/Support/Signals.h5
-rw-r--r--include/llvm/Support/SourceMgr.h14
-rw-r--r--include/llvm/Support/SystemUtils.h10
-rw-r--r--include/llvm/Support/TimeValue.h5
-rw-r--r--include/llvm/Support/ToolOutputFile.h4
-rw-r--r--include/llvm/Support/UnicodeCharRanges.h98
-rw-r--r--include/llvm/Support/YAMLTraits.h12
-rw-r--r--include/llvm/Support/raw_ostream.h19
-rw-r--r--include/llvm/TableGen/Record.h80
-rw-r--r--include/llvm/Target/Mangler.h5
-rw-r--r--include/llvm/Target/Target.td8
-rw-r--r--include/llvm/Target/TargetFrameLowering.h5
-rw-r--r--include/llvm/Target/TargetInstrInfo.h32
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h6
-rw-r--r--include/llvm/Target/TargetLowering.h1326
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h4
-rw-r--r--include/llvm/Target/TargetMachine.h3
-rw-r--r--include/llvm/Target/TargetOptions.h54
-rw-r--r--include/llvm/Target/TargetSchedule.td9
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h2
-rw-r--r--include/llvm/Transforms/Instrumentation.h35
-rw-r--r--include/llvm/Transforms/Scalar.h29
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h31
-rw-r--r--include/llvm/Transforms/Utils/BlackList.h59
-rw-r--r--include/llvm/Transforms/Utils/Local.h32
-rw-r--r--include/llvm/Transforms/Utils/ModuleUtils.h8
-rw-r--r--include/llvm/Transforms/Utils/PromoteMemToReg.h29
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdater.h104
-rw-r--r--include/llvm/Transforms/Utils/SpecialCaseList.h102
158 files changed, 3661 insertions, 3510 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index ffd8975..43a7866 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -21,9 +21,6 @@
namespace llvm {
-/// A signed type to represent a floating point numbers unbiased exponent.
-typedef signed short exponent_t;
-
struct fltSemantics;
class APSInt;
class StringRef;
@@ -120,11 +117,14 @@ enum lostFraction { // Example of truncated bits:
/// New formats: x87 in single and double precision mode (IEEE apart from
/// extended exponent range) (hard).
///
-/// New operations: sqrt, IEEE remainder, C90 fmod, nextafter, nexttoward.
+/// New operations: sqrt, IEEE remainder, C90 fmod, nexttoward.
///
class APFloat {
public:
+ /// A signed type to represent a floating point numbers unbiased exponent.
+ typedef signed short ExponentType;
+
/// \name Floating Point Semantics.
/// @{
@@ -191,7 +191,6 @@ public:
APFloat(const fltSemantics &); // Default construct to 0.0
APFloat(const fltSemantics &, StringRef);
APFloat(const fltSemantics &, integerPart);
- APFloat(const fltSemantics &, fltCategory, bool negative);
APFloat(const fltSemantics &, uninitializedTag);
APFloat(const fltSemantics &, const APInt &);
explicit APFloat(double d);
@@ -211,14 +210,18 @@ public:
///
/// \param Negative True iff the number should be negative.
static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
- return APFloat(Sem, fcZero, Negative);
+ APFloat Val(Sem, uninitialized);
+ Val.makeZero(Negative);
+ return Val;
}
/// Factory for Positive and Negative Infinity.
///
/// \param Negative True iff the number should be negative.
static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
- return APFloat(Sem, fcInfinity, Negative);
+ APFloat Val(Sem, uninitialized);
+ Val.makeInf(Negative);
+ return Val;
}
/// Factory for QNaN values.
@@ -300,6 +303,8 @@ public:
/// IEEE-754R 5.3.1: nextUp/nextDown.
opStatus next(bool nextDown);
+ /// @}
+
/// \name Sign operations.
/// @{
@@ -359,10 +364,7 @@ public:
///
/// This implies that the current value of the float is not zero, subnormal,
/// infinite, or NaN following the definition of normality from IEEE-754R.
- ///
- /// The current implementation of isNormal() differs from this by treating
- /// subnormal values as normal values.
- bool isIEEENormal() const { return !isDenormal() && isNormal(); }
+ bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
/// Returns true if and only if the current value is zero, subnormal, or
/// normal.
@@ -394,10 +396,18 @@ public:
fltCategory getCategory() const { return category; }
const fltSemantics &getSemantics() const { return *semantics; }
bool isNonZero() const { return category != fcZero; }
- bool isNormal() const { return category == fcNormal; }
+ bool isFiniteNonZero() const { return isFinite() && !isZero(); }
bool isPosZero() const { return isZero() && !isNegative(); }
bool isNegZero() const { return isZero() && isNegative(); }
+ /// Returns true if and only if the number has the smallest possible non-zero
+ /// magnitude in the current semantics.
+ bool isSmallest() const;
+
+ /// Returns true if and only if the number has the largest possible finite
+ /// magnitude in the current semantics.
+ bool isLargest() const;
+
/// @}
APFloat &operator=(const APFloat &);
@@ -491,24 +501,15 @@ private:
void makeNaN(bool SNaN = false, bool Neg = false, const APInt *fill = 0);
static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
const APInt *fill);
-
- /// @}
-
- /// \name Special value queries only useful internally to APFloat
- /// @{
-
- /// Returns true if and only if the number has the smallest possible non-zero
- /// magnitude in the current semantics.
- bool isSmallest() const;
- /// Returns true if and only if the number has the largest possible finite
- /// magnitude in the current semantics.
- bool isLargest() const;
+ void makeInf(bool Neg = false);
+ void makeZero(bool Neg = false);
/// @}
/// \name Miscellany
/// @{
+ bool convertFromStringSpecials(StringRef str);
opStatus normalize(roundingMode, lostFraction);
opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
cmpResult compareAbsoluteValue(const APFloat &) const;
@@ -557,7 +558,7 @@ private:
} significand;
/// The signed unbiased exponent of the value.
- exponent_t exponent;
+ ExponentType exponent;
/// What kind of floating point number this is.
///
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index e5797b8..625a6db 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -337,13 +337,17 @@ public:
/// \brief Determine if all bits are set
///
/// This checks to see if the value has all bits of the APInt are set or not.
- bool isAllOnesValue() const { return countPopulation() == BitWidth; }
+ bool isAllOnesValue() const {
+ if (isSingleWord())
+ return VAL == ~integerPart(0) >> (APINT_BITS_PER_WORD - BitWidth);
+ return countPopulationSlowCase() == BitWidth;
+ }
/// \brief Determine if this is the largest unsigned value.
///
/// This checks to see if the value of this APInt is the maximum unsigned
/// value for the APInt's bit width.
- bool isMaxValue() const { return countPopulation() == BitWidth; }
+ bool isMaxValue() const { return isAllOnesValue(); }
/// \brief Determine if this is the largest signed value.
///
diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h
index 44a61ff..1ca3288 100644
--- a/include/llvm/ADT/IntervalMap.h
+++ b/include/llvm/ADT/IntervalMap.h
@@ -612,7 +612,7 @@ public:
/// insertFrom - Add mapping of [a;b] to y if possible, coalescing as much as
/// possible. This may cause the node to grow by 1, or it may cause the node
/// to shrink because of coalescing.
-/// @param i Starting index = insertFrom(0, size, a)
+/// @param Pos Starting index = insertFrom(0, size, a)
/// @param Size Number of elements in node.
/// @param a Interval start.
/// @param b Interval stop.
@@ -1956,7 +1956,7 @@ iterator::eraseNode(unsigned Level) {
/// overflow - Distribute entries of the current node evenly among
/// its siblings and ensure that the current node is not full.
/// This may require allocating a new node.
-/// @param NodeT The type of node at Level (Leaf or Branch).
+/// @tparam NodeT The type of node at Level (Leaf or Branch).
/// @param Level path index of the overflowing node.
/// @return True when the tree height was changed.
template <typename KeyT, typename ValT, unsigned N, typename Traits>
diff --git a/include/llvm/ADT/NullablePtr.h b/include/llvm/ADT/NullablePtr.h
deleted file mode 100644
index 8ddfd5d..0000000
--- a/include/llvm/ADT/NullablePtr.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===- llvm/ADT/NullablePtr.h - A pointer that allows null ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines and implements the NullablePtr class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ADT_NULLABLEPTR_H
-#define LLVM_ADT_NULLABLEPTR_H
-
-#include <cassert>
-#include <cstddef>
-
-namespace llvm {
-/// NullablePtr pointer wrapper - NullablePtr is used for APIs where a
-/// potentially-null pointer gets passed around that must be explicitly handled
-/// in lots of places. By putting a wrapper around the null pointer, it makes
-/// it more likely that the null pointer case will be handled correctly.
-template<class T>
-class NullablePtr {
- T *Ptr;
-public:
- NullablePtr(T *P = 0) : Ptr(P) {}
-
- bool isNull() const { return Ptr == 0; }
- bool isNonNull() const { return Ptr != 0; }
-
- /// get - Return the pointer if it is non-null.
- const T *get() const {
- assert(Ptr && "Pointer wasn't checked for null!");
- return Ptr;
- }
-
- /// get - Return the pointer if it is non-null.
- T *get() {
- assert(Ptr && "Pointer wasn't checked for null!");
- return Ptr;
- }
-
- T *getPtrOrNull() { return Ptr; }
- const T *getPtrOrNull() const { return Ptr; }
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index fe9bef9..86949b2 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -426,6 +426,40 @@ public:
return *this;
}
+ /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
+ SmallBitVector &reset(const SmallBitVector &RHS) {
+ if (isSmall() && RHS.isSmall())
+ setSmallBits(getSmallBits() & ~RHS.getSmallBits());
+ else if (!isSmall() && !RHS.isSmall())
+ getPointer()->reset(*RHS.getPointer());
+ else
+ for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
+ if (RHS.test(i))
+ reset(i);
+
+ return *this;
+ }
+
+ /// test - Check if (This - RHS) is zero.
+ /// This is the same as reset(RHS) and any().
+ bool test(const SmallBitVector &RHS) const {
+ if (isSmall() && RHS.isSmall())
+ return (getSmallBits() & ~RHS.getSmallBits()) != 0;
+ if (!isSmall() && !RHS.isSmall())
+ return getPointer()->test(*RHS.getPointer());
+
+ unsigned i, e;
+ for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
+ if (test(i) && !RHS.test(i))
+ return true;
+
+ for (e = size(); i != e; ++i)
+ if (test(i))
+ return true;
+
+ return false;
+ }
+
SmallBitVector &operator|=(const SmallBitVector &RHS) {
resize(std::max(size(), RHS.size()));
if (isSmall())
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index d013d05..3e1e24c 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -19,7 +19,7 @@
#include <utility>
namespace llvm {
- template<typename T>
+ template <typename T>
class SmallVectorImpl;
class APInt;
class hash_code;
@@ -548,6 +548,10 @@ namespace llvm {
template <typename T> struct isPodLike;
template <> struct isPodLike<StringRef> { static const bool value = true; };
+ /// Construct a string ref from a boolean.
+ inline StringRef toStringRef(bool B) {
+ return StringRef(B ? "true" : "false");
+ }
}
#endif
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 41e463d..8d968e8 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -55,6 +55,7 @@ public:
msp430, // MSP430: msp430
ppc, // PPC: powerpc
ppc64, // PPC64: powerpc64, ppu
+ ppc64le, // PPC64LE: powerpc64le
r600, // R600: AMD GPUs HD2XXX - HD6XXX
sparc, // Sparc: sparc
sparcv9, // Sparcv9: Sparcv9
@@ -64,7 +65,6 @@ public:
x86, // X86: i[3-9]86
x86_64, // X86-64: amd64, x86_64
xcore, // XCore: xcore
- mblaze, // MBlaze: mblaze
nvptx, // NVPTX: 32-bit
nvptx64, // NVPTX: 64-bit
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
@@ -81,7 +81,8 @@ public:
BGP,
BGQ,
Freescale,
- IBM
+ IBM,
+ NVIDIA
};
enum OSType {
UnknownOS,
@@ -107,7 +108,9 @@ public:
NaCl, // Native Client
CNK, // BG/P Compute-Node Kernel
Bitrig,
- AIX
+ AIX,
+ CUDA, // NVIDIA CUDA
+ NVCL // NVIDIA OpenCL
};
enum EnvironmentType {
UnknownEnvironment,
diff --git a/include/llvm/Analysis/BlockFrequencyImpl.h b/include/llvm/Analysis/BlockFrequencyImpl.h
index b3e2d18..5e14d6f 100644
--- a/include/llvm/Analysis/BlockFrequencyImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyImpl.h
@@ -1,4 +1,4 @@
-//===---- BlockFrequencyImpl.h - Machine Block Frequency Implementation ---===//
+//===-- BlockFrequencyImpl.h - Block Frequency Implementation --*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
@@ -33,7 +33,7 @@ class BlockFrequencyInfo;
class MachineBlockFrequencyInfo;
/// BlockFrequencyImpl implements block frequency algorithm for IR and
-/// Machine Instructions. Algorithm starts with value 1024 (START_FREQ)
+/// Machine Instructions. Algorithm starts with value ENTRY_FREQ
/// for the entry block and then propagates frequencies using branch weights
/// from (Machine)BranchProbabilityInfo. LoopInfo is not required because
/// algorithm can find "backedges" by itself.
@@ -85,31 +85,16 @@ class BlockFrequencyImpl {
<< " --> " << Freqs[BB] << "\n");
}
- /// divBlockFreq - Divide BB block frequency by PROB. If Prob = 0 do nothing.
- ///
- void divBlockFreq(BlockT *BB, BranchProbability Prob) {
- uint64_t N = Prob.getNumerator();
- assert(N && "Illegal division by zero!");
- uint64_t D = Prob.getDenominator();
- uint64_t Freq = (Freqs[BB].getFrequency() * D) / N;
-
- // Should we assert it?
- if (Freq > UINT32_MAX)
- Freq = UINT32_MAX;
-
- Freqs[BB] = BlockFrequency(Freq);
- DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") /= (" << Prob
- << ") --> " << Freqs[BB] << "\n");
- }
-
// All blocks in postorder.
std::vector<BlockT *> POT;
// Map Block -> Position in reverse-postorder list.
DenseMap<BlockT *, unsigned> RPO;
- // Cycle Probability for each bloch.
- DenseMap<BlockT *, uint32_t> CycleProb;
+ // For each loop header, record the per-iteration probability of exiting the
+ // loop. This is the reciprocal of the expected number of loop iterations.
+ typedef DenseMap<BlockT*, BranchProbability> LoopExitProbMap;
+ LoopExitProbMap LoopExitProb;
// (reverse-)postorder traversal iterators.
typedef typename std::vector<BlockT *>::iterator pot_iterator;
@@ -123,7 +108,7 @@ class BlockFrequencyImpl {
rpot_iterator rpot_at(BlockT *BB) {
rpot_iterator I = rpot_begin();
- unsigned idx = RPO[BB];
+ unsigned idx = RPO.lookup(BB);
assert(idx);
std::advance(I, idx - 1);
@@ -131,22 +116,14 @@ class BlockFrequencyImpl {
return I;
}
-
- /// isReachable - Returns if BB block is reachable from the entry.
- ///
- bool isReachable(BlockT *BB) {
- return RPO.count(BB);
- }
-
- /// isBackedge - Return if edge Src -> Dst is a backedge.
+ /// isBackedge - Return if edge Src -> Dst is a reachable backedge.
///
bool isBackedge(BlockT *Src, BlockT *Dst) {
- assert(isReachable(Src));
- assert(isReachable(Dst));
-
- unsigned a = RPO[Src];
- unsigned b = RPO[Dst];
-
+ unsigned a = RPO.lookup(Src);
+ if (!a)
+ return false;
+ unsigned b = RPO.lookup(Dst);
+ assert(b && "Destination block should be reachable");
return a >= b;
}
@@ -196,7 +173,7 @@ class BlockFrequencyImpl {
PI != PE; ++PI) {
BlockT *Pred = *PI;
- if (isReachable(Pred) && isBackedge(Pred, BB)) {
+ if (isBackedge(Pred, BB)) {
isLoopHead = true;
} else if (BlocksInLoop.count(Pred)) {
incBlockFreq(BB, getEdgeFreq(Pred, BB));
@@ -211,10 +188,13 @@ class BlockFrequencyImpl {
if (!isLoopHead)
return;
- assert(EntryFreq >= CycleProb[BB]);
- uint32_t CProb = CycleProb[BB];
- uint32_t Numerator = EntryFreq - CProb ? EntryFreq - CProb : 1;
- divBlockFreq(BB, BranchProbability(Numerator, EntryFreq));
+ // This block is a loop header, so boost its frequency by the expected
+ // number of loop iterations. The loop blocks will be revisited so they all
+ // get this boost.
+ typename LoopExitProbMap::const_iterator I = LoopExitProb.find(BB);
+ assert(I != LoopExitProb.end() && "Loop header missing from table");
+ Freqs[BB] /= I->second;
+ DEBUG(dbgs() << "Loop header scaled to " << Freqs[BB] << ".\n");
}
/// doLoop - Propagate block frequency down through the loop.
@@ -234,24 +214,50 @@ class BlockFrequencyImpl {
}
// Compute loop's cyclic probability using backedges probabilities.
+ BlockFrequency BackFreq;
for (typename GT::ChildIteratorType
PI = GraphTraits< Inverse<BlockT *> >::child_begin(Head),
PE = GraphTraits< Inverse<BlockT *> >::child_end(Head);
PI != PE; ++PI) {
BlockT *Pred = *PI;
assert(Pred);
- if (isReachable(Pred) && isBackedge(Pred, Head)) {
- uint64_t N = getEdgeFreq(Pred, Head).getFrequency();
- uint64_t D = getBlockFreq(Head).getFrequency();
- assert(N <= EntryFreq && "Backedge frequency must be <= EntryFreq!");
- uint64_t Res = (N * EntryFreq) / D;
-
- assert(Res <= UINT32_MAX);
- CycleProb[Head] += (uint32_t) Res;
- DEBUG(dbgs() << " CycleProb[" << getBlockName(Head) << "] += " << Res
- << " --> " << CycleProb[Head] << "\n");
- }
+ if (isBackedge(Pred, Head))
+ BackFreq += getEdgeFreq(Pred, Head);
+ }
+
+ // The cyclic probability is freq(BackEdges) / freq(Head), where freq(Head)
+ // only counts edges entering the loop, not the loop backedges.
+ // The probability of leaving the loop on each iteration is:
+ //
+ // ExitProb = 1 - CyclicProb
+ //
+ // The Expected number of loop iterations is:
+ //
+ // Iterations = 1 / ExitProb
+ //
+ uint64_t D = std::max(getBlockFreq(Head).getFrequency(), UINT64_C(1));
+ uint64_t N = std::max(BackFreq.getFrequency(), UINT64_C(1));
+ if (N < D)
+ N = D - N;
+ else
+ // We'd expect N < D, but rounding and saturation means that can't be
+ // guaranteed.
+ N = 1;
+
+ // Now ExitProb = N / D, make sure it fits in an i32/i32 fraction.
+ assert(N <= D);
+ if (D > UINT32_MAX) {
+ unsigned Shift = 32 - countLeadingZeros(D);
+ D >>= Shift;
+ N >>= Shift;
+ if (N == 0)
+ N = 1;
}
+ BranchProbability LEP = BranchProbability(N, D);
+ LoopExitProb.insert(std::make_pair(Head, LEP));
+ DEBUG(dbgs() << "LoopExitProb[" << getBlockName(Head) << "] = " << LEP
+ << " from 1 - " << BackFreq << " / " << getBlockFreq(Head)
+ << ".\n");
}
friend class BlockFrequencyInfo;
@@ -266,7 +272,7 @@ class BlockFrequencyImpl {
// Clear everything.
RPO.clear();
POT.clear();
- CycleProb.clear();
+ LoopExitProb.clear();
Freqs.clear();
BlockT *EntryBlock = fn->begin();
@@ -292,8 +298,7 @@ class BlockFrequencyImpl {
PI != PE; ++PI) {
BlockT *Pred = *PI;
- if (isReachable(Pred) && isBackedge(Pred, BB)
- && (!LastTail || RPO[Pred] > RPO[LastTail]))
+ if (isBackedge(Pred, BB) && (!LastTail || RPO[Pred] > RPO[LastTail]))
LastTail = Pred;
}
diff --git a/include/llvm/Analysis/BlockFrequencyInfo.h b/include/llvm/Analysis/BlockFrequencyInfo.h
index fcab906..64bd15c 100644
--- a/include/llvm/Analysis/BlockFrequencyInfo.h
+++ b/include/llvm/Analysis/BlockFrequencyInfo.h
@@ -1,4 +1,4 @@
-//========-------- BlockFrequencyInfo.h - Block Frequency Analysis -------========//
+//===------- BlockFrequencyInfo.h - Block Frequency Analysis --*- C++ -*---===//
//
// The LLVM Compiler Infrastructure
//
@@ -43,10 +43,10 @@ public:
void print(raw_ostream &O, const Module *M) const;
/// getblockFreq - Return block frequency. Return 0 if we don't have the
- /// information. Please note that initial frequency is equal to 1024. It means
- /// that we should not rely on the value itself, but only on the comparison to
- /// the other block frequencies. We do this to avoid using of floating points.
- ///
+ /// information. Please note that initial frequency is equal to ENTRY_FREQ. It
+ /// means that we should not rely on the value itself, but only on the
+ /// comparison to the other block frequencies. We do this to avoid using of
+ /// floating points.
BlockFrequency getBlockFreq(const BasicBlock *BB) const;
};
diff --git a/include/llvm/Analysis/CFG.h b/include/llvm/Analysis/CFG.h
new file mode 100644
index 0000000..08fdc26
--- /dev/null
+++ b/include/llvm/Analysis/CFG.h
@@ -0,0 +1,69 @@
+//===-- Analysis/CFG.h - BasicBlock Analyses --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions performs analyses on basic blocks, and instructions
+// contained within basic blocks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CFG_H
+#define LLVM_ANALYSIS_CFG_H
+
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/Support/CFG.h"
+
+namespace llvm {
+
+class BasicBlock;
+class DominatorTree;
+class Function;
+class Instruction;
+class LoopInfo;
+class TerminatorInst;
+
+/// Analyze the specified function to find all of the loop backedges in the
+/// function and return them. This is a relatively cheap (compared to
+/// computing dominators and loop info) analysis.
+///
+/// The output is added to Result, as pairs of <from,to> edge info.
+void FindFunctionBackedges(
+ const Function &F,
+ SmallVectorImpl<std::pair<const BasicBlock *, const BasicBlock *> > &
+ Result);
+
+/// Search for the specified successor of basic block BB and return its position
+/// in the terminator instruction's list of successors. It is an error to call
+/// this with a block that is not a successor.
+unsigned GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ);
+
+/// Return true if the specified edge is a critical edge. Critical edges are
+/// edges from a block with multiple successors to a block with multiple
+/// predecessors.
+///
+bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,
+ bool AllowIdenticalEdges = false);
+
+/// Determine whether there is a path from From to To within a single function.
+/// Returns false only if we can prove that once 'From' has been executed then
+/// 'To' can not be executed. Conservatively returns true.
+///
+/// This function is linear with respect to the number of blocks in the CFG,
+/// walking down successors from From to reach To, with a fixed threshold.
+/// Using DT or LI allows us to answer more quickly. LI reduces the cost of
+/// an entire loop of any number of blocsk to be the same as the cost of a
+/// single block. DT reduces the cost by allowing the search to terminate when
+/// we find a block that dominates the block containing 'To'. DT is most useful
+/// on branchy code but not loops, and LI is most useful on code with loops but
+/// does not help on branchy code outside loops.
+bool isPotentiallyReachable(const Instruction *From, const Instruction *To,
+ DominatorTree *DT = 0, LoopInfo *LI = 0);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h
index a78ac59..8fce2f6 100644
--- a/include/llvm/Analysis/DependenceAnalysis.h
+++ b/include/llvm/Analysis/DependenceAnalysis.h
@@ -61,11 +61,20 @@ namespace llvm {
/// cases (for output, flow, and anti dependences), the dependence implies
/// an ordering, where the source must precede the destination; in contrast,
/// input dependences are unordered.
+ ///
+ /// When a dependence graph is built, each Dependence will be a member of
+ /// the set of predecessor edges for its destination instruction and a set
+ /// if successor edges for its source instruction. These sets are represented
+ /// as singly-linked lists, with the "next" fields stored in the dependence
+ /// itelf.
class Dependence {
public:
Dependence(Instruction *Source,
Instruction *Destination) :
- Src(Source), Dst(Destination) {}
+ Src(Source),
+ Dst(Destination),
+ NextPredecessor(NULL),
+ NextSuccessor(NULL) {}
virtual ~Dependence() {}
/// Dependence::DVEntry - Each level in the distance/direction vector
@@ -164,11 +173,36 @@ namespace llvm {
/// variable associated with the loop at this level.
virtual bool isScalar(unsigned Level) const;
+ /// getNextPredecessor - Returns the value of the NextPredecessor
+ /// field.
+ const Dependence *getNextPredecessor() const {
+ return NextPredecessor;
+ }
+
+ /// getNextSuccessor - Returns the value of the NextSuccessor
+ /// field.
+ const Dependence *getNextSuccessor() const {
+ return NextSuccessor;
+ }
+
+ /// setNextPredecessor - Sets the value of the NextPredecessor
+ /// field.
+ void setNextPredecessor(const Dependence *pred) {
+ NextPredecessor = pred;
+ }
+
+ /// setNextSuccessor - Sets the value of the NextSuccessor
+ /// field.
+ void setNextSuccessor(const Dependence *succ) {
+ NextSuccessor = succ;
+ }
+
/// dump - For debugging purposes, dumps a dependence to OS.
///
void dump(raw_ostream &OS) const;
private:
Instruction *Src, *Dst;
+ const Dependence *NextPredecessor, *NextSuccessor;
friend class DependenceAnalysis;
};
@@ -815,7 +849,7 @@ namespace llvm {
bool propagate(const SCEV *&Src,
const SCEV *&Dst,
SmallBitVector &Loops,
- SmallVector<Constraint, 4> &Constraints,
+ SmallVectorImpl<Constraint> &Constraints,
bool &Consistent);
/// propagateDistance - Attempt to propagate a distance
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index d760a4c..775d0df 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -1,4 +1,4 @@
-//===-- InstructionSimplify.h - Fold instructions into simpler forms ------===//
+//===-- InstructionSimplify.h - Fold instrs into simpler forms --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index 4883383..0d1ae8c 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This family of functions identifies calls to builtin functions that allocate
-// or free memory.
+// or free memory.
//
//===----------------------------------------------------------------------===//
@@ -78,7 +78,7 @@ static inline CallInst *extractMallocCall(Value *I,
return const_cast<CallInst*>(extractMallocCall((const Value*)I, TLI));
}
-/// isArrayMalloc - Returns the corresponding CallInst if the instruction
+/// isArrayMalloc - Returns the corresponding CallInst if the instruction
/// is a call to malloc whose array size can be determined and the array size
/// is not constant 1. Otherwise, return NULL.
const CallInst *isArrayMalloc(const Value *I, const DataLayout *TD,
@@ -98,7 +98,7 @@ PointerType *getMallocType(const CallInst *CI, const TargetLibraryInfo *TLI);
/// >1: Unique PointerType cannot be determined, return NULL.
Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI);
-/// getMallocArraySize - Returns the array size of a malloc call. If the
+/// getMallocArraySize - Returns the array size of a malloc call. If the
/// argument passed to malloc is a multiple of the size of the malloced type,
/// then return that multiple. For non-array mallocs, the multiple is
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
@@ -127,12 +127,12 @@ static inline CallInst *extractCallocCall(Value *I,
/// isFreeCall - Returns non-null if the value is a call to the builtin free()
const CallInst *isFreeCall(const Value *I, const TargetLibraryInfo *TLI);
-
+
static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI));
}
-
+
//===----------------------------------------------------------------------===//
// Utility functions to compute size of objects.
//
@@ -150,7 +150,7 @@ bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
typedef std::pair<APInt, APInt> SizeOffsetType;
-/// \brief Evaluate the size and offset of an object ponted by a Value*
+/// \brief Evaluate the size and offset of an object pointed to by a Value*
/// statically. Fails if size or offset are not known at compile time.
class ObjectSizeOffsetVisitor
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
@@ -206,7 +206,7 @@ public:
typedef std::pair<Value*, Value*> SizeOffsetEvalType;
-/// \brief Evaluate the size and offset of an object ponted by a Value*.
+/// \brief Evaluate the size and offset of an object pointed to by a Value*.
/// May create code to compute the result at run-time.
class ObjectSizeOffsetEvaluator
: public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 349447f..3817e41 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -545,6 +545,10 @@ namespace llvm {
/// forgetMemoizedResults - Drop memoized information computed for S.
void forgetMemoizedResults(const SCEV *S);
+ /// Return false iff given SCEV contains a SCEVUnknown with NULL value-
+ /// pointer.
+ bool checkValidity(const SCEV *S) const;
+
public:
static char ID; // Pass identification, replacement for typeid
ScalarEvolution();
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index eb29e34..21a3a12 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -171,6 +171,12 @@ public:
/// comments for a detailed explanation of the cost values.
virtual unsigned getUserCost(const User *U) const;
+ /// \brief hasBranchDivergence - Return true if branch divergence exists.
+ /// Branch divergence has a significantly negative impact on GPU performance
+ /// when threads in the same wavefront take different paths due to conditional
+ /// branches.
+ virtual bool hasBranchDivergence() const;
+
/// \brief Test whether calls to a function lower to actual program function
/// calls.
///
@@ -339,7 +345,11 @@ public:
/// merged into the instruction indexing mode. Some targets might want to
/// distinguish between address computation for memory operations on vector
/// types and scalar types. Such targets should override this function.
- virtual unsigned getAddressComputationCost(Type *Ty) const;
+ /// The 'IsComplex' parameter is a hint that the address computation is likely
+ /// to involve multiple instructions and as such unlikely to be merged into
+ /// the address indexing mode.
+ virtual unsigned getAddressComputationCost(Type *Ty,
+ bool IsComplex = false) const;
/// @}
diff --git a/include/llvm/AutoUpgrade.h b/include/llvm/AutoUpgrade.h
index e13c4c1..ca3446e 100644
--- a/include/llvm/AutoUpgrade.h
+++ b/include/llvm/AutoUpgrade.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// These functions are implemented by lib/VMCore/AutoUpgrade.cpp.
+// These functions are implemented by lib/IR/AutoUpgrade.cpp.
//
//===----------------------------------------------------------------------===//
@@ -20,19 +20,19 @@ namespace llvm {
class Function;
class CallInst;
- /// This is a more granular function that simply checks an intrinsic function
+ /// This is a more granular function that simply checks an intrinsic function
/// for upgrading, and returns true if it requires upgrading. It may return
/// null in NewFn if the all calls to the original intrinsic function
/// should be transformed to non-function-call instructions.
bool UpgradeIntrinsicFunction(Function *F, Function *&NewFn);
- /// This is the complement to the above, replacing a specific call to an
+ /// This is the complement to the above, replacing a specific call to an
/// intrinsic function with a call to the specified new function.
void UpgradeIntrinsicCall(CallInst *CI, Function *NewFn);
-
- /// This is an auto-upgrade hook for any old intrinsic function syntaxes
- /// which need to have both the function updated as well as all calls updated
- /// to the new function. This should only be run in a post-processing fashion
+
+ /// This is an auto-upgrade hook for any old intrinsic function syntaxes
+ /// which need to have both the function updated as well as all calls updated
+ /// to the new function. This should only be run in a post-processing fashion
/// so that it can update all calls to the old function.
void UpgradeCallsToIntrinsic(Function* F);
diff --git a/include/llvm/Bitcode/Archive.h b/include/llvm/Bitcode/Archive.h
deleted file mode 100644
index d27f690..0000000
--- a/include/llvm/Bitcode/Archive.h
+++ /dev/null
@@ -1,539 +0,0 @@
-//===-- llvm/Bitcode/Archive.h - LLVM Bitcode Archive -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header file declares the Archive and ArchiveMember classes that provide
-// manipulation of LLVM Archive files. The implementation is provided by the
-// lib/Bitcode/Archive library. This library is used to read and write
-// archive (*.a) files that contain LLVM bitcode files (or others).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_BITCODE_ARCHIVE_H
-#define LLVM_BITCODE_ARCHIVE_H
-
-#include "llvm/ADT/ilist.h"
-#include "llvm/ADT/ilist_node.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/PathV1.h"
-#include <map>
-#include <set>
-
-namespace llvm {
- class MemoryBuffer;
-
-// Forward declare classes
-class Module; // From VMCore
-class Archive; // Declared below
-class ArchiveMemberHeader; // Internal implementation class
-class LLVMContext; // Global data
-
-/// This class is the main class manipulated by users of the Archive class. It
-/// holds information about one member of the Archive. It is also the element
-/// stored by the Archive's ilist, the Archive's main abstraction. Because of
-/// the special requirements of archive files, users are not permitted to
-/// construct ArchiveMember instances. You should obtain them from the methods
-/// of the Archive class instead.
-/// @brief This class represents a single archive member.
-class ArchiveMember : public ilist_node<ArchiveMember> {
- /// @name Types
- /// @{
- public:
- /// These flags are used internally by the archive member to specify various
- /// characteristics of the member. The various "is" methods below provide
- /// access to the flags. The flags are not user settable.
- enum Flags {
- SVR4SymbolTableFlag = 1, ///< Member is a SVR4 symbol table
- BSD4SymbolTableFlag = 2, ///< Member is a BSD4 symbol table
- LLVMSymbolTableFlag = 4, ///< Member is an LLVM symbol table
- BitcodeFlag = 8, ///< Member is bitcode
- HasPathFlag = 16, ///< Member has a full or partial path
- HasLongFilenameFlag = 32, ///< Member uses the long filename syntax
- StringTableFlag = 64 ///< Member is an ar(1) format string table
- };
-
- /// @}
- /// @name Accessors
- /// @{
- public:
- /// @returns the parent Archive instance
- /// @brief Get the archive associated with this member
- Archive* getArchive() const { return parent; }
-
- /// @returns the path to the Archive's file
- /// @brief Get the path to the archive member
- const sys::Path& getPath() const { return path; }
-
- /// The "user" is the owner of the file per Unix security. This may not
- /// have any applicability on non-Unix systems but is a required component
- /// of the "ar" file format.
- /// @brief Get the user associated with this archive member.
- unsigned getUser() const { return info.getUser(); }
-
- /// The "group" is the owning group of the file per Unix security. This
- /// may not have any applicability on non-Unix systems but is a required
- /// component of the "ar" file format.
- /// @brief Get the group associated with this archive member.
- unsigned getGroup() const { return info.getGroup(); }
-
- /// The "mode" specifies the access permissions for the file per Unix
- /// security. This may not have any applicability on non-Unix systems but is
- /// a required component of the "ar" file format.
- /// @brief Get the permission mode associated with this archive member.
- unsigned getMode() const { return info.getMode(); }
-
- /// This method returns the time at which the archive member was last
- /// modified when it was not in the archive.
- /// @brief Get the time of last modification of the archive member.
- sys::TimeValue getModTime() const { return info.getTimestamp(); }
-
- /// @returns the size of the archive member in bytes.
- /// @brief Get the size of the archive member.
- uint64_t getSize() const { return info.getSize(); }
-
- /// This method returns the total size of the archive member as it
- /// appears on disk. This includes the file content, the header, the
- /// long file name if any, and the padding.
- /// @brief Get total on-disk member size.
- unsigned getMemberSize() const;
-
- /// This method will return a pointer to the in-memory content of the
- /// archive member, if it is available. If the data has not been loaded
- /// into memory, the return value will be null.
- /// @returns a pointer to the member's data.
- /// @brief Get the data content of the archive member
- const char* getData() const { return data; }
-
- /// @returns true iff the member is a SVR4 (non-LLVM) symbol table
- /// @brief Determine if this member is a SVR4 symbol table.
- bool isSVR4SymbolTable() const { return flags&SVR4SymbolTableFlag; }
-
- /// @returns true iff the member is a BSD4.4 (non-LLVM) symbol table
- /// @brief Determine if this member is a BSD4.4 symbol table.
- bool isBSD4SymbolTable() const { return flags&BSD4SymbolTableFlag; }
-
- /// @returns true iff the archive member is the LLVM symbol table
- /// @brief Determine if this member is the LLVM symbol table.
- bool isLLVMSymbolTable() const { return flags&LLVMSymbolTableFlag; }
-
- /// @returns true iff the archive member is the ar(1) string table
- /// @brief Determine if this member is the ar(1) string table.
- bool isStringTable() const { return flags&StringTableFlag; }
-
- /// @returns true iff the archive member is a bitcode file.
- /// @brief Determine if this member is a bitcode file.
- bool isBitcode() const { return flags&BitcodeFlag; }
-
- /// @returns true iff the file name contains a path (directory) component.
- /// @brief Determine if the member has a path
- bool hasPath() const { return flags&HasPathFlag; }
-
- /// Long filenames are an artifact of the ar(1) file format which allows
- /// up to sixteen characters in its header and doesn't allow a path
- /// separator character (/). To avoid this, a "long format" member name is
- /// allowed that doesn't have this restriction. This method determines if
- /// that "long format" is used for this member.
- /// @returns true iff the file name uses the long form
- /// @brief Determine if the member has a long file name
- bool hasLongFilename() const { return flags&HasLongFilenameFlag; }
-
- /// This method returns the status info (like Unix stat(2)) for the archive
- /// member. The status info provides the file's size, permissions, and
- /// modification time. The contents of the Path::StatusInfo structure, other
- /// than the size and modification time, may not have utility on non-Unix
- /// systems.
- /// @returns the status info for the archive member
- /// @brief Obtain the status info for the archive member
- const sys::FileStatus &getFileStatus() const { return info; }
-
- /// This method causes the archive member to be replaced with the contents
- /// of the file specified by \p File. The contents of \p this will be
- /// updated to reflect the new data from \p File. The \p File must exist and
- /// be readable on entry to this method.
- /// @returns true if an error occurred, false otherwise
- /// @brief Replace contents of archive member with a new file.
- bool replaceWith(const sys::Path &aFile, std::string* ErrMsg);
-
- /// @}
- /// @name Data
- /// @{
- private:
- Archive* parent; ///< Pointer to parent archive
- sys::PathWithStatus path; ///< Path of file containing the member
- sys::FileStatus info; ///< Status info (size,mode,date)
- unsigned flags; ///< Flags about the archive member
- const char* data; ///< Data for the member
-
- /// @}
- /// @name Constructors
- /// @{
- public:
- /// The default constructor is only used by the Archive's iplist when it
- /// constructs the list's sentry node.
- ArchiveMember();
-
- private:
- /// Used internally by the Archive class to construct an ArchiveMember.
- /// The contents of the ArchiveMember are filled out by the Archive class.
- explicit ArchiveMember(Archive *PAR);
-
- // So Archive can construct an ArchiveMember
- friend class llvm::Archive;
- /// @}
-};
-
-/// This class defines the interface to LLVM Archive files. The Archive class
-/// presents the archive file as an ilist of ArchiveMember objects. The members
-/// can be rearranged in any fashion either by directly editing the ilist or by
-/// using editing methods on the Archive class (recommended). The Archive
-/// class also provides several ways of accessing the archive file for various
-/// purposes such as editing and linking. Full symbol table support is provided
-/// for loading only those files that resolve symbols. Note that read
-/// performance of this library is _crucial_ for performance of JIT type
-/// applications and the linkers. Consequently, the implementation of the class
-/// is optimized for reading.
-class Archive {
-
- /// @name Types
- /// @{
- public:
- /// This is the ilist type over which users may iterate to examine
- /// the contents of the archive
- /// @brief The ilist type of ArchiveMembers that Archive contains.
- typedef iplist<ArchiveMember> MembersList;
-
- /// @brief Forward mutable iterator over ArchiveMember
- typedef MembersList::iterator iterator;
-
- /// @brief Forward immutable iterator over ArchiveMember
- typedef MembersList::const_iterator const_iterator;
-
- /// @brief Reverse mutable iterator over ArchiveMember
- typedef std::reverse_iterator<iterator> reverse_iterator;
-
- /// @brief Reverse immutable iterator over ArchiveMember
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- /// @brief The in-memory version of the symbol table
- typedef std::map<std::string,unsigned> SymTabType;
-
- /// @}
- /// @name ilist accessor methods
- /// @{
- public:
- inline iterator begin() { return members.begin(); }
- inline const_iterator begin() const { return members.begin(); }
- inline iterator end () { return members.end(); }
- inline const_iterator end () const { return members.end(); }
-
- inline reverse_iterator rbegin() { return members.rbegin(); }
- inline const_reverse_iterator rbegin() const { return members.rbegin(); }
- inline reverse_iterator rend () { return members.rend(); }
- inline const_reverse_iterator rend () const { return members.rend(); }
-
- inline size_t size() const { return members.size(); }
- inline bool empty() const { return members.empty(); }
- inline const ArchiveMember& front() const { return members.front(); }
- inline ArchiveMember& front() { return members.front(); }
- inline const ArchiveMember& back() const { return members.back(); }
- inline ArchiveMember& back() { return members.back(); }
-
- /// @}
- /// @name ilist mutator methods
- /// @{
- public:
- /// This method splices a \p src member from an archive (possibly \p this),
- /// to a position just before the member given by \p dest in \p this. When
- /// the archive is written, \p src will be written in its new location.
- /// @brief Move a member to a new location
- inline void splice(iterator dest, Archive& arch, iterator src)
- { return members.splice(dest,arch.members,src); }
-
- /// This method erases a \p target member from the archive. When the
- /// archive is written, it will no longer contain \p target. The associated
- /// ArchiveMember is deleted.
- /// @brief Erase a member.
- inline iterator erase(iterator target) { return members.erase(target); }
-
- /// @}
- /// @name Constructors
- /// @{
- public:
- /// Create an empty archive file and associate it with the \p Filename. This
- /// method does not actually create the archive disk file. It creates an
- /// empty Archive object. If the writeToDisk method is called, the archive
- /// file \p Filename will be created at that point, with whatever content
- /// the returned Archive object has at that time.
- /// @returns An Archive* that represents the new archive file.
- /// @brief Create an empty Archive.
- static Archive* CreateEmpty(
- const sys::Path& Filename,///< Name of the archive to (eventually) create.
- LLVMContext& C ///< Context to use for global information
- );
-
- /// Open an existing archive and load its contents in preparation for
- /// editing. After this call, the member ilist is completely populated based
- /// on the contents of the archive file. You should use this form of open if
- /// you intend to modify the archive or traverse its contents (e.g. for
- /// printing).
- /// @brief Open and load an archive file
- static Archive* OpenAndLoad(
- const sys::Path& filePath, ///< The file path to open and load
- LLVMContext& C, ///< The context to use for global information
- std::string* ErrorMessage ///< An optional error string
- );
-
- /// This method opens an existing archive file from \p Filename and reads in
- /// its symbol table without reading in any of the archive's members. This
- /// reduces both I/O and cpu time in opening the archive if it is to be used
- /// solely for symbol lookup (e.g. during linking). The \p Filename must
- /// exist and be an archive file or an error will be returned. This form
- /// of opening the archive is intended for read-only operations that need to
- /// locate members via the symbol table for link editing. Since the archve
- /// members are not read by this method, the archive will appear empty upon
- /// return. If editing operations are performed on the archive, they will
- /// completely replace the contents of the archive! It is recommended that
- /// if this form of opening the archive is used that only the symbol table
- /// lookup methods (getSymbolTable, findModuleDefiningSymbol, and
- /// findModulesDefiningSymbols) be used.
- /// @returns an Archive* that represents the archive file, or null on error.
- /// @brief Open an existing archive and load its symbols.
- static Archive* OpenAndLoadSymbols(
- const sys::Path& Filename, ///< Name of the archive file to open
- LLVMContext& C, ///< The context to use for global info
- std::string* ErrorMessage=0 ///< An optional error string
- );
-
- /// This destructor cleans up the Archive object, releases all memory, and
- /// closes files. It does nothing with the archive file on disk. If you
- /// haven't used the writeToDisk method by the time the destructor is
- /// called, all changes to the archive will be lost.
- /// @brief Destruct in-memory archive
- ~Archive();
-
- /// @}
- /// @name Accessors
- /// @{
- public:
- /// @returns the path to the archive file.
- /// @brief Get the archive path.
- const sys::Path& getPath() { return archPath; }
-
- /// This method is provided so that editing methods can be invoked directly
- /// on the Archive's iplist of ArchiveMember. However, it is recommended
- /// that the usual STL style iterator interface be used instead.
- /// @returns the iplist of ArchiveMember
- /// @brief Get the iplist of the members
- MembersList& getMembers() { return members; }
-
- /// This method allows direct query of the Archive's symbol table. The
- /// symbol table is a std::map of std::string (the symbol) to unsigned (the
- /// file offset). Note that for efficiency reasons, the offset stored in
- /// the symbol table is not the actual offset. It is the offset from the
- /// beginning of the first "real" file member (after the symbol table). Use
- /// the getFirstFileOffset() to obtain that offset and add this value to the
- /// offset in the symbol table to obtain the real file offset. Note that
- /// there is purposefully no interface provided by Archive to look up
- /// members by their offset. Use the findModulesDefiningSymbols and
- /// findModuleDefiningSymbol methods instead.
- /// @returns the Archive's symbol table.
- /// @brief Get the archive's symbol table
- const SymTabType& getSymbolTable() { return symTab; }
-
- /// This method returns the offset in the archive file to the first "real"
- /// file member. Archive files, on disk, have a signature and might have a
- /// symbol table that precedes the first actual file member. This method
- /// allows you to determine what the size of those fields are.
- /// @returns the offset to the first "real" file member in the archive.
- /// @brief Get the offset to the first "real" file member in the archive.
- unsigned getFirstFileOffset() { return firstFileOffset; }
-
- /// This method will scan the archive for bitcode modules, interpret them
- /// and return a vector of the instantiated modules in \p Modules. If an
- /// error occurs, this method will return true. If \p ErrMessage is not null
- /// and an error occurs, \p *ErrMessage will be set to a string explaining
- /// the error that occurred.
- /// @returns true if an error occurred
- /// @brief Instantiate all the bitcode modules located in the archive
- bool getAllModules(std::vector<Module*>& Modules, std::string* ErrMessage);
-
- /// This accessor looks up the \p symbol in the archive's symbol table and
- /// returns the associated module that defines that symbol. This method can
- /// be called as many times as necessary. This is handy for linking the
- /// archive into another module based on unresolved symbols. Note that the
- /// Module returned by this accessor should not be deleted by the caller. It
- /// is managed internally by the Archive class. It is possible that multiple
- /// calls to this accessor will return the same Module instance because the
- /// associated module defines multiple symbols.
- /// @returns The Module* found or null if the archive does not contain a
- /// module that defines the \p symbol.
- /// @brief Look up a module by symbol name.
- Module* findModuleDefiningSymbol(
- const std::string& symbol, ///< Symbol to be sought
- std::string* ErrMessage ///< Error message storage, if non-zero
- );
-
- /// This method is similar to findModuleDefiningSymbol but allows lookup of
- /// more than one symbol at a time. If \p symbols contains a list of
- /// undefined symbols in some module, then calling this method is like
- /// making one complete pass through the archive to resolve symbols but is
- /// more efficient than looking at the individual members. Note that on
- /// exit, the symbols resolved by this method will be removed from \p
- /// symbols to ensure they are not re-searched on a subsequent call. If
- /// you need to retain the list of symbols, make a copy.
- /// @brief Look up multiple symbols in the archive.
- bool findModulesDefiningSymbols(
- std::set<std::string>& symbols, ///< Symbols to be sought
- SmallVectorImpl<Module*>& modules, ///< The modules matching \p symbols
- std::string* ErrMessage ///< Error msg storage, if non-zero
- );
-
- /// This method determines whether the archive is a properly formed llvm
- /// bitcode archive. It first makes sure the symbol table has been loaded
- /// and has a non-zero size. If it does, then it is an archive. If not,
- /// then it tries to load all the bitcode modules of the archive. Finally,
- /// it returns whether it was successful.
- /// @returns true if the archive is a proper llvm bitcode archive
- /// @brief Determine whether the archive is a proper llvm bitcode archive.
- bool isBitcodeArchive();
-
- /// @}
- /// @name Mutators
- /// @{
- public:
- /// This method is the only way to get the archive written to disk. It
- /// creates or overwrites the file specified when \p this was created
- /// or opened. The arguments provide options for writing the archive. If
- /// \p CreateSymbolTable is true, the archive is scanned for bitcode files
- /// and a symbol table of the externally visible function and global
- /// variable names is created. If \p TruncateNames is true, the names of the
- /// archive members will have their path component stripped and the file
- /// name will be truncated at 15 characters. If \p Compress is specified,
- /// all archive members will be compressed before being written. If
- /// \p PrintSymTab is true, the symbol table will be printed to std::cout.
- /// @returns true if an error occurred, \p error set to error message;
- /// returns false if the writing succeeded.
- /// @brief Write (possibly modified) archive contents to disk
- bool writeToDisk(
- bool CreateSymbolTable=false, ///< Create Symbol table
- bool TruncateNames=false, ///< Truncate the filename to 15 chars
- std::string* ErrMessage=0 ///< If non-null, where error msg is set
- );
-
- /// This method adds a new file to the archive. The \p filename is examined
- /// to determine just enough information to create an ArchiveMember object
- /// which is then inserted into the Archive object's ilist at the location
- /// given by \p where.
- /// @returns true if an error occurred, false otherwise
- /// @brief Add a file to the archive.
- bool addFileBefore(
- const sys::Path& filename, ///< The file to be added
- iterator where, ///< Insertion point
- std::string* ErrMsg ///< Optional error message location
- );
-
- /// @}
- /// @name Implementation
- /// @{
- protected:
- /// @brief Construct an Archive for \p filename and optionally map it
- /// into memory.
- explicit Archive(const sys::Path& filename, LLVMContext& C);
-
- /// @param data The symbol table data to be parsed
- /// @param len The length of the symbol table data
- /// @param error Set to address of a std::string to get error messages
- /// @returns false on error
- /// @brief Parse the symbol table at \p data.
- bool parseSymbolTable(const void* data,unsigned len,std::string* error);
-
- /// @returns A fully populated ArchiveMember or 0 if an error occurred.
- /// @brief Parse the header of a member starting at \p At
- ArchiveMember* parseMemberHeader(
- const char*&At, ///< The pointer to the location we're parsing
- const char*End, ///< The pointer to the end of the archive
- std::string* error ///< Optional error message catcher
- );
-
- /// @param ErrMessage Set to address of a std::string to get error messages
- /// @returns false on error
- /// @brief Check that the archive signature is correct
- bool checkSignature(std::string* ErrMessage);
-
- /// @param ErrMessage Set to address of a std::string to get error messages
- /// @returns false on error
- /// @brief Load the entire archive.
- bool loadArchive(std::string* ErrMessage);
-
- /// @param ErrMessage Set to address of a std::string to get error messages
- /// @returns false on error
- /// @brief Load just the symbol table.
- bool loadSymbolTable(std::string* ErrMessage);
-
- /// @brief Write the symbol table to an ofstream.
- void writeSymbolTable(std::ofstream& ARFile);
-
- /// Writes one ArchiveMember to an ofstream. If an error occurs, returns
- /// false, otherwise true. If an error occurs and error is non-null then
- /// it will be set to an error message.
- /// @returns false if writing member succeeded,
- /// returns true if writing member failed, \p error set to error message.
- bool writeMember(
- const ArchiveMember& member, ///< The member to be written
- std::ofstream& ARFile, ///< The file to write member onto
- bool CreateSymbolTable, ///< Should symbol table be created?
- bool TruncateNames, ///< Should names be truncated to 11 chars?
- std::string* ErrMessage ///< If non-null, place were error msg is set
- );
-
- /// @brief Fill in an ArchiveMemberHeader from ArchiveMember.
- bool fillHeader(const ArchiveMember&mbr,
- ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const;
-
- /// @brief Maps archive into memory
- bool mapToMemory(std::string* ErrMsg);
-
- /// @brief Frees all the members and unmaps the archive file.
- void cleanUpMemory();
-
- /// This type is used to keep track of bitcode modules loaded from the
- /// symbol table. It maps the file offset to a pair that consists of the
- /// associated ArchiveMember and the Module.
- /// @brief Module mapping type
- typedef std::map<unsigned,std::pair<Module*,ArchiveMember*> >
- ModuleMap;
-
-
- /// @}
- /// @name Data
- /// @{
- protected:
- sys::Path archPath; ///< Path to the archive file we read/write
- MembersList members; ///< The ilist of ArchiveMember
- MemoryBuffer *mapfile; ///< Raw Archive contents mapped into memory
- const char* base; ///< Base of the memory mapped file data
- SymTabType symTab; ///< The symbol table
- std::string strtab; ///< The string table for long file names
- unsigned symTabSize; ///< Size in bytes of symbol table
- unsigned firstFileOffset; ///< Offset to first normal file.
- ModuleMap modules; ///< The modules loaded via symbol lookup.
- ArchiveMember* foreignST; ///< This holds the foreign symbol table.
- LLVMContext& Context; ///< This holds global data.
- /// @}
- /// @name Hidden
- /// @{
- private:
- Archive() LLVM_DELETED_FUNCTION;
- Archive(const Archive&) LLVM_DELETED_FUNCTION;
- Archive& operator=(const Archive&) LLVM_DELETED_FUNCTION;
- /// @}
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index f9690d5..463e3b9 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -330,6 +330,47 @@ namespace bitc {
enum UseListCodes {
USELIST_CODE_ENTRY = 1 // USELIST_CODE_ENTRY: TBD.
};
+
+ enum AttributeKindCodes {
+ // = 0 is unused
+ ATTR_KIND_ALIGNMENT = 1,
+ ATTR_KIND_ALWAYS_INLINE = 2,
+ ATTR_KIND_BY_VAL = 3,
+ ATTR_KIND_INLINE_HINT = 4,
+ ATTR_KIND_IN_REG = 5,
+ ATTR_KIND_MIN_SIZE = 6,
+ ATTR_KIND_NAKED = 7,
+ ATTR_KIND_NEST = 8,
+ ATTR_KIND_NO_ALIAS = 9,
+ ATTR_KIND_NO_BUILTIN = 10,
+ ATTR_KIND_NO_CAPTURE = 11,
+ ATTR_KIND_NO_DUPLICATE = 12,
+ ATTR_KIND_NO_IMPLICIT_FLOAT = 13,
+ ATTR_KIND_NO_INLINE = 14,
+ ATTR_KIND_NON_LAZY_BIND = 15,
+ ATTR_KIND_NO_RED_ZONE = 16,
+ ATTR_KIND_NO_RETURN = 17,
+ ATTR_KIND_NO_UNWIND = 18,
+ ATTR_KIND_OPTIMIZE_FOR_SIZE = 19,
+ ATTR_KIND_READ_NONE = 20,
+ ATTR_KIND_READ_ONLY = 21,
+ ATTR_KIND_RETURNED = 22,
+ ATTR_KIND_RETURNS_TWICE = 23,
+ ATTR_KIND_S_EXT = 24,
+ ATTR_KIND_STACK_ALIGNMENT = 25,
+ ATTR_KIND_STACK_PROTECT = 26,
+ ATTR_KIND_STACK_PROTECT_REQ = 27,
+ ATTR_KIND_STACK_PROTECT_STRONG = 28,
+ ATTR_KIND_STRUCT_RET = 29,
+ ATTR_KIND_SANITIZE_ADDRESS = 30,
+ ATTR_KIND_SANITIZE_THREAD = 31,
+ ATTR_KIND_SANITIZE_MEMORY = 32,
+ ATTR_KIND_UW_TABLE = 33,
+ ATTR_KIND_Z_EXT = 34,
+ ATTR_KIND_BUILTIN = 35,
+ ATTR_KIND_COLD = 36
+ };
+
} // End bitc namespace
} // End llvm namespace
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 5973255..677331b 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -121,6 +121,8 @@ namespace llvm {
public:
virtual ~AsmPrinter();
+ const DwarfDebug *getDwarfDebug() const { return DD; }
+
/// isVerbose - Return true if assembly output should contain comments.
///
bool isVerbose() const { return VerboseAsm; }
@@ -233,8 +235,8 @@ namespace llvm {
/// it if appropriate.
void EmitBasicBlockStart(const MachineBasicBlock *MBB) const;
- /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
- void EmitGlobalConstant(const Constant *CV, unsigned AddrSpace = 0);
+ /// \brief Print a general LLVM constant to the .s file.
+ void EmitGlobalConstant(const Constant *CV);
//===------------------------------------------------------------------===//
@@ -371,10 +373,10 @@ namespace llvm {
//===------------------------------------------------------------------===//
/// EmitSLEB128 - emit the specified signed leb128 value.
- void EmitSLEB128(int Value, const char *Desc = 0) const;
+ void EmitSLEB128(int64_t Value, const char *Desc = 0) const;
/// EmitULEB128 - emit the specified unsigned leb128 value.
- void EmitULEB128(unsigned Value, const char *Desc = 0,
+ void EmitULEB128(uint64_t Value, const char *Desc = 0,
unsigned PadTo = 0) const;
/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
@@ -402,16 +404,13 @@ namespace llvm {
void EmitSectionOffset(const MCSymbol *Label,
const MCSymbol *SectionLabel) const;
- /// getDebugValueLocation - Get location information encoded by DBG_VALUE
- /// operands.
- virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
-
/// getISAEncoding - Get the value for DW_AT_APPLE_isa. Zero if no isa
/// encoding specified.
virtual unsigned getISAEncoding() { return 0; }
/// EmitDwarfRegOp - Emit dwarf register operation.
- virtual void EmitDwarfRegOp(const MachineLocation &MLoc) const;
+ virtual void EmitDwarfRegOp(const MachineLocation &MLoc,
+ bool Indirect) const;
//===------------------------------------------------------------------===//
// Dwarf Lowering Routines
diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h
index 9cd2dec..c8ec764 100644
--- a/include/llvm/CodeGen/CalcSpillWeights.h
+++ b/include/llvm/CodeGen/CalcSpillWeights.h
@@ -18,6 +18,7 @@ namespace llvm {
class LiveInterval;
class LiveIntervals;
+ class MachineBlockFrequencyInfo;
class MachineLoopInfo;
/// normalizeSpillWeight - The spill weight of a live interval is computed as:
@@ -43,11 +44,13 @@ namespace llvm {
MachineFunction &MF;
LiveIntervals &LIS;
const MachineLoopInfo &Loops;
+ const MachineBlockFrequencyInfo &MBFI;
DenseMap<unsigned, float> Hint;
public:
VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis,
- const MachineLoopInfo &loops) :
- MF(mf), LIS(lis), Loops(loops) {}
+ const MachineLoopInfo &loops,
+ const MachineBlockFrequencyInfo &mbfi)
+ : MF(mf), LIS(lis), Loops(loops), MBFI(mbfi) {}
/// CalculateWeightAndHint - (re)compute li's spill weight and allocation
/// hint.
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
index fa9d60f..a18f433 100644
--- a/include/llvm/CodeGen/CallingConvLower.h
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -158,7 +158,7 @@ private:
MachineFunction &MF;
const TargetMachine &TM;
const TargetRegisterInfo &TRI;
- SmallVector<CCValAssign, 16> &Locs;
+ SmallVectorImpl<CCValAssign> &Locs;
LLVMContext &Context;
unsigned StackOffset;
@@ -219,7 +219,7 @@ protected:
public:
CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF,
- const TargetMachine &TM, SmallVector<CCValAssign, 16> &locs,
+ const TargetMachine &TM, SmallVectorImpl<CCValAssign> &locs,
LLVMContext &C);
void addLoc(const CCValAssign &V) {
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
index 9a27661..0c21e76 100644
--- a/include/llvm/CodeGen/CommandFlags.h
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -110,11 +110,6 @@ DisableFPElim("disable-fp-elim",
cl::init(false));
cl::opt<bool>
-DisableFPElimNonLeaf("disable-non-leaf-fp-elim",
- cl::desc("Disable frame pointer elimination optimization for non-leaf funcs"),
- cl::init(false));
-
-cl::opt<bool>
EnableUnsafeFPMath("enable-unsafe-fp-math",
cl::desc("Enable optimizations that may decrease FP precision"),
cl::init(false));
@@ -186,11 +181,6 @@ OverrideStackAlignment("stack-alignment",
cl::desc("Override default stack alignment"),
cl::init(0));
-cl::opt<bool>
-EnableRealignStack("realign-stack",
- cl::desc("Realign stack if needed"),
- cl::init(true));
-
cl::opt<std::string>
TrapFuncName("trap-func", cl::Hidden,
cl::desc("Emit a call to trap function rather than a trap instruction"),
@@ -220,8 +210,4 @@ cl::opt<std::string> StartAfter("start-after",
cl::value_desc("pass-name"),
cl::init(""));
-cl::opt<unsigned>
-SSPBufferSize("stack-protector-buffer-size", cl::init(8),
- cl::desc("Lower bound for a buffer to be considered for "
- "stack protection"));
#endif
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 471e9bf..0063474 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -1,4 +1,4 @@
-//===-- FastISel.h - Definition of the FastISel class ---------------------===//
+//===-- FastISel.h - Definition of the FastISel class ---*- C++ -*---------===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the FastISel class.
-//
+///
+/// \file
+/// This file defines the FastISel class.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_FASTISEL_H
@@ -26,7 +27,6 @@ class ConstantFP;
class FunctionLoweringInfo;
class Instruction;
class LoadInst;
-class MachineBasicBlock;
class MachineConstantPool;
class MachineFunction;
class MachineInstr;
@@ -42,9 +42,8 @@ class TargetRegisterInfo;
class User;
class Value;
-/// FastISel - This is a fast-path instruction selection class that
-/// generates poor code and doesn't support illegal types or non-trivial
-/// lowering, but runs quickly.
+/// This is a fast-path instruction selection class that generates poor code and
+/// doesn't support illegal types or non-trivial lowering, but runs quickly.
class FastISel {
protected:
DenseMap<const Value *, unsigned> LocalValueMap;
@@ -60,99 +59,92 @@ protected:
const TargetRegisterInfo &TRI;
const TargetLibraryInfo *LibInfo;
- /// The position of the last instruction for materializing constants
- /// for use in the current block. It resets to EmitStartPt when it
- /// makes sense (for example, it's usually profitable to avoid function
- /// calls between the definition and the use)
+ /// The position of the last instruction for materializing constants for use
+ /// in the current block. It resets to EmitStartPt when it makes sense (for
+ /// example, it's usually profitable to avoid function calls between the
+ /// definition and the use)
MachineInstr *LastLocalValue;
- /// The top most instruction in the current block that is allowed for
- /// emitting local variables. LastLocalValue resets to EmitStartPt when
- /// it makes sense (for example, on function calls)
+ /// The top most instruction in the current block that is allowed for emitting
+ /// local variables. LastLocalValue resets to EmitStartPt when it makes sense
+ /// (for example, on function calls)
MachineInstr *EmitStartPt;
public:
- /// getLastLocalValue - Return the position of the last instruction
- /// emitted for materializing constants for use in the current block.
+ /// Return the position of the last instruction emitted for materializing
+ /// constants for use in the current block.
MachineInstr *getLastLocalValue() { return LastLocalValue; }
- /// setLastLocalValue - Update the position of the last instruction
- /// emitted for materializing constants for use in the current block.
+ /// Update the position of the last instruction emitted for materializing
+ /// constants for use in the current block.
void setLastLocalValue(MachineInstr *I) {
EmitStartPt = I;
LastLocalValue = I;
}
- /// startNewBlock - Set the current block to which generated machine
- /// instructions will be appended, and clear the local CSE map.
- ///
+ /// Set the current block to which generated machine instructions will be
+ /// appended, and clear the local CSE map.
void startNewBlock();
- /// getCurDebugLoc() - Return current debug location information.
+ /// Return current debug location information.
DebugLoc getCurDebugLoc() const { return DL; }
- /// LowerArguments - Do "fast" instruction selection for function arguments
- /// and append machine instructions to the current block. Return true if
- /// it is successful.
+ /// Do "fast" instruction selection for function arguments and append machine
+ /// instructions to the current block. Return true if it is successful.
bool LowerArguments();
- /// SelectInstruction - Do "fast" instruction selection for the given
- /// LLVM IR instruction, and append generated machine instructions to
- /// the current block. Return true if selection was successful.
- ///
+ /// Do "fast" instruction selection for the given LLVM IR instruction, and
+ /// append generated machine instructions to the current block. Return true if
+ /// selection was successful.
bool SelectInstruction(const Instruction *I);
- /// SelectOperator - Do "fast" instruction selection for the given
- /// LLVM IR operator (Instruction or ConstantExpr), and append
- /// generated machine instructions to the current block. Return true
- /// if selection was successful.
- ///
+ /// Do "fast" instruction selection for the given LLVM IR operator
+ /// (Instruction or ConstantExpr), and append generated machine instructions
+ /// to the current block. Return true if selection was successful.
bool SelectOperator(const User *I, unsigned Opcode);
- /// getRegForValue - Create a virtual register and arrange for it to
- /// be assigned the value for the given LLVM value.
+ /// Create a virtual register and arrange for it to be assigned the value for
+ /// the given LLVM value.
unsigned getRegForValue(const Value *V);
- /// lookUpRegForValue - Look up the value to see if its value is already
- /// cached in a register. It may be defined by instructions across blocks or
- /// defined locally.
+ /// Look up the value to see if its value is already cached in a register. It
+ /// may be defined by instructions across blocks or defined locally.
unsigned lookUpRegForValue(const Value *V);
- /// getRegForGEPIndex - This is a wrapper around getRegForValue that also
- /// takes care of truncating or sign-extending the given getelementptr
- /// index value.
+ /// This is a wrapper around getRegForValue that also takes care of truncating
+ /// or sign-extending the given getelementptr index value.
std::pair<unsigned, bool> getRegForGEPIndex(const Value *V);
- /// \brief We're checking to see if we can fold \p LI into \p FoldInst.
- /// Note that we could have a sequence where multiple LLVM IR instructions
- /// are folded into the same machineinstr. For example we could have:
+ /// \brief We're checking to see if we can fold \p LI into \p FoldInst. Note
+ /// that we could have a sequence where multiple LLVM IR instructions are
+ /// folded into the same machineinstr. For example we could have:
+ ///
/// A: x = load i32 *P
/// B: y = icmp A, 42
/// C: br y, ...
///
- /// In this scenario, \p LI is "A", and \p FoldInst is "C". We know
- /// about "B" (and any other folded instructions) because it is between
- /// A and C.
+ /// In this scenario, \p LI is "A", and \p FoldInst is "C". We know about "B"
+ /// (and any other folded instructions) because it is between A and C.
///
/// If we succeed folding, return true.
- ///
bool tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst);
- /// \brief The specified machine instr operand is a vreg, and that
- /// vreg is being provided by the specified load instruction. If possible,
- /// try to fold the load as an operand to the instruction, returning true if
+ /// \brief The specified machine instr operand is a vreg, and that vreg is
+ /// being provided by the specified load instruction. If possible, try to
+ /// fold the load as an operand to the instruction, returning true if
/// possible.
+ ///
/// This method should be implemented by targets.
virtual bool tryToFoldLoadIntoMI(MachineInstr * /*MI*/, unsigned /*OpNo*/,
const LoadInst * /*LI*/) {
return false;
}
- /// recomputeInsertPt - Reset InsertPt to prepare for inserting instructions
- /// into the current block.
+ /// Reset InsertPt to prepare for inserting instructions into the current
+ /// block.
void recomputeInsertPt();
- /// removeDeadCode - Remove all dead instructions between the I and E.
+ /// Remove all dead instructions between the I and E.
void removeDeadCode(MachineBasicBlock::iterator I,
MachineBasicBlock::iterator E);
@@ -161,11 +153,11 @@ public:
DebugLoc DL;
};
- /// enterLocalValueArea - Prepare InsertPt to begin inserting instructions
- /// into the local value area and return the old insert position.
+ /// Prepare InsertPt to begin inserting instructions into the local value area
+ /// and return the old insert position.
SavePoint enterLocalValueArea();
- /// leaveLocalValueArea - Reset InsertPt to the given old insert position.
+ /// Reset InsertPt to the given old insert position.
void leaveLocalValueArea(SavePoint Old);
virtual ~FastISel();
@@ -174,69 +166,59 @@ protected:
explicit FastISel(FunctionLoweringInfo &funcInfo,
const TargetLibraryInfo *libInfo);
- /// TargetSelectInstruction - This method is called by target-independent
- /// code when the normal FastISel process fails to select an instruction.
- /// This gives targets a chance to emit code for anything that doesn't
- /// fit into FastISel's framework. It returns true if it was successful.
- ///
+ /// This method is called by target-independent code when the normal FastISel
+ /// process fails to select an instruction. This gives targets a chance to
+ /// emit code for anything that doesn't fit into FastISel's framework. It
+ /// returns true if it was successful.
virtual bool
TargetSelectInstruction(const Instruction *I) = 0;
- /// FastLowerArguments - This method is called by target-independent code to
- /// do target specific argument lowering. It returns true if it was
- /// successful.
+ /// This method is called by target-independent code to do target specific
+ /// argument lowering. It returns true if it was successful.
virtual bool FastLowerArguments();
- /// FastEmit_r - This method is called by target-independent code
- /// to request that an instruction with the given type and opcode
- /// be emitted.
+ /// This method is called by target-independent code to request that an
+ /// instruction with the given type and opcode be emitted.
virtual unsigned FastEmit_(MVT VT,
MVT RetVT,
unsigned Opcode);
- /// FastEmit_r - This method is called by target-independent code
- /// to request that an instruction with the given type, opcode, and
- /// register operand be emitted.
- ///
+ /// This method is called by target-independent code to request that an
+ /// instruction with the given type, opcode, and register operand be emitted.
virtual unsigned FastEmit_r(MVT VT,
MVT RetVT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill);
- /// FastEmit_rr - This method is called by target-independent code
- /// to request that an instruction with the given type, opcode, and
- /// register operands be emitted.
- ///
+ /// This method is called by target-independent code to request that an
+ /// instruction with the given type, opcode, and register operands be emitted.
virtual unsigned FastEmit_rr(MVT VT,
MVT RetVT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill);
- /// FastEmit_ri - This method is called by target-independent code
- /// to request that an instruction with the given type, opcode, and
- /// register and immediate operands be emitted.
- ///
+ /// This method is called by target-independent code to request that an
+ /// instruction with the given type, opcode, and register and immediate
+ /// operands be emitted.
virtual unsigned FastEmit_ri(MVT VT,
MVT RetVT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill,
uint64_t Imm);
- /// FastEmit_rf - This method is called by target-independent code
- /// to request that an instruction with the given type, opcode, and
- /// register and floating-point immediate operands be emitted.
- ///
+ /// This method is called by target-independent code to request that an
+ /// instruction with the given type, opcode, and register and floating-point
+ /// immediate operands be emitted.
virtual unsigned FastEmit_rf(MVT VT,
MVT RetVT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill,
const ConstantFP *FPImm);
- /// FastEmit_rri - This method is called by target-independent code
- /// to request that an instruction with the given type, opcode, and
- /// register and immediate operands be emitted.
- ///
+ /// This method is called by target-independent code to request that an
+ /// instruction with the given type, opcode, and register and immediate
+ /// operands be emitted.
virtual unsigned FastEmit_rri(MVT VT,
MVT RetVT,
unsigned Opcode,
@@ -244,142 +226,130 @@ protected:
unsigned Op1, bool Op1IsKill,
uint64_t Imm);
- /// FastEmit_ri_ - This method is a wrapper of FastEmit_ri. It first tries
- /// to emit an instruction with an immediate operand using FastEmit_ri.
- /// If that fails, it materializes the immediate into a register and try
- /// FastEmit_rr instead.
+ /// \brief This method is a wrapper of FastEmit_ri.
+ ///
+ /// It first tries to emit an instruction with an immediate operand using
+ /// FastEmit_ri. If that fails, it materializes the immediate into a register
+ /// and try FastEmit_rr instead.
unsigned FastEmit_ri_(MVT VT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill,
uint64_t Imm, MVT ImmType);
- /// FastEmit_i - This method is called by target-independent code
- /// to request that an instruction with the given type, opcode, and
- /// immediate operand be emitted.
+ /// This method is called by target-independent code to request that an
+ /// instruction with the given type, opcode, and immediate operand be emitted.
virtual unsigned FastEmit_i(MVT VT,
MVT RetVT,
unsigned Opcode,
uint64_t Imm);
- /// FastEmit_f - This method is called by target-independent code
- /// to request that an instruction with the given type, opcode, and
- /// floating-point immediate operand be emitted.
+ /// This method is called by target-independent code to request that an
+ /// instruction with the given type, opcode, and floating-point immediate
+ /// operand be emitted.
virtual unsigned FastEmit_f(MVT VT,
MVT RetVT,
unsigned Opcode,
const ConstantFP *FPImm);
- /// FastEmitInst_ - Emit a MachineInstr with no operands and a
- /// result register in the given register class.
- ///
+ /// Emit a MachineInstr with no operands and a result register in the given
+ /// register class.
unsigned FastEmitInst_(unsigned MachineInstOpcode,
const TargetRegisterClass *RC);
- /// FastEmitInst_r - Emit a MachineInstr with one register operand
- /// and a result register in the given register class.
- ///
+ /// Emit a MachineInstr with one register operand and a result register in the
+ /// given register class.
unsigned FastEmitInst_r(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill);
- /// FastEmitInst_rr - Emit a MachineInstr with two register operands
- /// and a result register in the given register class.
- ///
+ /// Emit a MachineInstr with two register operands and a result register in
+ /// the given register class.
unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill);
- /// FastEmitInst_rrr - Emit a MachineInstr with three register operands
- /// and a result register in the given register class.
- ///
+ /// Emit a MachineInstr with three register operands and a result register in
+ /// the given register class.
unsigned FastEmitInst_rrr(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill,
unsigned Op2, bool Op2IsKill);
- /// FastEmitInst_ri - Emit a MachineInstr with a register operand,
- /// an immediate, and a result register in the given register class.
- ///
+ /// Emit a MachineInstr with a register operand, an immediate, and a result
+ /// register in the given register class.
unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
uint64_t Imm);
- /// FastEmitInst_rii - Emit a MachineInstr with one register operand
- /// and two immediate operands.
- ///
+ /// Emit a MachineInstr with one register operand and two immediate operands.
unsigned FastEmitInst_rii(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
uint64_t Imm1, uint64_t Imm2);
- /// FastEmitInst_rf - Emit a MachineInstr with two register operands
- /// and a result register in the given register class.
- ///
+ /// Emit a MachineInstr with two register operands and a result register in
+ /// the given register class.
unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
const ConstantFP *FPImm);
- /// FastEmitInst_rri - Emit a MachineInstr with two register operands,
- /// an immediate, and a result register in the given register class.
- ///
+ /// Emit a MachineInstr with two register operands, an immediate, and a result
+ /// register in the given register class.
unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill,
uint64_t Imm);
- /// FastEmitInst_rrii - Emit a MachineInstr with two register operands,
- /// two immediates operands, and a result register in the given register
- /// class.
+ /// Emit a MachineInstr with two register operands, two immediates operands,
+ /// and a result register in the given register class.
unsigned FastEmitInst_rrii(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill,
uint64_t Imm1, uint64_t Imm2);
- /// FastEmitInst_i - Emit a MachineInstr with a single immediate
- /// operand, and a result register in the given register class.
+ /// Emit a MachineInstr with a single immediate operand, and a result register
+ /// in the given register class.
unsigned FastEmitInst_i(unsigned MachineInstrOpcode,
const TargetRegisterClass *RC,
uint64_t Imm);
- /// FastEmitInst_ii - Emit a MachineInstr with a two immediate operands.
+ /// Emit a MachineInstr with a two immediate operands.
unsigned FastEmitInst_ii(unsigned MachineInstrOpcode,
const TargetRegisterClass *RC,
uint64_t Imm1, uint64_t Imm2);
- /// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg
- /// from a specified index of a superregister to a specified type.
+ /// Emit a MachineInstr for an extract_subreg from a specified index of a
+ /// superregister to a specified type.
unsigned FastEmitInst_extractsubreg(MVT RetVT,
unsigned Op0, bool Op0IsKill,
uint32_t Idx);
- /// FastEmitZExtFromI1 - Emit MachineInstrs to compute the value of Op
- /// with all but the least significant bit set to zero.
+ /// Emit MachineInstrs to compute the value of Op with all but the least
+ /// significant bit set to zero.
unsigned FastEmitZExtFromI1(MVT VT,
unsigned Op0, bool Op0IsKill);
- /// FastEmitBranch - Emit an unconditional branch to the given block,
- /// unless it is the immediate (fall-through) successor, and update
- /// the CFG.
+ /// Emit an unconditional branch to the given block, unless it is the
+ /// immediate (fall-through) successor, and update the CFG.
void FastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL);
void UpdateValueMap(const Value* I, unsigned Reg, unsigned NumRegs = 1);
unsigned createResultReg(const TargetRegisterClass *RC);
- /// TargetMaterializeConstant - Emit a constant in a register using
- /// target-specific logic, such as constant pool loads.
+ /// Emit a constant in a register using target-specific logic, such as
+ /// constant pool loads.
virtual unsigned TargetMaterializeConstant(const Constant* C) {
return 0;
}
- /// TargetMaterializeAlloca - Emit an alloca address in a register using
- /// target-specific logic.
+ /// Emit an alloca address in a register using target-specific logic.
virtual unsigned TargetMaterializeAlloca(const AllocaInst* C) {
return 0;
}
@@ -405,25 +375,26 @@ private:
bool SelectInsertValue(const User *I);
- /// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks.
+ /// \brief Handle PHI nodes in successor blocks.
+ ///
/// Emit code to ensure constants are copied into registers when needed.
/// Remember the virtual registers that need to be added to the Machine PHI
- /// nodes as input. We cannot just directly add them, because expansion
- /// might result in multiple MBB's for one BB. As such, the start of the
- /// BB might correspond to a different MBB than the end.
+ /// nodes as input. We cannot just directly add them, because expansion might
+ /// result in multiple MBB's for one BB. As such, the start of the BB might
+ /// correspond to a different MBB than the end.
bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
- /// materializeRegForValue - Helper for getRegForVale. This function is
- /// called when the value isn't already available in a register and must
- /// be materialized with new instructions.
+ /// Helper for getRegForVale. This function is called when the value isn't
+ /// already available in a register and must be materialized with new
+ /// instructions.
unsigned materializeRegForValue(const Value *V, MVT VT);
- /// flushLocalValueMap - clears LocalValueMap and moves the area for the
- /// new local variables to the beginning of the block. It helps to avoid
- /// spilling cached variables across heavy instructions like calls.
+ /// Clears LocalValueMap and moves the area for the new local variables to the
+ /// beginning of the block. It helps to avoid spilling cached variables across
+ /// heavy instructions like calls.
void flushLocalValueMap();
- /// hasTrivialKill - Test whether the given value has exactly one use.
+ /// Test whether the given value has exactly one use.
bool hasTrivialKill(const Value *V) const;
};
diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h
index 206fef7..50d320f 100644
--- a/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -50,7 +50,6 @@ class Value;
///
class FunctionLoweringInfo {
const TargetMachine &TM;
- const TargetLowering *TLI;
public:
const Function *Fn;
MachineFunction *MF;
@@ -116,7 +115,12 @@ public:
/// there's no other convenient place for it to live right now.
std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
- explicit FunctionLoweringInfo(const TargetMachine &TM);
+ /// If the current MBB is a landing pad, the exception pointer and exception
+ /// selector registers are copied into these virtual registers by
+ /// SelectionDAGISel::PrepareEHLandingPad().
+ unsigned ExceptionPointerVirtReg, ExceptionSelectorVirtReg;
+
+ explicit FunctionLoweringInfo(const TargetMachine &TM) : TM(TM) {}
/// set - Initialize this FunctionLoweringInfo with the given Function
/// and its associated MachineFunction.
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index 0fd211b..9466b90 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -77,18 +77,6 @@ namespace ISD {
/// adjustment during unwind.
FRAME_TO_ARGS_OFFSET,
- /// RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the
- /// address of the exception block on entry to an landing pad block.
- EXCEPTIONADDR,
-
- /// RESULT, OUTCHAIN = LSDAADDR(INCHAIN) - This node represents the
- /// address of the Language Specific Data Area for the enclosing function.
- LSDAADDR,
-
- /// RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node
- /// represents the selection index of the exception thrown.
- EHSELECTION,
-
/// OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
/// 'eh_return' gcc dwarf builtin, which is used to return from
/// exception. The general meaning is: adjust stack by OFFSET and pass
@@ -647,7 +635,7 @@ namespace ISD {
/// which do not reference a specific memory location should be less than
/// this value. Those that do must not be less than this value, and can
/// be used with SelectionDAG::getMemIntrinsicNode.
- static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+150;
+ static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+180;
//===--------------------------------------------------------------------===//
/// MemIndexedMode enum - This enum defines the load / store indexed
diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h
index ff65db4..26563a6 100644
--- a/include/llvm/CodeGen/LexicalScopes.h
+++ b/include/llvm/CodeGen/LexicalScopes.h
@@ -141,8 +141,8 @@ private:
DenseMap<const MDNode *, LexicalScope *> AbstractScopeMap;
/// AbstractScopesList - Tracks abstract scopes constructed while processing
- /// a function.
- SmallVector<LexicalScope *, 4>AbstractScopesList;
+ /// a function.
+ SmallVector<LexicalScope *, 4> AbstractScopesList;
/// CurrentFnLexicalScope - Top level scope for the current function.
///
@@ -166,13 +166,13 @@ public:
virtual ~LexicalScope() {}
// Accessors.
- LexicalScope *getParent() const { return Parent; }
- const MDNode *getDesc() const { return Desc; }
- const MDNode *getInlinedAt() const { return InlinedAtLocation; }
- const MDNode *getScopeNode() const { return Desc; }
- bool isAbstractScope() const { return AbstractScope; }
- SmallVector<LexicalScope *, 4> &getChildren() { return Children; }
- SmallVector<InsnRange, 4> &getRanges() { return Ranges; }
+ LexicalScope *getParent() const { return Parent; }
+ const MDNode *getDesc() const { return Desc; }
+ const MDNode *getInlinedAt() const { return InlinedAtLocation; }
+ const MDNode *getScopeNode() const { return Desc; }
+ bool isAbstractScope() const { return AbstractScope; }
+ SmallVectorImpl<LexicalScope *> &getChildren() { return Children; }
+ SmallVectorImpl<InsnRange> &getRanges() { return Ranges; }
/// addChild - Add a child scope.
void addChild(LexicalScope *S) { Children.push_back(S); }
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index cb09a49..efad0c6 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -389,7 +389,7 @@ namespace llvm {
void join(LiveInterval &Other,
const int *ValNoAssignments,
const int *RHSValNoAssignments,
- SmallVector<VNInfo*, 16> &NewVNInfo,
+ SmallVectorImpl<VNInfo *> &NewVNInfo,
MachineRegisterInfo *MRI);
/// isInOneLiveRange - Return true if the range specified is entirely in the
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index 7d72f37..ffb07a5 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -35,6 +35,7 @@ namespace llvm {
class AliasAnalysis;
class BitVector;
+ class BlockFrequency;
class LiveRangeCalc;
class LiveVariables;
class MachineDominatorTree;
@@ -99,7 +100,7 @@ namespace llvm {
virtual ~LiveIntervals();
// Calculate the spill weight to assign to a single instruction.
- static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);
+ static float getSpillWeight(bool isDef, bool isUse, BlockFrequency freq);
LiveInterval &getInterval(unsigned Reg) {
LiveInterval *LI = VirtRegIntervals[Reg];
diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h
index e59276f..a8749da 100644
--- a/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/include/llvm/CodeGen/LiveRangeEdit.h
@@ -19,6 +19,7 @@
#define LLVM_CODEGEN_LIVERANGEEDIT_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/Target/TargetMachine.h"
@@ -27,6 +28,7 @@ namespace llvm {
class AliasAnalysis;
class LiveIntervals;
+class MachineBlockFrequencyInfo;
class MachineLoopInfo;
class MachineRegisterInfo;
class VirtRegMap;
@@ -89,6 +91,12 @@ private:
/// a load, eliminate the register by folding the def into the use.
bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead);
+ typedef SetVector<LiveInterval*,
+ SmallVector<LiveInterval*, 8>,
+ SmallPtrSet<LiveInterval*, 8> > ToShrinkSet;
+ /// Helper for eliminateDeadDefs.
+ void eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink);
+
public:
/// Create a LiveRangeEdit for breaking down parent into smaller pieces.
/// @param parent The register being spilled or split.
@@ -201,7 +209,8 @@ public:
/// calculateRegClassAndHint - Recompute register class and hint for each new
/// register.
void calculateRegClassAndHint(MachineFunction&,
- const MachineLoopInfo&);
+ const MachineLoopInfo&,
+ const MachineBlockFrequencyInfo&);
};
}
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h
index 6628fd2..dc735f7 100644
--- a/include/llvm/CodeGen/LiveVariables.h
+++ b/include/llvm/CodeGen/LiveVariables.h
@@ -157,8 +157,8 @@ private: // Intermediate data structures
void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
void HandlePhysRegDef(unsigned Reg, MachineInstr *MI,
- SmallVector<unsigned, 4> &Defs);
- void UpdatePhysRegDefs(MachineInstr *MI, SmallVector<unsigned, 4> &Defs);
+ SmallVectorImpl<unsigned> &Defs);
+ void UpdatePhysRegDefs(MachineInstr *MI, SmallVectorImpl<unsigned> &Defs);
/// FindLastRefOrPartRef - Return the last reference or partial reference of
/// the specified register.
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 0f2f874..d6f5883 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -296,6 +296,11 @@ public:
/// is an error to add the same register to the same set more than once.
void addLiveIn(unsigned Reg) { LiveIns.push_back(Reg); }
+ /// Add PhysReg as live in to this block, and ensure that there is a copy of
+ /// PhysReg to a virtual register of class RC. Return the virtual register
+ /// that is a copy of the live in PhysReg.
+ unsigned addLiveIn(unsigned PhysReg, const TargetRegisterClass *RC);
+
/// removeLiveIn - Remove the specified register from the live in set.
///
void removeLiveIn(unsigned Reg);
diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h
index 8ed215d..912ce89 100644
--- a/include/llvm/CodeGen/MachineConstantPool.h
+++ b/include/llvm/CodeGen/MachineConstantPool.h
@@ -132,15 +132,17 @@ public:
/// address of the function constant pool values.
/// @brief The machine constant pool.
class MachineConstantPool {
- const DataLayout *TD; ///< The machine's DataLayout.
- unsigned PoolAlignment; ///< The alignment for the pool.
+ const TargetMachine &TM; ///< The target machine.
+ unsigned PoolAlignment; ///< The alignment for the pool.
std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
/// MachineConstantPoolValues that use an existing MachineConstantPoolEntry.
DenseSet<MachineConstantPoolValue*> MachineCPVsSharingEntries;
+
+ const DataLayout *getDataLayout() const;
public:
/// @brief The only constructor.
- explicit MachineConstantPool(const DataLayout *td)
- : TD(td), PoolAlignment(1) {}
+ explicit MachineConstantPool(const TargetMachine &TM)
+ : TM(TM), PoolAlignment(1) {}
~MachineConstantPool();
/// getConstantPoolAlignment - Return the alignment required by
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index cdec7e6..022634d 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -27,6 +27,7 @@ class Type;
class MachineFunction;
class MachineBasicBlock;
class TargetFrameLowering;
+class TargetMachine;
class BitVector;
class Value;
class AllocaInst;
@@ -119,6 +120,8 @@ class MachineFrameInfo {
isSpillSlot(isSS), MayNeedSP(NSP), Alloca(Val), PreAllocated(false) {}
};
+ const TargetMachine &TM;
+
/// Objects - The list of stack objects allocated...
///
std::vector<StackObject> Objects;
@@ -201,10 +204,6 @@ class MachineFrameInfo {
/// CSIValid - Has CSInfo been set yet?
bool CSIValid;
- /// TargetFrameLowering - Target information about frame layout.
- ///
- const TargetFrameLowering &TFI;
-
/// LocalFrameObjects - References to frame indices which are mapped
/// into the local frame allocation block. <FrameIdx, LocalOffset>
SmallVector<std::pair<int, int64_t>, 32> LocalFrameObjects;
@@ -223,9 +222,11 @@ class MachineFrameInfo {
/// Whether the "realign-stack" option is on.
bool RealignOption;
+
+ const TargetFrameLowering *getFrameLowering() const;
public:
- explicit MachineFrameInfo(const TargetFrameLowering &tfi, bool RealignOpt)
- : TFI(tfi), RealignOption(RealignOpt) {
+ explicit MachineFrameInfo(const TargetMachine &TM, bool RealignOpt)
+ : TM(TM), RealignOption(RealignOpt) {
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
HasVarSizedObjects = false;
FrameAddressTaken = false;
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 195cce7..cf5e7e2 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -908,11 +908,6 @@ public:
bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA,
bool &SawStore) const;
- /// isSafeToReMat - Return true if it's safe to rematerialize the specified
- /// instruction which defined the specified register instead of copying it.
- bool isSafeToReMat(const TargetInstrInfo *TII, AliasAnalysis *AA,
- unsigned DstReg) const;
-
/// hasOrderedMemoryRef - Return true if this instruction may have an ordered
/// or volatile memory reference, or if the information describing the memory
/// reference is not available. Return false if it is known to have no
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index 92c8da9..df01371 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -335,6 +335,51 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
return BuildMI(*BB, BB->end(), DL, MCID, DestReg);
}
+/// BuildMI - This version of the builder builds a DBG_VALUE intrinsic
+/// for either a value in a register or a register-indirect+offset
+/// address. The convention is that a DBG_VALUE is indirect iff the
+/// second operand is an immediate.
+///
+inline MachineInstrBuilder BuildMI(MachineFunction &MF,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ bool IsIndirect,
+ unsigned Reg,
+ unsigned Offset,
+ const MDNode *MD) {
+ if (IsIndirect)
+ return BuildMI(MF, DL, MCID)
+ .addReg(Reg, RegState::Debug)
+ .addImm(Offset)
+ .addMetadata(MD);
+ else {
+ assert(Offset == 0 && "A direct address cannot have an offset.");
+ return BuildMI(MF, DL, MCID)
+ .addReg(Reg, RegState::Debug)
+ .addReg(0U, RegState::Debug)
+ .addMetadata(MD);
+ }
+}
+
+/// BuildMI - This version of the builder builds a DBG_VALUE intrinsic
+/// for either a value in a register or a register-indirect+offset
+/// address and inserts it at position I.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ bool IsIndirect,
+ unsigned Reg,
+ unsigned Offset,
+ const MDNode *MD) {
+ MachineFunction &MF = *BB.getParent();
+ MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, MD);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MF, MI);
+}
+
+
inline unsigned getDefRegState(bool B) {
return B ? RegState::Define : 0;
}
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 414770b..57b28fe 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -391,7 +391,7 @@ public:
}
void setIsDebug(bool Val = true) {
- assert(isReg() && IsDef && "Wrong MachineOperand accessor");
+ assert(isReg() && !IsDef && "Wrong MachineOperand accessor");
IsDebug = Val;
}
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 24ba7bb..7a6dcd0 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <vector>
@@ -26,7 +27,7 @@ namespace llvm {
/// registers, including vreg register classes, use/def chains for registers,
/// etc.
class MachineRegisterInfo {
- const TargetRegisterInfo *const TRI;
+ const TargetMachine &TM;
/// IsSSA - True when the machine function is in SSA form and virtual
/// registers have a single def.
@@ -108,9 +109,13 @@ class MachineRegisterInfo {
MachineRegisterInfo(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION;
void operator=(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION;
public:
- explicit MachineRegisterInfo(const TargetRegisterInfo &TRI);
+ explicit MachineRegisterInfo(const TargetMachine &TM);
~MachineRegisterInfo();
+ const TargetRegisterInfo *getTargetRegisterInfo() const {
+ return TM.getRegisterInfo();
+ }
+
//===--------------------------------------------------------------------===//
// Function State
//===--------------------------------------------------------------------===//
@@ -377,7 +382,8 @@ public:
bool isPhysRegUsed(unsigned Reg) const {
if (UsedPhysRegMask.test(Reg))
return true;
- for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
+ for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
+ Units.isValid(); ++Units)
if (UsedRegUnits.test(*Units))
return true;
return false;
@@ -392,7 +398,8 @@ public:
/// setPhysRegUsed - Mark the specified register used in this function.
/// This should only be called during and after register allocation.
void setPhysRegUsed(unsigned Reg) {
- for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
+ for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
+ Units.isValid(); ++Units)
UsedRegUnits.set(*Units);
}
@@ -406,7 +413,8 @@ public:
/// This should only be called during and after register allocation.
void setPhysRegUnused(unsigned Reg) {
UsedPhysRegMask.reset(Reg);
- for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
+ for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
+ Units.isValid(); ++Units)
UsedRegUnits.reset(*Units);
}
@@ -466,7 +474,8 @@ public:
/// register, so a register allocator needs to track its liveness and
/// availability.
bool isAllocatable(unsigned PhysReg) const {
- return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg);
+ return getTargetRegisterInfo()->isInAllocatableClass(PhysReg) &&
+ !isReserved(PhysReg);
}
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
index 769e4b4..d110ea1 100644
--- a/include/llvm/CodeGen/MachineScheduler.h
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -30,7 +30,6 @@
#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
-#include "llvm/Target/TargetInstrInfo.h"
namespace llvm {
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 7ec90ae..9b6f61e 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -308,7 +308,8 @@ protected:
AnalysisID addPass(AnalysisID PassID);
/// Add a pass to the PassManager if that pass is supposed to be run, as
- /// determined by the StartAfter and StopAfter options.
+ /// determined by the StartAfter and StopAfter options. Takes ownership of the
+ /// pass.
void addPass(Pass *P);
/// addMachinePasses helper to create the target-selected or overriden
@@ -329,7 +330,7 @@ namespace llvm {
/// This pass implements the target transform info analysis using the target
/// independent information available to the LLVM code generator.
ImmutablePass *
- createBasicTargetTransformInfoPass(const TargetLoweringBase *TLI);
+ createBasicTargetTransformInfoPass(const TargetMachine *TM);
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
/// work well with unreachable basic blocks (what live ranges make sense for a
@@ -518,7 +519,7 @@ namespace llvm {
/// createStackProtectorPass - This pass adds stack protectors to functions.
///
- FunctionPass *createStackProtectorPass(const TargetLoweringBase *tli);
+ FunctionPass *createStackProtectorPass(const TargetMachine *TM);
/// createMachineVerifierPass - This pass verifies cenerated machine code
/// instructions for correctness.
@@ -527,12 +528,12 @@ namespace llvm {
/// createDwarfEHPass - This pass mulches exception handling code into a form
/// adapted to code generation. Required if using dwarf exception handling.
- FunctionPass *createDwarfEHPass(const TargetLoweringBase *tli);
+ FunctionPass *createDwarfEHPass(const TargetMachine *TM);
/// createSjLjEHPreparePass - This pass adapts exception handling code to use
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
///
- FunctionPass *createSjLjEHPreparePass(const TargetLoweringBase *tli);
+ FunctionPass *createSjLjEHPreparePass(const TargetMachine *TM);
/// LocalStackSlotAllocation - This pass assigns local frame indices to stack
/// slots relative to one another and allocates base registers to access them
diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h
index 8b8e3d9..6f2d139 100644
--- a/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/include/llvm/CodeGen/RegAllocPBQP.h
@@ -26,8 +26,8 @@
namespace llvm {
class LiveIntervals;
+ class MachineBlockFrequencyInfo;
class MachineFunction;
- class MachineLoopInfo;
class TargetRegisterInfo;
template<class T> class OwningPtr;
@@ -125,7 +125,7 @@ namespace llvm {
/// Build a PBQP instance to represent the register allocation problem for
/// the given MachineFunction.
virtual PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals *lis,
- const MachineLoopInfo *loopInfo,
+ const MachineBlockFrequencyInfo *mbfi,
const RegSet &vregs);
private:
@@ -144,7 +144,7 @@ namespace llvm {
/// Build a PBQP instance to represent the register allocation problem for
/// the given MachineFunction.
virtual PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals *lis,
- const MachineLoopInfo *loopInfo,
+ const MachineBlockFrequencyInfo *mbfi,
const RegSet &vregs);
private:
diff --git a/include/llvm/CodeGen/RegisterClassInfo.h b/include/llvm/CodeGen/RegisterClassInfo.h
index 3ad22e6..9ec12bd 100644
--- a/include/llvm/CodeGen/RegisterClassInfo.h
+++ b/include/llvm/CodeGen/RegisterClassInfo.h
@@ -62,6 +62,8 @@ class RegisterClassInfo {
// Reserved registers in the current MF.
BitVector Reserved;
+ OwningArrayPtr<unsigned> PSetLimits;
+
// Compute all information about RC.
void compute(const TargetRegisterClass *RC) const;
@@ -126,8 +128,19 @@ public:
unsigned getLastCostChange(const TargetRegisterClass *RC) {
return get(RC).LastCostChange;
}
+
+ /// Get the register unit limit for the given pressure set index.
+ ///
+ /// RegisterClassInfo adjusts this limit for reserved registers.
+ unsigned getRegPressureSetLimit(unsigned Idx) const {
+ if (!PSetLimits[Idx])
+ PSetLimits[Idx] = computePSetLimit(Idx);
+ return PSetLimits[Idx];
+ }
+
+protected:
+ unsigned computePSetLimit(unsigned Idx) const;
};
} // end namespace llvm
#endif
-
diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h
index 2670180..8a0a8f3 100644
--- a/include/llvm/CodeGen/RegisterPressure.h
+++ b/include/llvm/CodeGen/RegisterPressure.h
@@ -99,6 +99,10 @@ struct PressureElement {
PressureElement(unsigned id, int inc): PSetID(id), UnitIncrease(inc) {}
bool isValid() const { return PSetID != ~0U; }
+
+ // If signed PSetID is negative, it is invalid; convert it to INT_MAX to give
+ // it lowest priority.
+ int PSetRank() const { return PSetID & INT_MAX; }
};
/// Store the effects of a change in pressure on things that MI scheduler cares
@@ -183,6 +187,9 @@ class RegPressureTracker {
/// or RegisterPressure. If requireIntervals is false, LIS are ignored.
bool RequireIntervals;
+ /// True if UntiedDefs will be populated.
+ bool TrackUntiedDefs;
+
/// Register pressure corresponds to liveness before this instruction
/// iterator. It may point to the end of the block or a DebugValue rather than
/// an instruction.
@@ -194,16 +201,24 @@ class RegPressureTracker {
/// Set of live registers.
LiveRegSet LiveRegs;
+ /// Set of vreg defs that start a live range.
+ SparseSet<unsigned, VirtReg2IndexFunctor> UntiedDefs;
+ /// Live-through pressure.
+ std::vector<unsigned> LiveThruPressure;
+
public:
RegPressureTracker(IntervalPressure &rp) :
- MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(true) {}
+ MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(true),
+ TrackUntiedDefs(false) {}
RegPressureTracker(RegionPressure &rp) :
- MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(false) {}
+ MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(false),
+ TrackUntiedDefs(false) {}
void init(const MachineFunction *mf, const RegisterClassInfo *rci,
const LiveIntervals *lis, const MachineBasicBlock *mbb,
- MachineBasicBlock::const_iterator pos);
+ MachineBasicBlock::const_iterator pos,
+ bool ShouldTrackUntiedDefs = false);
/// Force liveness of virtual registers or physical register
/// units. Particularly useful to initialize the livein/out state of the
@@ -232,6 +247,17 @@ public:
/// Finalize the region boundaries and recored live ins and live outs.
void closeRegion();
+ /// Initialize the LiveThru pressure set based on the untied defs found in
+ /// RPTracker.
+ void initLiveThru(const RegPressureTracker &RPTracker);
+
+ /// Copy an existing live thru pressure result.
+ void initLiveThru(ArrayRef<unsigned> PressureSet) {
+ LiveThruPressure.assign(PressureSet.begin(), PressureSet.end());
+ }
+
+ ArrayRef<unsigned> getLiveThru() const { return LiveThruPressure; }
+
/// Get the resulting register pressure over the traversed region.
/// This result is complete if either advance() or recede() has returned true,
/// or if closeRegion() was explicitly invoked.
@@ -304,6 +330,10 @@ public:
return getDownwardPressure(MI, PressureResult, MaxPressureResult);
}
+ bool hasUntiedDef(unsigned VirtReg) const {
+ return UntiedDefs.count(VirtReg);
+ }
+
void dump() const;
protected:
@@ -315,6 +345,11 @@ protected:
void bumpUpwardPressure(const MachineInstr *MI);
void bumpDownwardPressure(const MachineInstr *MI);
};
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+void dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
+ const TargetRegisterInfo *TRI);
+#endif
} // end namespace llvm
#endif
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
index 95bf291..28ebe53 100644
--- a/include/llvm/CodeGen/RegisterScavenging.h
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -131,7 +131,7 @@ public:
/// Query whether a frame index is a scavenging frame index.
bool isScavengingFrameIndex(int FI) const {
- for (SmallVector<ScavengedInfo, 2>::const_iterator I = Scavenged.begin(),
+ for (SmallVectorImpl<ScavengedInfo>::const_iterator I = Scavenged.begin(),
IE = Scavenged.end(); I != IE; ++I)
if (I->FrameIndex == FI)
return true;
@@ -141,7 +141,7 @@ public:
/// Get an array of scavenging frame indices.
void getScavengingFrameIndices(SmallVectorImpl<int> &A) const {
- for (SmallVector<ScavengedInfo, 2>::const_iterator I = Scavenged.begin(),
+ for (SmallVectorImpl<ScavengedInfo>::const_iterator I = Scavenged.begin(),
IE = Scavenged.end(); I != IE; ++I)
if (I->FrameIndex >= 0)
A.push_back(I->FrameIndex);
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 7cff27e..371ac6c 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -90,11 +90,6 @@ namespace llvm {
/// the value of the Latency field of the predecessor, however advanced
/// models may provide additional information about specific edges.
unsigned Latency;
- /// Record MinLatency seperately from "expected" Latency.
- ///
- /// FIXME: this field is not packed on LP64. Convert to 16-bit DAG edge
- /// latency after introducing saturating truncation.
- unsigned MinLatency;
public:
/// SDep - Construct a null SDep. This is only for use by container
@@ -120,10 +115,9 @@ namespace llvm {
Latency = 1;
break;
}
- MinLatency = Latency;
}
SDep(SUnit *S, OrderKind kind)
- : Dep(S, Order), Contents(), Latency(0), MinLatency(0) {
+ : Dep(S, Order), Contents(), Latency(0) {
Contents.OrdKind = kind;
}
@@ -142,8 +136,7 @@ namespace llvm {
}
bool operator==(const SDep &Other) const {
- return overlaps(Other)
- && Latency == Other.Latency && MinLatency == Other.MinLatency;
+ return overlaps(Other) && Latency == Other.Latency;
}
bool operator!=(const SDep &Other) const {
@@ -163,18 +156,6 @@ namespace llvm {
Latency = Lat;
}
- /// getMinLatency - Return the minimum latency for this edge. Minimum
- /// latency is used for scheduling groups, while normal (expected) latency
- /// is for instruction cost and critical path.
- unsigned getMinLatency() const {
- return MinLatency;
- }
-
- /// setMinLatency - Set the minimum latency for this edge.
- void setMinLatency(unsigned Lat) {
- MinLatency = Lat;
- }
-
//// getSUnit - Return the SUnit to which this edge points.
SUnit *getSUnit() const {
return Dep.getPointer();
@@ -282,10 +263,10 @@ namespace llvm {
SmallVector<SDep, 4> Preds; // All sunit predecessors.
SmallVector<SDep, 4> Succs; // All sunit successors.
- typedef SmallVector<SDep, 4>::iterator pred_iterator;
- typedef SmallVector<SDep, 4>::iterator succ_iterator;
- typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator;
- typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator;
+ typedef SmallVectorImpl<SDep>::iterator pred_iterator;
+ typedef SmallVectorImpl<SDep>::iterator succ_iterator;
+ typedef SmallVectorImpl<SDep>::const_iterator const_pred_iterator;
+ typedef SmallVectorImpl<SDep>::const_iterator const_succ_iterator;
unsigned NodeNum; // Entry # of node in the node vector.
unsigned NodeQueueId; // Queue id of node.
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 990cac6..9ab1013 100644
--- a/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -158,7 +158,7 @@ namespace llvm {
/// \brief Resolve and cache a resolved scheduling class for an SUnit.
const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
- if (!SU->SchedClass)
+ if (!SU->SchedClass && SchedModel.hasInstrSchedModel())
SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
return SU->SchedClass;
}
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 487ab28..79e533e 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -72,7 +72,8 @@ private:
class SDDbgInfo {
SmallVector<SDDbgValue*, 32> DbgValues;
SmallVector<SDDbgValue*, 32> ByvalParmDbgValues;
- DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMap;
+ typedef DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMapType;
+ DbgValMapType DbgValMap;
void operator=(const SDDbgInfo&) LLVM_DELETED_FUNCTION;
SDDbgInfo(const SDDbgInfo&) LLVM_DELETED_FUNCTION;
@@ -98,14 +99,13 @@ public:
}
ArrayRef<SDDbgValue*> getSDDbgValues(const SDNode *Node) {
- DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> >::iterator I =
- DbgValMap.find(Node);
+ DbgValMapType::iterator I = DbgValMap.find(Node);
if (I != DbgValMap.end())
return I->second;
return ArrayRef<SDDbgValue*>();
}
- typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator;
+ typedef SmallVectorImpl<SDDbgValue*>::iterator DbgIterator;
DbgIterator DbgBegin() { return DbgValues.begin(); }
DbgIterator DbgEnd() { return DbgValues.end(); }
DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); }
@@ -129,7 +129,6 @@ void checkForCycles(const SelectionDAG *DAG);
///
class SelectionDAG {
const TargetMachine &TM;
- const TargetLowering &TLI;
const TargetSelectionDAGInfo &TSI;
const TargetTransformInfo *TTI;
MachineFunction *MF;
@@ -232,7 +231,9 @@ public:
MachineFunction &getMachineFunction() const { return *MF; }
const TargetMachine &getTarget() const { return TM; }
- const TargetLowering &getTargetLoweringInfo() const { return TLI; }
+ const TargetLowering &getTargetLoweringInfo() const {
+ return *TM.getTargetLowering();
+ }
const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
const TargetTransformInfo *getTargetTransformInfo() const { return TTI; }
LLVMContext *getContext() const {return Context; }
@@ -609,9 +610,23 @@ public:
"Cannot compare scalars to vectors");
assert(LHS.getValueType().isVector() == VT.isVector() &&
"Cannot compare scalars to vectors");
+ assert(Cond != ISD::SETCC_INVALID &&
+ "Cannot create a setCC of an invalid node.");
return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
}
+ // getSelect - Helper function to make it easier to build Select's if you just
+ // have operands and don't want to check for vector.
+ SDValue getSelect(SDLoc DL, EVT VT, SDValue Cond,
+ SDValue LHS, SDValue RHS) {
+ assert(LHS.getValueType() == RHS.getValueType() &&
+ "Cannot use select on differing types");
+ assert(VT.isVector() == LHS.getValueType().isVector() &&
+ "Cannot mix vectors and scalars");
+ return getNode(Cond.getValueType().isVector() ? ISD::VSELECT : ISD::SELECT, DL, VT,
+ Cond, LHS, RHS);
+ }
+
/// getSelectCC - Helper function to make it easier to build SelectCC's if you
/// just have an ISD::CondCode instead of an SDValue.
///
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index 37bbc1f..3d55d3a 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -30,7 +30,6 @@ namespace llvm {
class MachineInstr;
class TargetLowering;
class TargetLibraryInfo;
- class TargetInstrInfo;
class TargetTransformInfo;
class FunctionLoweringInfo;
class ScheduleHazardRecognizer;
@@ -42,8 +41,7 @@ namespace llvm {
/// pattern-matching instruction selectors.
class SelectionDAGISel : public MachineFunctionPass {
public:
- const TargetMachine &TM;
- const TargetLowering *TLI;
+ TargetMachine &TM;
const TargetLibraryInfo *LibInfo;
const TargetTransformInfo *TTI;
FunctionLoweringInfo *FuncInfo;
@@ -56,11 +54,13 @@ public:
CodeGenOpt::Level OptLevel;
static char ID;
- explicit SelectionDAGISel(const TargetMachine &tm,
+ explicit SelectionDAGISel(TargetMachine &tm,
CodeGenOpt::Level OL = CodeGenOpt::Default);
virtual ~SelectionDAGISel();
- const TargetLowering *getTargetLowering() { return TLI; }
+ const TargetLowering *getTargetLowering() const {
+ return TM.getTargetLowering();
+ }
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 0f45dc8..987f290 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -539,7 +539,7 @@ public:
/// NOTE: This is still very expensive. Use carefully.
bool hasPredecessorHelper(const SDNode *N,
SmallPtrSet<const SDNode *, 32> &Visited,
- SmallVector<const SDNode *, 16> &Worklist) const;
+ SmallVectorImpl<const SDNode *> &Worklist) const;
/// getNumOperands - Return the number of values used by this operation.
///
@@ -1181,7 +1181,8 @@ class ShuffleVectorSDNode : public SDNode {
const int *Mask;
protected:
friend class SelectionDAG;
- ShuffleVectorSDNode(EVT VT, unsigned Order, DebugLoc dl, SDValue N1, SDValue N2, const int *M)
+ ShuffleVectorSDNode(EVT VT, unsigned Order, DebugLoc dl, SDValue N1,
+ SDValue N2, const int *M)
: SDNode(ISD::VECTOR_SHUFFLE, Order, dl, getSDVTList(VT)), Mask(M) {
InitOperands(Ops, N1, N2);
}
@@ -1195,16 +1196,16 @@ public:
assert(Idx < getValueType(0).getVectorNumElements() && "Idx out of range!");
return Mask[Idx];
}
-
+
bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
- int getSplatIndex() const {
+ int getSplatIndex() const {
assert(isSplat() && "Cannot get splat index for non-splat!");
EVT VT = getValueType(0);
for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
- if (Mask[i] != -1)
+ if (Mask[i] >= 0)
return Mask[i];
}
- return -1;
+ llvm_unreachable("Splat with all undef indices?");
}
static bool isSplatMask(const int *Mask, EVT VT);
@@ -1212,7 +1213,7 @@ public:
return N->getOpcode() == ISD::VECTOR_SHUFFLE;
}
};
-
+
class ConstantSDNode : public SDNode {
const ConstantInt *Value;
friend class SelectionDAG;
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
index 676cdaf..984796a 100644
--- a/include/llvm/CodeGen/SlotIndexes.h
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -59,7 +59,7 @@ namespace llvm {
// poisoned, so that dangling SlotIndex access can be reliably detected.
void setPoison() {
intptr_t tmp = reinterpret_cast<intptr_t>(mi);
- assert(((tmp & 0x1) == 0x0) && "Pointer already poisoned?");
+ assert(((tmp & 0x1) == 0x0) && "Pointer already poisoned?");
tmp |= 0x1;
mi = reinterpret_cast<MachineInstr*>(tmp);
}
@@ -218,6 +218,13 @@ namespace llvm {
return other.getIndex() - getIndex();
}
+ /// Return the scaled distance from this index to the given one, where all
+ /// slots on the same instruction have zero distance.
+ int getInstrDistance(SlotIndex other) const {
+ return (other.listEntry()->getIndex() - listEntry()->getIndex())
+ / Slot_Count;
+ }
+
/// isBlock - Returns true if this is a block boundary slot.
bool isBlock() const { return getSlot() == Slot_Block; }
@@ -672,7 +679,7 @@ namespace llvm {
/// performance. Any remaining SlotIndex objects that point to the same
/// index are left 'dangling' (much the same as a dangling pointer to a
/// freed object) and should not be accessed, except to destruct them.
- ///
+ ///
/// Like dangling pointers, access to dangling SlotIndexes can cause
/// painful-to-track-down bugs, especially if the memory for the index
/// previously pointed to has been re-used. To detect dangling SlotIndex
diff --git a/include/llvm/CodeGen/TargetSchedule.h b/include/llvm/CodeGen/TargetSchedule.h
index 3e22252..f2adcf8 100644
--- a/include/llvm/CodeGen/TargetSchedule.h
+++ b/include/llvm/CodeGen/TargetSchedule.h
@@ -84,9 +84,6 @@ public:
/// \brief Maximum number of micro-ops that may be scheduled per cycle.
unsigned getIssueWidth() const { return SchedModel.IssueWidth; }
- /// \brief Number of cycles the OOO processor is expected to hide.
- unsigned getILPWindow() const { return SchedModel.ILPWindow; }
-
/// \brief Return the number of issue slots required for this MI.
unsigned getNumMicroOps(const MachineInstr *MI,
const MCSchedClassDesc *SC = 0) const;
@@ -131,18 +128,23 @@ public:
return ResourceLCM;
}
+ /// \brief Number of micro-ops that may be buffered for OOO execution.
+ unsigned getMicroOpBufferSize() const { return SchedModel.MicroOpBufferSize; }
+
+ /// \brief Number of resource units that may be buffered for OOO execution.
+ /// \return The buffer size in resource units or -1 for unlimited.
+ int getResourceBufferSize(unsigned PIdx) const {
+ return SchedModel.getProcResource(PIdx)->BufferSize;
+ }
+
/// \brief Compute operand latency based on the available machine model.
///
- /// Computes and return the latency of the given data dependent def and use
+ /// Compute and return the latency of the given data dependent def and use
/// when the operand indices are already known. UseMI may be NULL for an
/// unknown user.
- ///
- /// FindMin may be set to get the minimum vs. expected latency. Minimum
- /// latency is used for scheduling groups, while expected latency is for
- /// instruction cost and critical path.
unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx,
- const MachineInstr *UseMI, unsigned UseOperIdx,
- bool FindMin) const;
+ const MachineInstr *UseMI, unsigned UseOperIdx)
+ const;
/// \brief Compute the instruction latency based on the available machine
/// model.
@@ -157,12 +159,6 @@ public:
/// This is typically one cycle.
unsigned computeOutputLatency(const MachineInstr *DefMI, unsigned DefIdx,
const MachineInstr *DepMI) const;
-
-private:
- /// getDefLatency is a helper for computeOperandLatency. Return the
- /// instruction's latency if operand lookup is not required.
- /// Otherwise return -1.
- int getDefLatency(const MachineInstr *DefMI, bool FindMin) const;
};
} // namespace llvm
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index ec48b67..b7b3d73 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -343,6 +343,10 @@ namespace llvm {
unsigned getSizeInBits() const {
switch (SimpleTy) {
+ default:
+ llvm_unreachable("getSizeInBits called on extended MVT.");
+ case Other:
+ llvm_unreachable("Value type is non-standard value, Other.");
case iPTR:
llvm_unreachable("Value type size is target-dependent. Ask TLI.");
case iPTRAny:
@@ -352,8 +356,6 @@ namespace llvm {
llvm_unreachable("Value type is overloaded.");
case Metadata:
llvm_unreachable("Value type is metadata.");
- default:
- llvm_unreachable("getSizeInBits called on extended MVT.");
case i1 : return 1;
case v2i1: return 2;
case v4i1: return 4;
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index d27fcde..4b0aa4b 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -33,27 +33,6 @@
/* Define to 1 if you have the `arc4random' function. */
#cmakedefine HAVE_ARC4RANDOM
-/* Define to 1 if you have the `argz_append' function. */
-#cmakedefine HAVE_ARGZ_APPEND ${HAVE_ARGZ_APPEND}
-
-/* Define to 1 if you have the `argz_create_sep' function. */
-#cmakedefine HAVE_ARGZ_CREATE_SEP ${HAVE_ARGZ_CREATE_SEP}
-
-/* Define to 1 if you have the <argz.h> header file. */
-#cmakedefine HAVE_ARGZ_H ${HAVE_ARGZ_H}
-
-/* Define to 1 if you have the `argz_insert' function. */
-#cmakedefine HAVE_ARGZ_INSERT ${HAVE_ARGZ_INSERT}
-
-/* Define to 1 if you have the `argz_next' function. */
-#cmakedefine HAVE_ARGZ_NEXT ${HAVE_ARGZ_NEXT}
-
-/* Define to 1 if you have the `argz_stringify' function. */
-#cmakedefine HAVE_ARGZ_STRINGIFY ${HAVE_ARGZ_STRINGIFY}
-
-/* Define to 1 if you have the <assert.h> header file. */
-#cmakedefine HAVE_ASSERT_H ${HAVE_ASSERT_H}
-
/* Define to 1 if you have the `backtrace' function. */
#cmakedefine HAVE_BACKTRACE ${HAVE_BACKTRACE}
@@ -69,6 +48,12 @@
/* Define to 1 if you have the `closedir' function. */
#cmakedefine HAVE_CLOSEDIR ${HAVE_CLOSEDIR}
+/* Define if curses provides the has_color() function on this platform. */
+#cmakedefine HAVE_CURSES
+
+/* Define to 1 if you have the <curses.h> header file. */
+#cmakedefine HAVE_CURSES_H
+
/* Define to 1 if you have the <cxxabi.h> header file. */
#cmakedefine HAVE_CXXABI_H ${HAVE_CXXABI_H}
@@ -78,9 +63,6 @@
/* can use __crashreporter_info__ */
#undef HAVE_CRASHREPORTER_INFO
-/* Define to 1 if you have the <ctype.h> header file. */
-#cmakedefine HAVE_CTYPE_H ${HAVE_CTYPE_H}
-
/* Define to 1 if you have the declaration of `strerror_s', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_STRERROR_S
@@ -92,9 +74,6 @@
/* Define if you have the GNU dld library. */
#undef HAVE_DLD
-/* Define to 1 if you have the <dld.h> header file. */
-#cmakedefine HAVE_DLD_H ${HAVE_DLD_H}
-
/* Define to 1 if you have the `dlerror' function. */
#cmakedefine HAVE_DLERROR ${HAVE_DLERROR}
@@ -104,9 +83,6 @@
/* Define if dlopen() is available on this platform. */
#cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN}
-/* Define to 1 if you have the <dl.h> header file. */
-#cmakedefine HAVE_DL_H ${HAVE_DL_H}
-
/* Define if the dot program is available */
#cmakedefine HAVE_DOT ${HAVE_DOT}
@@ -119,9 +95,6 @@
/* Define to 1 if you have the <errno.h> header file. */
#cmakedefine HAVE_ERRNO_H ${HAVE_ERRNO_H}
-/* Define to 1 if the system has the type `error_t'. */
-#cmakedefine HAVE_ERROR_T ${HAVE_ERROR_T}
-
/* Define to 1 if you have the <execinfo.h> header file. */
#cmakedefine HAVE_EXECINFO_H ${HAVE_EXECINFO_H}
@@ -170,6 +143,12 @@
/* Define to 1 if you have the `fmodf' function. */
#cmakedefine HAVE_FMODF ${HAVE_FMODF}
+/* Define to 1 if you have the `futimes' function. */
+#cmakedefine HAVE_FUTIMES ${HAVE_FUTIMES}
+
+/* Define to 1 if you have the `futimens' function */
+#cmakedefine HAVE_FUTIMENS ${HAVE_FUTIMENS}
+
/* Define to 1 if you have the `getcwd' function. */
#cmakedefine HAVE_GETCWD ${HAVE_GETCWD}
@@ -191,9 +170,6 @@
/* Define if the gv program is available */
#cmakedefine HAVE_GV ${HAVE_GV}
-/* Define to 1 if you have the `index' function. */
-#cmakedefine HAVE_INDEX ${HAVE_INDEX}
-
/* Define to 1 if the system has the type `int64_t'. */
#cmakedefine HAVE_INT64_T ${HAVE_INT64_T}
@@ -239,12 +215,9 @@
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H ${HAVE_LIMITS_H}
-/* Define if you can use -Wl,-export-dynamic. */
+/* Define if you can use -rdynamic. */
#define HAVE_LINK_EXPORT_DYNAMIC 1
-/* Define to 1 if you have the <link.h> header file. */
-#cmakedefine HAVE_LINK_H ${HAVE_LINK_H}
-
/* Define if you can use -Wl,-R. to pass -R. to the linker, in order to add
the current directory to the dynamic linker search path. */
#undef HAVE_LINK_R
@@ -270,15 +243,6 @@
/* Define to 1 if you have the `malloc_zone_statistics' function. */
#cmakedefine HAVE_MALLOC_ZONE_STATISTICS ${HAVE_MALLOC_ZONE_STATISTICS}
-/* Define to 1 if you have the `memcpy' function. */
-#cmakedefine HAVE_MEMCPY ${HAVE_MEMCPY}
-
-/* Define to 1 if you have the `memmove' function. */
-#cmakedefine HAVE_MEMMOVE ${HAVE_MEMMOVE}
-
-/* Define to 1 if you have the <memory.h> header file. */
-#cmakedefine HAVE_MEMORY_H ${HAVE_MEMORY_H}
-
/* Define to 1 if you have the `mkdtemp' function. */
#cmakedefine HAVE_MKDTEMP ${HAVE_MKDTEMP}
@@ -298,6 +262,18 @@
/* Define if mmap() can map files into memory */
#undef HAVE_MMAP_FILE
+/* Define to 1 if you have the <ncursesw/curses.h> header file. */
+#cmakedefine HAVE_NCURSESW_CURSES_H
+
+/* Define to 1 if you have the <ncursesw.h> header file. */
+#cmakedefine HAVE_NCURSESW_H
+
+/* Define to 1 if you have the <ncurses/curses.h> header file. */
+#cmakedefine HAVE_NCURSES_CURSES_H
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#cmakedefine HAVE_NCURSES_H
+
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#cmakedefine HAVE_NDIR_H ${HAVE_NDIR_H}
@@ -346,9 +322,6 @@
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
-/* Define to 1 if you have the `rindex' function. */
-#cmakedefine HAVE_RINDEX ${HAVE_RINDEX}
-
/* Define to 1 if you have the `rintf' function. */
#undef HAVE_RINTF
@@ -367,9 +340,6 @@
/* Define to 1 if you have the `setjmp' function. */
#cmakedefine HAVE_SETJMP ${HAVE_SETJMP}
-/* Define to 1 if you have the <setjmp.h> header file. */
-#cmakedefine HAVE_SETJMP_H ${HAVE_SETJMP_H}
-
/* Define to 1 if you have the `setrlimit' function. */
#cmakedefine HAVE_SETRLIMIT ${HAVE_SETRLIMIT}
@@ -388,24 +358,12 @@
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
-/* Define to 1 if you have the <stdio.h> header file. */
-#cmakedefine HAVE_STDIO_H ${HAVE_STDIO_H}
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#cmakedefine HAVE_STDLIB_H ${HAVE_STDLIB_H}
-
/* Set to 1 if the std::isinf function is found in <cmath> */
#undef HAVE_STD_ISINF_IN_CMATH
/* Set to 1 if the std::isnan function is found in <cmath> */
#undef HAVE_STD_ISNAN_IN_CMATH
-/* Define to 1 if you have the `strchr' function. */
-#cmakedefine HAVE_STRCHR ${HAVE_STRCHR}
-
-/* Define to 1 if you have the `strcmp' function. */
-#cmakedefine HAVE_STRCMP ${HAVE_STRCMP}
-
/* Define to 1 if you have the `strdup' function. */
#cmakedefine HAVE_STRDUP ${HAVE_STRDUP}
@@ -415,15 +373,6 @@
/* Define to 1 if you have the `strerror_r' function. */
#cmakedefine HAVE_STRERROR_R ${HAVE_STRERROR_R}
-/* Define to 1 if you have the <strings.h> header file. */
-#cmakedefine HAVE_STRINGS_H ${HAVE_STRINGS_H}
-
-/* Define to 1 if you have the <string.h> header file. */
-#cmakedefine HAVE_STRING_H ${HAVE_STRING_H}
-
-/* Define to 1 if you have the `strrchr' function. */
-#cmakedefine HAVE_STRRCHR ${HAVE_STRRCHR}
-
/* Define to 1 if you have the `strtof' function. */
#cmakedefine HAVE_STRTOF ${HAVE_STRTOF}
@@ -440,9 +389,6 @@
*/
#cmakedefine HAVE_SYS_DIR_H ${HAVE_SYS_DIR_H}
-/* Define to 1 if you have the <sys/dl.h> header file. */
-#cmakedefine HAVE_SYS_DL_H ${HAVE_SYS_DL_H}
-
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#cmakedefine HAVE_SYS_IOCTL_H ${HAVE_SYS_IOCTL_H}
@@ -495,14 +441,11 @@
/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
#cmakedefine HAVE_VALGRIND_VALGRIND_H ${HAVE_VALGRIND_VALGRIND_H}
-/* Define to 1 if you have the <windows.h> header file. */
-#cmakedefine HAVE_WINDOWS_H ${HAVE_WINDOWS_H}
-
/* Define to 1 if you have the `writev' function. */
#cmakedefine HAVE_WRITEV ${HAVE_WRITEV}
/* Define if the xdot.py program is available */
-#cmakedefine HAVE_XDOT_PY ${HAVE_XDOT_PY}
+#cmakedefine HAVE_XDOT ${HAVE_XDOT}
/* Define to 1 if you have the <zlib.h> header file. */
#cmakedefine HAVE_ZLIB_H ${HAVE_ZLIB_H}
@@ -651,8 +594,8 @@
/* Define to path to twopi program if found or 'echo twopi' otherwise */
#cmakedefine LLVM_PATH_TWOPI "${LLVM_PATH_TWOPI}"
-/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */
-#cmakedefine LLVM_PATH_XDOT_PY "${LLVM_PATH_XDOT_PY}"
+/* Define to path to xdot.py program if found or 'echo xdot' otherwise */
+#cmakedefine LLVM_PATH_XDOT "${LLVM_PATH_XDOT}"
/* Installation prefix directory */
#cmakedefine LLVM_PREFIX "${LLVM_PREFIX}"
@@ -728,9 +671,6 @@
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
-/* Define to a type to use for `error_t' if it is not otherwise available. */
-#cmakedefine error_t ${error_t}
-
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index c3860b6..7bb1caa 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -51,15 +51,9 @@
/* Define to 1 if you have the `argz_stringify' function. */
#undef HAVE_ARGZ_STRINGIFY
-/* Define to 1 if you have the <assert.h> header file. */
-#undef HAVE_ASSERT_H
-
/* Define to 1 if you have the `backtrace' function. */
#undef HAVE_BACKTRACE
-/* Define to 1 if you have the `bcopy' function. */
-#undef HAVE_BCOPY
-
/* Define to 1 if you have the `ceilf' function. */
#undef HAVE_CEILF
@@ -75,8 +69,11 @@
/* can use __crashreporter_info__ */
#undef HAVE_CRASHREPORTER_INFO
-/* Define to 1 if you have the <ctype.h> header file. */
-#undef HAVE_CTYPE_H
+/* Define if curses provides the has_color() function on this platform. */
+#undef HAVE_CURSES
+
+/* Define to 1 if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
/* Define to 1 if you have the <cxxabi.h> header file. */
#undef HAVE_CXXABI_H
@@ -100,9 +97,6 @@
/* Define if you have the GNU dld library. */
#undef HAVE_DLD
-/* Define to 1 if you have the <dld.h> header file. */
-#undef HAVE_DLD_H
-
/* Define to 1 if you have the `dlerror' function. */
#undef HAVE_DLERROR
@@ -112,9 +106,6 @@
/* Define if dlopen() is available on this platform. */
#undef HAVE_DLOPEN
-/* Define to 1 if you have the <dl.h> header file. */
-#undef HAVE_DL_H
-
/* Define if the dot program is available */
#undef HAVE_DOT
@@ -166,6 +157,12 @@
/* Define to 1 if you have the `fmodf' function. */
#undef HAVE_FMODF
+/* Define to 1 if you have the `futimens' function. */
+#undef HAVE_FUTIMENS
+
+/* Define to 1 if you have the `futimes' function. */
+#undef HAVE_FUTIMES
+
/* Define to 1 if you have the `getcwd' function. */
#undef HAVE_GETCWD
@@ -187,9 +184,6 @@
/* Define if the gv program is available */
#undef HAVE_GV
-/* Define to 1 if you have the `index' function. */
-#undef HAVE_INDEX
-
/* Define to 1 if the system has the type `int64_t'. */
#undef HAVE_INT64_T
@@ -232,10 +226,7 @@
/* Define to 1 if you have the `z' library (-lz). */
#undef HAVE_LIBZ
-/* Define to 1 if you have the <limits.h> header file. */
-#undef HAVE_LIMITS_H
-
-/* Define if you can use -Wl,-export-dynamic. */
+/* Define if you can use -rdynamic. */
#undef HAVE_LINK_EXPORT_DYNAMIC
/* Define to 1 if you have the <link.h> header file. */
@@ -275,12 +266,6 @@
/* Define to 1 if you have the `malloc_zone_statistics' function. */
#undef HAVE_MALLOC_ZONE_STATISTICS
-/* Define to 1 if you have the `memcpy' function. */
-#undef HAVE_MEMCPY
-
-/* Define to 1 if you have the `memmove' function. */
-#undef HAVE_MEMMOVE
-
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@@ -303,6 +288,18 @@
/* Define if mmap() can map files into memory */
#undef HAVE_MMAP_FILE
+/* Define to 1 if you have the <ncursesw/curses.h> header file. */
+#undef HAVE_NCURSESW_CURSES_H
+
+/* Define to 1 if you have the <ncursesw.h> header file. */
+#undef HAVE_NCURSESW_H
+
+/* Define to 1 if you have the <ncurses/curses.h> header file. */
+#undef HAVE_NCURSES_CURSES_H
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
@@ -351,9 +348,6 @@
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
-/* Define to 1 if you have the `rindex' function. */
-#undef HAVE_RINDEX
-
/* Define to 1 if you have the `rintf' function. */
#undef HAVE_RINTF
@@ -393,9 +387,6 @@
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
-/* Define to 1 if you have the <stdio.h> header file. */
-#undef HAVE_STDIO_H
-
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
@@ -405,15 +396,6 @@
/* Set to 1 if the std::isnan function is found in <cmath> */
#undef HAVE_STD_ISNAN_IN_CMATH
-/* Define to 1 if you have the `strchr' function. */
-#undef HAVE_STRCHR
-
-/* Define to 1 if you have the `strcmp' function. */
-#undef HAVE_STRCMP
-
-/* Define to 1 if you have the `strdup' function. */
-#undef HAVE_STRDUP
-
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
@@ -426,9 +408,6 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
-/* Define to 1 if you have the `strrchr' function. */
-#undef HAVE_STRRCHR
-
/* Define to 1 if you have the `strtof' function. */
#undef HAVE_STRTOF
@@ -445,9 +424,6 @@
*/
#undef HAVE_SYS_DIR_H
-/* Define to 1 if you have the <sys/dl.h> header file. */
-#undef HAVE_SYS_DL_H
-
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
@@ -500,14 +476,11 @@
/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
#undef HAVE_VALGRIND_VALGRIND_H
-/* Define to 1 if you have the <windows.h> header file. */
-#undef HAVE_WINDOWS_H
-
/* Define to 1 if you have the `writev' function. */
#undef HAVE_WRITEV
-/* Define if the xdot.py program is available */
-#undef HAVE_XDOT_PY
+/* Define if the xdot program is available */
+#undef HAVE_XDOT
/* Define to 1 if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
@@ -656,8 +629,8 @@
/* Define to path to twopi program if found or 'echo twopi' otherwise */
#undef LLVM_PATH_TWOPI
-/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */
-#undef LLVM_PATH_XDOT_PY
+/* Define to path to xdot program if found or 'echo xdot' otherwise */
+#undef LLVM_PATH_XDOT
/* Installation prefix directory */
#undef LLVM_PREFIX
diff --git a/include/llvm/DIBuilder.h b/include/llvm/DIBuilder.h
index 2440064..a15d619 100644
--- a/include/llvm/DIBuilder.h
+++ b/include/llvm/DIBuilder.h
@@ -29,6 +29,7 @@ namespace llvm {
class MDNode;
class StringRef;
class DIBasicType;
+ class DICompileUnit;
class DICompositeType;
class DIDerivedType;
class DIDescriptor;
@@ -53,7 +54,6 @@ namespace llvm {
private:
Module &M;
LLVMContext & VMContext;
- MDNode *TheCU;
MDNode *TempEnumTypes;
MDNode *TempRetainTypes;
@@ -70,12 +70,17 @@ namespace llvm {
SmallVector<Value *, 4> AllGVs;
SmallVector<Value *, 4> AllImportedModules;
+ DITemplateValueParameter
+ createTemplateValueParameter(unsigned Tag, DIDescriptor Scope,
+ StringRef Name, DIType Ty, Value *Val,
+ MDNode *File = 0, unsigned LineNo = 0,
+ unsigned ColumnNo = 0);
+
DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION;
void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION;
public:
explicit DIBuilder(Module &M);
- const MDNode *getCU() { return TheCU; }
enum ComplexAddrKind { OpPlus=1, OpDeref };
/// finalize - Construct any deferred debug info descriptors.
@@ -97,20 +102,24 @@ namespace llvm {
/// Objective-C.
/// @param SplitName The name of the file that we'll split debug info out
/// into.
- void createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
- StringRef Producer, bool isOptimized,
- StringRef Flags, unsigned RV,
- StringRef SplitName = StringRef());
+ DICompileUnit createCompileUnit(unsigned Lang, StringRef File,
+ StringRef Dir, StringRef Producer,
+ bool isOptimized, StringRef Flags,
+ unsigned RV,
+ StringRef SplitName = StringRef());
/// createFile - Create a file descriptor to hold debugging information
/// for a file.
DIFile createFile(StringRef Filename, StringRef Directory);
/// createEnumerator - Create a single enumerator value.
- DIEnumerator createEnumerator(StringRef Name, uint64_t Val);
+ DIEnumerator createEnumerator(StringRef Name, int64_t Val);
+
+ /// \brief Create a DWARF unspecified type.
+ DIBasicType createUnspecifiedType(StringRef Name);
- /// createNullPtrType - Create C++0x nullptr type.
- DIBasicType createNullPtrType(StringRef Name);
+ /// \brief Create C++11 nullptr type.
+ DIBasicType createNullPtrType();
/// createBasicType - Create debugging information entry for a basic
/// type.
@@ -337,6 +346,32 @@ namespace llvm {
DIType Ty, Value *Val, MDNode *File = 0,
unsigned LineNo = 0, unsigned ColumnNo = 0);
+ /// \brief Create debugging information for a template template parameter.
+ /// @param Scope Scope in which this type is defined.
+ /// @param Name Value parameter name.
+ /// @param Ty Parameter type.
+ /// @param Val The fully qualified name of the template.
+ /// @param File File where this type parameter is defined.
+ /// @param LineNo Line number.
+ /// @param ColumnNo Column Number.
+ DITemplateValueParameter
+ createTemplateTemplateParameter(DIDescriptor Scope, StringRef Name,
+ DIType Ty, StringRef Val, MDNode *File = 0,
+ unsigned LineNo = 0, unsigned ColumnNo = 0);
+
+ /// \brief Create debugging information for a template parameter pack.
+ /// @param Scope Scope in which this type is defined.
+ /// @param Name Value parameter name.
+ /// @param Ty Parameter type.
+ /// @param Val An array of types in the pack.
+ /// @param File File where this type parameter is defined.
+ /// @param LineNo Line number.
+ /// @param ColumnNo Column Number.
+ DITemplateValueParameter
+ createTemplateParameterPack(DIDescriptor Scope, StringRef Name,
+ DIType Ty, DIArray Val, MDNode *File = 0,
+ unsigned LineNo = 0, unsigned ColumnNo = 0);
+
/// createArrayType - Create debugging information entry for an array.
/// @param Size Array size.
/// @param AlignInBits Alignment.
diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h
index 61d0681..f7e6434 100644
--- a/include/llvm/DebugInfo.h
+++ b/include/llvm/DebugInfo.h
@@ -31,6 +31,7 @@ namespace llvm {
class Type;
class Value;
class DbgDeclareInst;
+ class DbgValueInst;
class Instruction;
class MDNode;
class NamedMDNode;
@@ -63,7 +64,8 @@ namespace llvm {
FlagObjcClassComplete = 1 << 9,
FlagObjectPointer = 1 << 10,
FlagVector = 1 << 11,
- FlagStaticMember = 1 << 12
+ FlagStaticMember = 1 << 12,
+ FlagIndirectVariable = 1 << 13
};
protected:
const MDNode *DbgNode;
@@ -87,20 +89,27 @@ namespace llvm {
void replaceFunctionField(unsigned Elt, Function *F);
public:
- explicit DIDescriptor() : DbgNode(0) {}
- explicit DIDescriptor(const MDNode *N) : DbgNode(N) {}
- explicit DIDescriptor(const DIFile F);
- explicit DIDescriptor(const DISubprogram F);
- explicit DIDescriptor(const DILexicalBlockFile F);
- explicit DIDescriptor(const DILexicalBlock F);
- explicit DIDescriptor(const DIVariable F);
- explicit DIDescriptor(const DIType F);
+ explicit DIDescriptor(const MDNode *N = 0) : DbgNode(N) {}
bool Verify() const;
operator MDNode *() const { return const_cast<MDNode*>(DbgNode); }
MDNode *operator ->() const { return const_cast<MDNode*>(DbgNode); }
+ // An explicit operator bool so that we can do testing of DI values
+ // easily.
+ // FIXME: This operator bool isn't actually protecting anything at the
+ // moment due to the conversion operator above making DIDescriptor nodes
+ // implicitly convertable to bool.
+ LLVM_EXPLICIT operator bool() const { return DbgNode != 0; }
+
+ bool operator==(DIDescriptor Other) const {
+ return DbgNode == Other.DbgNode;
+ }
+ bool operator!=(DIDescriptor Other) const {
+ return !operator==(Other);
+ }
+
unsigned getTag() const {
return getUnsignedField(0) & ~LLVMDebugVersionMask;
}
@@ -120,7 +129,6 @@ namespace llvm {
bool isSubrange() const;
bool isEnumerator() const;
bool isType() const;
- bool isGlobal() const;
bool isUnspecifiedParameter() const;
bool isTemplateTypeParameter() const;
bool isTemplateValueParameter() const;
@@ -149,8 +157,7 @@ namespace llvm {
/// DIArray - This descriptor holds an array of descriptors.
class DIArray : public DIDescriptor {
public:
- explicit DIArray(const MDNode *N = 0)
- : DIDescriptor(N) {}
+ explicit DIArray(const MDNode *N = 0) : DIDescriptor(N) {}
unsigned getNumElements() const;
DIDescriptor getElement(unsigned Idx) const {
@@ -158,59 +165,6 @@ namespace llvm {
}
};
- /// DIScope - A base class for various scopes.
- class DIScope : public DIDescriptor {
- protected:
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
- public:
- explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {}
-
- /// Set the filename by allocating a new string MDNode for
- /// it and attaching it to the underlying node.
- void setFilename(StringRef Name, LLVMContext &Context);
- StringRef getFilename() const;
- StringRef getDirectory() const;
- };
-
- /// DIFile - This is a wrapper for a file.
- class DIFile : public DIScope {
- friend class DIDescriptor;
- public:
- explicit DIFile(const MDNode *N = 0) : DIScope(N) {
- if (DbgNode && !isFile())
- DbgNode = 0;
- }
- MDNode *getFileNode() const;
- bool Verify() const;
- };
-
- /// DICompileUnit - A wrapper for a compile unit.
- class DICompileUnit : public DIScope {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
- public:
- explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
-
- unsigned getLanguage() const { return getUnsignedField(2); }
- StringRef getProducer() const { return getStringField(3); }
-
- bool isOptimized() const { return getUnsignedField(4) != 0; }
- StringRef getFlags() const { return getStringField(5); }
- unsigned getRunTimeVersion() const { return getUnsignedField(6); }
-
- DIArray getEnumTypes() const;
- DIArray getRetainedTypes() const;
- DIArray getSubprograms() const;
- DIArray getGlobalVariables() const;
- DIArray getImportedEntities() const;
-
- StringRef getSplitDebugFilename() const { return getStringField(12); }
-
- /// Verify - Verify that a compile unit is well formed.
- bool Verify() const;
- };
-
/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
/// FIXME: it seems strange that this doesn't have either a reference to the
/// type/precision or a file/line pair for location info.
@@ -221,10 +175,25 @@ namespace llvm {
explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {}
StringRef getName() const { return getStringField(1); }
- uint64_t getEnumValue() const { return getUInt64Field(2); }
+ int64_t getEnumValue() const { return getInt64Field(2); }
bool Verify() const;
};
+ /// DIScope - A base class for various scopes.
+ class DIScope : public DIDescriptor {
+ protected:
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
+ public:
+ explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {}
+
+ /// Gets the parent scope for this scope node or returns a
+ /// default constructed scope.
+ DIScope getContext() const;
+ StringRef getFilename() const;
+ StringRef getDirectory() const;
+ };
+
/// DIType - This is a wrapper for a type.
/// FIXME: Types should be factored much better so that CV qualifiers and
/// others do not require a huge and empty descriptor full of zeros.
@@ -232,14 +201,12 @@ namespace llvm {
protected:
friend class DIDescriptor;
void printInternal(raw_ostream &OS) const;
- // This ctor is used when the Tag has already been validated by a derived
- // ctor.
- DIType(const MDNode *N, bool, bool) : DIScope(N) {}
+
public:
+ DIType(const MDNode *N = 0) : DIScope(N) {}
+
/// Verify - Verify that a type descriptor is well formed.
bool Verify() const;
- explicit DIType(const MDNode *N);
- explicit DIType() {}
DIScope getContext() const { return getFieldAs<DIScope>(2); }
StringRef getName() const { return getStringField(3); }
@@ -314,12 +281,9 @@ namespace llvm {
class DIDerivedType : public DIType {
friend class DIDescriptor;
void printInternal(raw_ostream &OS) const;
- protected:
- explicit DIDerivedType(const MDNode *N, bool, bool)
- : DIType(N, true, true) {}
+
public:
- explicit DIDerivedType(const MDNode *N = 0)
- : DIType(N, true, true) {}
+ explicit DIDerivedType(const MDNode *N = 0) : DIType(N) {}
DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
@@ -355,11 +319,7 @@ namespace llvm {
friend class DIDescriptor;
void printInternal(raw_ostream &OS) const;
public:
- explicit DICompositeType(const MDNode *N = 0)
- : DIDerivedType(N, true, true) {
- if (N && !isCompositeType())
- DbgNode = 0;
- }
+ explicit DICompositeType(const MDNode *N = 0) : DIDerivedType(N) {}
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
void setTypeArray(DIArray Elements, DIArray TParams = DIArray());
@@ -374,42 +334,38 @@ namespace llvm {
bool Verify() const;
};
- /// DITemplateTypeParameter - This is a wrapper for template type parameter.
- class DITemplateTypeParameter : public DIDescriptor {
+ /// DIFile - This is a wrapper for a file.
+ class DIFile : public DIScope {
+ friend class DIDescriptor;
public:
- explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {}
-
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- StringRef getName() const { return getStringField(2); }
- DIType getType() const { return getFieldAs<DIType>(3); }
- StringRef getFilename() const {
- return getFieldAs<DIFile>(4).getFilename();
- }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(4).getDirectory();
- }
- unsigned getLineNumber() const { return getUnsignedField(5); }
- unsigned getColumnNumber() const { return getUnsignedField(6); }
+ explicit DIFile(const MDNode *N = 0) : DIScope(N) {}
+ MDNode *getFileNode() const;
bool Verify() const;
};
- /// DITemplateValueParameter - This is a wrapper for template value parameter.
- class DITemplateValueParameter : public DIDescriptor {
+ /// DICompileUnit - A wrapper for a compile unit.
+ class DICompileUnit : public DIScope {
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
- explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {}
+ explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- StringRef getName() const { return getStringField(2); }
- DIType getType() const { return getFieldAs<DIType>(3); }
- Value *getValue() const;
- StringRef getFilename() const {
- return getFieldAs<DIFile>(5).getFilename();
- }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(5).getDirectory();
- }
- unsigned getLineNumber() const { return getUnsignedField(6); }
- unsigned getColumnNumber() const { return getUnsignedField(7); }
+ unsigned getLanguage() const { return getUnsignedField(2); }
+ StringRef getProducer() const { return getStringField(3); }
+
+ bool isOptimized() const { return getUnsignedField(4) != 0; }
+ StringRef getFlags() const { return getStringField(5); }
+ unsigned getRunTimeVersion() const { return getUnsignedField(6); }
+
+ DIArray getEnumTypes() const;
+ DIArray getRetainedTypes() const;
+ DIArray getSubprograms() const;
+ DIArray getGlobalVariables() const;
+ DIArray getImportedEntities() const;
+
+ StringRef getSplitDebugFilename() const { return getStringField(12); }
+
+ /// Verify - Verify that a compile unit is well formed.
bool Verify() const;
};
@@ -489,6 +445,83 @@ namespace llvm {
unsigned getScopeLineNumber() const { return getUnsignedField(19); }
};
+ /// DILexicalBlock - This is a wrapper for a lexical block.
+ class DILexicalBlock : public DIScope {
+ public:
+ explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
+ DIScope getContext() const { return getFieldAs<DIScope>(2); }
+ unsigned getLineNumber() const { return getUnsignedField(3); }
+ unsigned getColumnNumber() const { return getUnsignedField(4); }
+ bool Verify() const;
+ };
+
+ /// DILexicalBlockFile - This is a wrapper for a lexical block with
+ /// a filename change.
+ class DILexicalBlockFile : public DIScope {
+ public:
+ explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
+ DIScope getContext() const {
+ if (getScope().isSubprogram())
+ return getScope();
+ return getScope().getContext();
+ }
+ unsigned getLineNumber() const { return getScope().getLineNumber(); }
+ unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
+ DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); }
+ bool Verify() const;
+ };
+
+ /// DINameSpace - A wrapper for a C++ style name space.
+ class DINameSpace : public DIScope {
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
+ public:
+ explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
+ DIScope getContext() const { return getFieldAs<DIScope>(2); }
+ StringRef getName() const { return getStringField(3); }
+ unsigned getLineNumber() const { return getUnsignedField(4); }
+ bool Verify() const;
+ };
+
+ /// DITemplateTypeParameter - This is a wrapper for template type parameter.
+ class DITemplateTypeParameter : public DIDescriptor {
+ public:
+ explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getName() const { return getStringField(2); }
+ DIType getType() const { return getFieldAs<DIType>(3); }
+ StringRef getFilename() const {
+ return getFieldAs<DIFile>(4).getFilename();
+ }
+ StringRef getDirectory() const {
+ return getFieldAs<DIFile>(4).getDirectory();
+ }
+ unsigned getLineNumber() const { return getUnsignedField(5); }
+ unsigned getColumnNumber() const { return getUnsignedField(6); }
+ bool Verify() const;
+ };
+
+ /// DITemplateValueParameter - This is a wrapper for template value parameter.
+ class DITemplateValueParameter : public DIDescriptor {
+ public:
+ explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getName() const { return getStringField(2); }
+ DIType getType() const { return getFieldAs<DIType>(3); }
+ Value *getValue() const;
+ StringRef getFilename() const {
+ return getFieldAs<DIFile>(5).getFilename();
+ }
+ StringRef getDirectory() const {
+ return getFieldAs<DIFile>(5).getDirectory();
+ }
+ unsigned getLineNumber() const { return getUnsignedField(6); }
+ unsigned getColumnNumber() const { return getUnsignedField(7); }
+ bool Verify() const;
+ };
+
/// DIGlobalVariable - This is a wrapper for a global variable.
class DIGlobalVariable : public DIDescriptor {
friend class DIDescriptor;
@@ -529,8 +562,7 @@ namespace llvm {
friend class DIDescriptor;
void printInternal(raw_ostream &OS) const;
public:
- explicit DIVariable(const MDNode *N = 0)
- : DIDescriptor(N) {}
+ explicit DIVariable(const MDNode *N = 0) : DIDescriptor(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
@@ -553,6 +585,11 @@ namespace llvm {
return (getUnsignedField(6) & FlagObjectPointer) != 0;
}
+ /// \brief Return true if this variable is represented as a pointer.
+ bool isIndirect() const {
+ return (getUnsignedField(6) & FlagIndirectVariable) != 0;
+ }
+
/// getInlinedAt - If this variable is inlined then return inline location.
MDNode *getInlinedAt() const;
@@ -583,40 +620,6 @@ namespace llvm {
void printExtendedName(raw_ostream &OS) const;
};
- /// DILexicalBlock - This is a wrapper for a lexical block.
- class DILexicalBlock : public DIScope {
- public:
- explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
- DIScope getContext() const { return getFieldAs<DIScope>(2); }
- unsigned getLineNumber() const { return getUnsignedField(3); }
- unsigned getColumnNumber() const { return getUnsignedField(4); }
- bool Verify() const;
- };
-
- /// DILexicalBlockFile - This is a wrapper for a lexical block with
- /// a filename change.
- class DILexicalBlockFile : public DIScope {
- public:
- explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
- DIScope getContext() const { if (getScope().isSubprogram()) return getScope(); return getScope().getContext(); }
- unsigned getLineNumber() const { return getScope().getLineNumber(); }
- unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
- DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); }
- bool Verify() const;
- };
-
- /// DINameSpace - A wrapper for a C++ style name space.
- class DINameSpace : public DIScope {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
- public:
- explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
- DIScope getContext() const { return getFieldAs<DIScope>(2); }
- StringRef getName() const { return getStringField(3); }
- unsigned getLineNumber() const { return getUnsignedField(4); }
- bool Verify() const;
- };
-
/// DILocation - This object holds location information. This object
/// is not associated with any DWARF tag.
class DILocation : public DIDescriptor {
@@ -714,12 +717,27 @@ namespace llvm {
/// cleanseInlinedVariable - Remove inlined scope from the variable.
DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
+ /// DebugInfoFinder tries to list all debug info MDNodes used in a module. To
+ /// list debug info MDNodes used by an instruction, DebugInfoFinder uses
+ /// processDeclare, processValue and processLocation to handle DbgDeclareInst,
+ /// DbgValueInst and DbgLoc attached to instructions. processModule will go
+ /// through all DICompileUnits in llvm.dbg.cu and list debug info MDNodes
+ /// used by the CUs.
class DebugInfoFinder {
public:
/// processModule - Process entire module and collect debug info
/// anchors.
void processModule(const Module &M);
+ /// processDeclare - Process DbgDeclareInst.
+ void processDeclare(const DbgDeclareInst *DDI);
+ /// Process DbgValueInst.
+ void processValue(const DbgValueInst *DVI);
+ /// processLocation - Process DILocation.
+ void processLocation(DILocation Loc);
+
+ /// Clear all lists.
+ void reset();
private:
/// processType - Process DIType.
void processType(DIType DT);
@@ -730,11 +748,7 @@ namespace llvm {
/// processSubprogram - Process DISubprogram.
void processSubprogram(DISubprogram SP);
- /// processDeclare - Process DbgDeclareInst.
- void processDeclare(const DbgDeclareInst *DDI);
-
- /// processLocation - Process DILocation.
- void processLocation(DILocation Loc);
+ void processScope(DIScope Scope);
/// addCompileUnit - Add compile unit into CUs.
bool addCompileUnit(DICompileUnit CU);
@@ -748,8 +762,10 @@ namespace llvm {
/// addType - Add type into Tys.
bool addType(DIType DT);
+ bool addScope(DIScope Scope);
+
public:
- typedef SmallVector<MDNode *, 8>::const_iterator iterator;
+ typedef SmallVectorImpl<MDNode *>::const_iterator iterator;
iterator compile_unit_begin() const { return CUs.begin(); }
iterator compile_unit_end() const { return CUs.end(); }
iterator subprogram_begin() const { return SPs.begin(); }
@@ -758,17 +774,21 @@ namespace llvm {
iterator global_variable_end() const { return GVs.end(); }
iterator type_begin() const { return TYs.begin(); }
iterator type_end() const { return TYs.end(); }
+ iterator scope_begin() const { return Scopes.begin(); }
+ iterator scope_end() const { return Scopes.end(); }
unsigned compile_unit_count() const { return CUs.size(); }
unsigned global_variable_count() const { return GVs.size(); }
unsigned subprogram_count() const { return SPs.size(); }
unsigned type_count() const { return TYs.size(); }
+ unsigned scope_count() const { return Scopes.size(); }
private:
SmallVector<MDNode *, 8> CUs; // Compile Units
SmallVector<MDNode *, 8> SPs; // Subprograms
SmallVector<MDNode *, 8> GVs; // Global Variables;
SmallVector<MDNode *, 8> TYs; // Types
+ SmallVector<MDNode *, 8> Scopes; // Scopes
SmallPtrSet<MDNode *, 64> NodesSeen;
};
} // end namespace llvm
diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h
index 8fcd9e0..4bb7c77 100644
--- a/include/llvm/DebugInfo/DIContext.h
+++ b/include/llvm/DebugInfo/DIContext.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/RelocVisitor.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -105,6 +106,7 @@ enum DIDumpType {
DIDT_Info,
DIDT_InfoDwo,
DIDT_Line,
+ DIDT_Loc,
DIDT_Ranges,
DIDT_Pubnames,
DIDT_Str,
@@ -121,6 +123,12 @@ typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
class DIContext {
public:
+ enum DIContextKind {
+ CK_DWARF
+ };
+ DIContextKind getKind() const { return Kind; }
+
+ DIContext(DIContextKind K) : Kind(K) {}
virtual ~DIContext();
/// getDWARFContext - get a context for binary DWARF data.
@@ -134,6 +142,8 @@ public:
uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+private:
+ const DIContextKind Kind;
};
}
diff --git a/include/llvm/ExecutionEngine/ObjectCache.h b/include/llvm/ExecutionEngine/ObjectCache.h
index 0bee861..aa200fb 100644
--- a/include/llvm/ExecutionEngine/ObjectCache.h
+++ b/include/llvm/ExecutionEngine/ObjectCache.h
@@ -30,23 +30,9 @@ public:
/// getObjectCopy - Returns a pointer to a newly allocated MemoryBuffer that
/// contains the object which corresponds with Module M, or 0 if an object is
- /// not available. The caller owns the MemoryBuffer returned by this function.
- MemoryBuffer* getObjectCopy(const Module* M) {
- const MemoryBuffer* Obj = getObject(M);
- if (Obj)
- return MemoryBuffer::getMemBufferCopy(Obj->getBuffer());
- else
- return 0;
- }
-
-protected:
- /// getObject - Returns a pointer to a MemoryBuffer that contains an object
- /// that corresponds with Module M, or 0 if an object is not available.
- /// The pointer returned by this function is not suitable for loading because
- /// the memory is read-only and owned by the ObjectCache. To retrieve an
- /// owning pointer to a MemoryBuffer (which is suitable for calling
- /// RuntimeDyld::loadObject() with) use getObjectCopy() instead.
- virtual const MemoryBuffer* getObject(const Module* M) = 0;
+ /// not available. The caller owns both the MemoryBuffer returned by this
+ /// and the memory it references.
+ virtual MemoryBuffer* getObject(const Module* M) = 0;
};
}
diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h
index 40d61ff..eb6ed46 100644
--- a/include/llvm/IR/Argument.h
+++ b/include/llvm/IR/Argument.h
@@ -82,6 +82,11 @@ public:
/// its containing function.
bool hasReturnedAttr() const;
+ /// \brief Return true if this argument has the readonly or readnone attribute
+ /// on it in its containing function.
+ bool onlyReadsMemory() const;
+
+
/// \brief Add a Attribute to an argument.
void addAttr(AttributeSet AS);
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index 0d14709..2183758 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -67,6 +67,8 @@ public:
///< stored as log2 of alignment with +1 bias
///< 0 means unaligned (different from align(1))
AlwaysInline, ///< inline=always
+ Builtin, ///< Callee is recognized as a builtin, despite
+ ///< nobuiltin attribute on its declaration.
ByVal, ///< Pass structure by value
Cold, ///< Marks function as being in a cold path.
InlineHint, ///< Source said inlining was desirable
@@ -248,6 +250,8 @@ public:
/// attribute sets are immutable, this returns a new set.
AttributeSet addAttribute(LLVMContext &C, unsigned Index,
StringRef Kind) const;
+ AttributeSet addAttribute(LLVMContext &C, unsigned Index,
+ StringRef Kind, StringRef Value) const;
/// \brief Add attributes to the attribute set at the given index. Since
/// attribute sets are immutable, this returns a new set.
diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h
index 6f3ab20..585fc5e 100644
--- a/include/llvm/IR/CallingConv.h
+++ b/include/llvm/IR/CallingConv.h
@@ -93,13 +93,6 @@ namespace CallingConv {
/// Passes all arguments in register or parameter space.
PTX_Device = 72,
- /// MBLAZE_INTR - Calling convention used for MBlaze interrupt routines.
- MBLAZE_INTR = 73,
-
- /// MBLAZE_INTR - Calling convention used for MBlaze interrupt support
- /// routines (i.e. GCC's save_volatiles attribute).
- MBLAZE_SVOL = 74,
-
/// SPIR_FUNC - Calling convention for SPIR non-kernel device functions.
/// No lowering or expansion of arguments.
/// Structures are passed as a pointer to a struct with the byval attribute.
@@ -119,8 +112,17 @@ namespace CallingConv {
SPIR_KERNEL = 76,
/// Intel_OCL_BI - Calling conventions for Intel OpenCL built-ins
- Intel_OCL_BI = 77
+ Intel_OCL_BI = 77,
+
+ /// \brief The C convention as specified in the x86-64 supplement to the
+ /// System V ABI, used on most non-Windows systems.
+ X86_64_SysV = 78,
+ /// \brief The C convention as implemented on Windows/x86-64. This
+ /// convention differs from the more common \c X86_64_SysV convention
+ /// in a number of ways, most notably in that XMM registers used to pass
+ /// arguments are shadowed by GPRs, and vice versa.
+ X86_64_Win64 = 79
};
} // End CallingConv namespace
diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h
index 2f29f54..99aed0d 100644
--- a/include/llvm/IR/Constants.h
+++ b/include/llvm/IR/Constants.h
@@ -112,7 +112,6 @@ public:
/// Return the constant as a 64-bit unsigned integer value after it
/// has been zero extended as appropriate for the type of this constant. Note
/// that this method can assert if the value does not fit in 64 bits.
- /// @deprecated
/// @brief Return the zero extended value.
inline uint64_t getZExtValue() const {
return Val.getZExtValue();
@@ -121,7 +120,6 @@ public:
/// Return the constant as a 64-bit integer value after it has been sign
/// extended as appropriate for the type of this constant. Note that
/// this method can assert if the value does not fit in 64 bits.
- /// @deprecated
/// @brief Return the sign extended value.
inline int64_t getSExtValue() const {
return Val.getSExtValue();
diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h
index b0def6b..269edeb 100644
--- a/include/llvm/IR/DataLayout.h
+++ b/include/llvm/IR/DataLayout.h
@@ -237,13 +237,14 @@ public:
/// Layout pointer alignment
/// FIXME: The defaults need to be removed once all of
/// the backends/clients are updated.
- unsigned getPointerABIAlignment(unsigned AS = 0) const {
+ unsigned getPointerABIAlignment(unsigned AS = 0) const {
DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
if (val == Pointers.end()) {
val = Pointers.find(0);
}
return val->second.ABIAlign;
}
+
/// Return target's alignment for stack-based pointers
/// FIXME: The defaults need to be removed once all of
/// the backends/clients are updated.
@@ -257,7 +258,7 @@ public:
/// Layout pointer size
/// FIXME: The defaults need to be removed once all of
/// the backends/clients are updated.
- unsigned getPointerSize(unsigned AS = 0) const {
+ unsigned getPointerSize(unsigned AS = 0) const {
DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
if (val == Pointers.end()) {
val = Pointers.find(0);
@@ -267,9 +268,21 @@ public:
/// Layout pointer size, in bits
/// FIXME: The defaults need to be removed once all of
/// the backends/clients are updated.
- unsigned getPointerSizeInBits(unsigned AS = 0) const {
+ unsigned getPointerSizeInBits(unsigned AS = 0) const {
return getPointerSize(AS) * 8;
}
+
+ /// Layout pointer size, in bits, based on the type. If this function is
+ /// called with a pointer type, then the type size of the pointer is returned.
+ /// If this function is called with a vector of pointers, then the type size
+ /// of the pointer is returned. This should only be called with a pointer or
+ /// vector of pointers.
+ unsigned getPointerTypeSizeInBits(Type *) const;
+
+ unsigned getPointerTypeSize(Type *Ty) const {
+ return getPointerTypeSizeInBits(Ty) / 8;
+ }
+
/// Size examples:
///
/// Type SizeInBits StoreSizeInBits AllocSizeInBits[*]
diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h
index f97929f..0e51c6f 100644
--- a/include/llvm/IR/Function.h
+++ b/include/llvm/IR/Function.h
@@ -166,30 +166,37 @@ public:
(static_cast<unsigned>(CC) << 1));
}
- /// getAttributes - Return the attribute list for this Function.
- ///
+ /// @brief Return the attribute list for this Function.
AttributeSet getAttributes() const { return AttributeSets; }
- /// setAttributes - Set the attribute list for this Function.
- ///
+ /// @brief Set the attribute list for this Function.
void setAttributes(AttributeSet attrs) { AttributeSets = attrs; }
- /// addFnAttr - Add function attributes to this function.
- ///
+ /// @brief Add function attributes to this function.
void addFnAttr(Attribute::AttrKind N) {
setAttributes(AttributeSets.addAttribute(getContext(),
AttributeSet::FunctionIndex, N));
}
- /// addFnAttr - Add function attributes to this function.
- ///
+ /// @brief Remove function attributes from this function.
+ void removeFnAttr(Attribute::AttrKind N) {
+ setAttributes(AttributeSets.removeAttribute(
+ getContext(), AttributeSet::FunctionIndex, N));
+ }
+
+ /// @brief Add function attributes to this function.
void addFnAttr(StringRef Kind) {
setAttributes(
AttributeSets.addAttribute(getContext(),
AttributeSet::FunctionIndex, Kind));
}
+ void addFnAttr(StringRef Kind, StringRef Value) {
+ setAttributes(
+ AttributeSets.addAttribute(getContext(),
+ AttributeSet::FunctionIndex, Kind, Value));
+ }
- /// \brief Return true if the function has the attribute.
+ /// @brief Return true if the function has the attribute.
bool hasFnAttribute(Attribute::AttrKind Kind) const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
}
@@ -197,6 +204,14 @@ public:
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
}
+ /// @brief Return the attribute for the given attribute kind.
+ Attribute getFnAttribute(Attribute::AttrKind Kind) const {
+ return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind);
+ }
+ Attribute getFnAttribute(StringRef Kind) const {
+ return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind);
+ }
+
/// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
/// to use during code generation.
bool hasGC() const;
@@ -303,6 +318,21 @@ public:
addAttribute(n, Attribute::NoCapture);
}
+ bool doesNotAccessMemory(unsigned n) const {
+ return AttributeSets.hasAttribute(n, Attribute::ReadNone);
+ }
+ void setDoesNotAccessMemory(unsigned n) {
+ addAttribute(n, Attribute::ReadNone);
+ }
+
+ bool onlyReadsMemory(unsigned n) const {
+ return doesNotAccessMemory(n) ||
+ AttributeSets.hasAttribute(n, Attribute::ReadOnly);
+ }
+ void setOnlyReadsMemory(unsigned n) {
+ addAttribute(n, Attribute::ReadOnly);
+ }
+
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a Function) from the Function Src to this one.
void copyAttributesFrom(const GlobalValue *Src);
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index f11d3b4..e396e71 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -49,10 +49,6 @@ protected:
class IRBuilderBase {
DebugLoc CurDbgLocation;
protected:
- /// Save the current debug location here while we are suppressing
- /// line table entries.
- llvm::DebugLoc SavedDbgLocation;
-
BasicBlock *BB;
BasicBlock::iterator InsertPt;
LLVMContext &Context;
@@ -71,6 +67,7 @@ public:
/// inserted into a block.
void ClearInsertionPoint() {
BB = 0;
+ InsertPt = 0;
}
BasicBlock *GetInsertBlock() const { return BB; }
@@ -89,6 +86,7 @@ public:
void SetInsertPoint(Instruction *I) {
BB = I->getParent();
InsertPt = I;
+ assert(I != BB->end() && "Can't read debug loc from end()");
SetCurrentDebugLocation(I->getDebugLoc());
}
@@ -117,23 +115,6 @@ public:
CurDbgLocation = L;
}
- /// \brief Temporarily suppress DebugLocations from being attached
- /// to emitted instructions, until the next call to
- /// SetCurrentDebugLocation() or EnableDebugLocations(). Use this
- /// if you want an instruction to be counted towards the prologue or
- /// if there is no useful source location.
- void DisableDebugLocations() {
- llvm::DebugLoc Empty;
- SavedDbgLocation = getCurrentDebugLocation();
- SetCurrentDebugLocation(Empty);
- }
-
- /// \brief Restore the previously saved DebugLocation.
- void EnableDebugLocations() {
- assert(CurDbgLocation.isUnknown());
- SetCurrentDebugLocation(SavedDbgLocation);
- }
-
/// \brief Get location information used by debugging information.
DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; }
@@ -290,7 +271,7 @@ public:
}
/// \brief Fetch the type representing a pointer to an integer value.
- IntegerType* getIntPtrTy(DataLayout *DL, unsigned AddrSpace = 0) {
+ IntegerType* getIntPtrTy(const DataLayout *DL, unsigned AddrSpace = 0) {
return DL->getIntPtrType(Context, AddrSpace);
}
diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h
index f50c28a..e12bb03 100644
--- a/include/llvm/IR/InstrTypes.h
+++ b/include/llvm/IR/InstrTypes.h
@@ -531,6 +531,12 @@ public:
Type *DestTy ///< The Type to which the value should be cast.
);
+ /// @brief Check whether a bitcast between these types is valid
+ static bool isBitCastable(
+ Type *SrcTy, ///< The Type from which the value should be cast.
+ Type *DestTy ///< The Type to which the value should be cast.
+ );
+
/// Returns the opcode necessary to cast Val into Ty using usual casting
/// rules.
/// @brief Infer the opcode for cast operand and type
@@ -698,7 +704,7 @@ public:
/// @brief Create a CmpInst
static CmpInst *Create(OtherOps Op, unsigned short predicate, Value *S1,
Value *S2, const Twine &Name, BasicBlock *InsertAtEnd);
-
+
/// @brief Get the opcode casted to the right type
OtherOps getOpcode() const {
return static_cast<OtherOps>(Instruction::getOpcode());
@@ -715,15 +721,15 @@ public:
static bool isFPPredicate(Predicate P) {
return P >= FIRST_FCMP_PREDICATE && P <= LAST_FCMP_PREDICATE;
}
-
+
static bool isIntPredicate(Predicate P) {
return P >= FIRST_ICMP_PREDICATE && P <= LAST_ICMP_PREDICATE;
}
-
+
bool isFPPredicate() const { return isFPPredicate(getPredicate()); }
bool isIntPredicate() const { return isIntPredicate(getPredicate()); }
-
-
+
+
/// For example, EQ -> NE, UGT -> ULE, SLT -> SGE,
/// OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
/// @returns the inverse predicate for the instruction's current predicate.
@@ -821,7 +827,7 @@ public:
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
-
+
/// @brief Create a result type for fcmp/icmp
static Type* makeCmpResultType(Type* opnd_type) {
if (VectorType* vt = dyn_cast<VectorType>(opnd_type)) {
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index 7e29699..e05c3a8 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -1278,7 +1278,11 @@ public:
void removeAttribute(unsigned i, Attribute attr);
/// \brief Determine whether this call has the given attribute.
- bool hasFnAttr(Attribute::AttrKind A) const;
+ bool hasFnAttr(Attribute::AttrKind A) const {
+ assert(A != Attribute::NoBuiltin &&
+ "Use CallInst::isNoBuiltin() to check for Attribute::NoBuiltin");
+ return hasFnAttrImpl(A);
+ }
/// \brief Determine whether the call or the callee has the given attributes.
bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;
@@ -1288,6 +1292,13 @@ public:
return AttributeList.getParamAlignment(i);
}
+ /// \brief Return true if the call should not be treated as a call to a
+ /// builtin.
+ bool isNoBuiltin() const {
+ return hasFnAttrImpl(Attribute::NoBuiltin) &&
+ !hasFnAttrImpl(Attribute::Builtin);
+ }
+
/// \brief Return true if the call should not be inlined.
bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
void setIsNoInline() {
@@ -1378,6 +1389,9 @@ public:
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
+
+ bool hasFnAttrImpl(Attribute::AttrKind A) const;
+
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
void setInstructionSubclassData(unsigned short D) {
@@ -2609,7 +2623,6 @@ public:
}
/// addCase - Add an entry to the switch instruction...
- /// @deprecated
/// Note:
/// This action invalidates case_end(). Old case_end() iterator will
/// point to the added case.
@@ -2695,7 +2708,6 @@ public:
}
/// Resolves case value for current case.
- /// @deprecated
ConstantIntTy *getCaseValue() {
assert(Index < SI->getNumCases() && "Index out the number of cases.");
IntegersSubsetRef CaseRanges = *SubsetIt;
@@ -2799,7 +2811,6 @@ public:
CaseIt(const ParentTy& Src) : ParentTy(Src) {}
/// Sets the new value for current case.
- /// @deprecated.
void setValue(ConstantInt *V) {
assert(Index < SI->getNumCases() && "Index out the number of cases.");
IntegersSubsetToBB Mapping;
@@ -3024,7 +3035,11 @@ public:
void removeAttribute(unsigned i, Attribute attr);
/// \brief Determine whether this call has the NoAlias attribute.
- bool hasFnAttr(Attribute::AttrKind A) const;
+ bool hasFnAttr(Attribute::AttrKind A) const {
+ assert(A != Attribute::NoBuiltin &&
+ "Use CallInst::isNoBuiltin() to check for Attribute::NoBuiltin");
+ return hasFnAttrImpl(A);
+ }
/// \brief Determine whether the call or the callee has the given attributes.
bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;
@@ -3034,6 +3049,15 @@ public:
return AttributeList.getParamAlignment(i);
}
+ /// \brief Return true if the call should not be treated as a call to a
+ /// builtin.
+ bool isNoBuiltin() const {
+ // We assert in hasFnAttr if one passes in Attribute::NoBuiltin, so we have
+ // to check it by hand.
+ return hasFnAttrImpl(Attribute::NoBuiltin) &&
+ !hasFnAttrImpl(Attribute::Builtin);
+ }
+
/// \brief Return true if the call should not be inlined.
bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
void setIsNoInline() {
@@ -3140,6 +3164,8 @@ private:
virtual unsigned getNumSuccessorsV() const;
virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+ bool hasFnAttrImpl(Attribute::AttrKind A) const;
+
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
void setInstructionSubclassData(unsigned short D) {
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index e252664..1a849c4 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -55,6 +55,18 @@ class NoCapture<int argNo> : IntrinsicProperty {
int ArgNo = argNo;
}
+// ReadOnly - The specified argument pointer is not written to through the
+// pointer by the intrinsic.
+class ReadOnly<int argNo> : IntrinsicProperty {
+ int ArgNo = argNo;
+}
+
+// ReadNone - The specified argument pointer is not dereferenced by the
+// intrinsic.
+class ReadNone<int argNo> : IntrinsicProperty {
+ int ArgNo = argNo;
+}
+
def IntrNoReturn : IntrinsicProperty;
//===----------------------------------------------------------------------===//
@@ -253,11 +265,13 @@ def int_stackprotector : Intrinsic<[], [llvm_ptr_ty, llvm_ptrptr_ty], []>;
def int_memcpy : Intrinsic<[],
[llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
llvm_i32_ty, llvm_i1_ty],
- [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>]>;
+ [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>,
+ ReadOnly<1>]>;
def int_memmove : Intrinsic<[],
[llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
llvm_i32_ty, llvm_i1_ty],
- [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>]>;
+ [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>,
+ ReadOnly<1>]>;
def int_memset : Intrinsic<[],
[llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,
llvm_i32_ty, llvm_i1_ty],
@@ -347,6 +361,9 @@ def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>;
def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>;
def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>;
+// __builtin_unwind_init is an undocumented GCC intrinsic that causes all
+// callee-saved registers to be saved and restored (regardless of whether they
+// are used) in the calling function. It is used by libgcc_eh.
def int_eh_unwind_init: Intrinsic<[]>,
GCCBuiltin<"__builtin_unwind_init">;
@@ -477,6 +494,7 @@ def int_convertuu : Intrinsic<[llvm_anyint_ty],
include "llvm/IR/IntrinsicsPowerPC.td"
include "llvm/IR/IntrinsicsX86.td"
include "llvm/IR/IntrinsicsARM.td"
+include "llvm/IR/IntrinsicsAArch64.td"
include "llvm/IR/IntrinsicsXCore.td"
include "llvm/IR/IntrinsicsHexagon.td"
include "llvm/IR/IntrinsicsNVVM.td"
diff --git a/include/llvm/IR/IntrinsicsAArch64.td b/include/llvm/IR/IntrinsicsAArch64.td
new file mode 100644
index 0000000..d7b1947
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsAArch64.td
@@ -0,0 +1,41 @@
+//===- IntrinsicsAArch64.td - Defines AArch64 intrinsics -----------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the AArch64-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Advanced SIMD (NEON)
+
+let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
+
+// Vector Absolute Compare (Floating Point)
+def int_aarch64_neon_vacgeq : Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+def int_aarch64_neon_vacgtq : Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+
+// Vector maxNum (Floating Point)
+def int_aarch64_neon_vmaxnm : Neon_2Arg_Intrinsic;
+
+// Vector minNum (Floating Point)
+def int_aarch64_neon_vminnm : Neon_2Arg_Intrinsic;
+
+// Vector Pairwise maxNum (Floating Point)
+def int_aarch64_neon_vpmaxnm : Neon_2Arg_Intrinsic;
+
+// Vector Pairwise minNum (Floating Point)
+def int_aarch64_neon_vpminnm : Neon_2Arg_Intrinsic;
+
+// Vector Multiply Extended (Floating Point)
+def int_aarch64_neon_vmulx : Neon_2Arg_Intrinsic;
+}
diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td
index 93b1ae1..3c5d5ff 100644
--- a/include/llvm/IR/IntrinsicsARM.td
+++ b/include/llvm/IR/IntrinsicsARM.td
@@ -34,12 +34,15 @@ def int_arm_usat : GCCBuiltin<"__builtin_arm_usat">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
//===----------------------------------------------------------------------===//
-// Load and Store exclusive doubleword
+// Load, Store and Clear exclusive
+
+def int_arm_ldrex : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty]>;
+def int_arm_strex : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_anyptr_ty]>;
+def int_arm_clrex : Intrinsic<[]>;
def int_arm_strexd : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
- llvm_ptr_ty], [IntrReadWriteArgMem]>;
-def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty],
- [IntrReadArgMem]>;
+ llvm_ptr_ty]>;
+def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty]>;
//===----------------------------------------------------------------------===//
// VFP
@@ -124,6 +127,8 @@ class Neon_CvtFxToFP_Intrinsic
: Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>;
class Neon_CvtFPToFx_Intrinsic
: Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]>;
+class Neon_CvtFPtoInt_1Arg_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// The table operands for VTBL and VTBX consist of 1 to 4 v8i8 vectors.
// Besides the table, VTBL has one other v8i8 argument and VTBX has two.
@@ -177,10 +182,12 @@ let Properties = [IntrNoMem, Commutative] in {
// Vector Maximum.
def int_arm_neon_vmaxs : Neon_2Arg_Intrinsic;
def int_arm_neon_vmaxu : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vmaxnm : Neon_2Arg_Intrinsic;
// Vector Minimum.
def int_arm_neon_vmins : Neon_2Arg_Intrinsic;
def int_arm_neon_vminu : Neon_2Arg_Intrinsic;
+ def int_arm_neon_vminnm : Neon_2Arg_Intrinsic;
// Vector Reciprocal Step.
def int_arm_neon_vrecps : Neon_2Arg_Intrinsic;
@@ -314,6 +321,16 @@ def int_arm_neon_vrecpe : Neon_1Arg_Intrinsic;
// Vector Reciprocal Square Root Estimate.
def int_arm_neon_vrsqrte : Neon_1Arg_Intrinsic;
+// Vector Conversions Between Floating-point and Integer
+def int_arm_neon_vcvtau : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtas : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtnu : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtns : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtpu : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtps : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtmu : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtms : Neon_CvtFPtoInt_1Arg_Intrinsic;
+
// Vector Conversions Between Floating-point and Fixed-point.
def int_arm_neon_vcvtfp2fxs : Neon_CvtFPToFx_Intrinsic;
def int_arm_neon_vcvtfp2fxu : Neon_CvtFPToFx_Intrinsic;
@@ -347,6 +364,14 @@ def int_arm_neon_vtbx2 : Neon_Tbl4Arg_Intrinsic;
def int_arm_neon_vtbx3 : Neon_Tbl5Arg_Intrinsic;
def int_arm_neon_vtbx4 : Neon_Tbl6Arg_Intrinsic;
+// Vector Rounding
+def int_arm_neon_vrintn : Neon_1Arg_Intrinsic;
+def int_arm_neon_vrintx : Neon_1Arg_Intrinsic;
+def int_arm_neon_vrinta : Neon_1Arg_Intrinsic;
+def int_arm_neon_vrintz : Neon_1Arg_Intrinsic;
+def int_arm_neon_vrintm : Neon_1Arg_Intrinsic;
+def int_arm_neon_vrintp : Neon_1Arg_Intrinsic;
+
// De-interleaving vector loads from N-element structures.
// Source operands are the address and alignment.
def int_arm_neon_vld1 : Intrinsic<[llvm_anyvector_ty],
diff --git a/include/llvm/IR/IntrinsicsNVVM.td b/include/llvm/IR/IntrinsicsNVVM.td
index c248517..a372c22 100644
--- a/include/llvm/IR/IntrinsicsNVVM.td
+++ b/include/llvm/IR/IntrinsicsNVVM.td
@@ -861,8 +861,6 @@ def int_nvvm_ptr_gen_to_param: Intrinsic<[llvm_anyptr_ty],
// Move intrinsics, used in nvvm internally
-def int_nvvm_move_i8 : Intrinsic<[llvm_i8_ty], [llvm_i8_ty], [IntrNoMem],
- "llvm.nvvm.move.i8">;
def int_nvvm_move_i16 : Intrinsic<[llvm_i16_ty], [llvm_i16_ty], [IntrNoMem],
"llvm.nvvm.move.i16">;
def int_nvvm_move_i32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem],
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 69e0ab4..c7675c2 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -2578,3 +2578,42 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_xtest : GCCBuiltin<"__builtin_ia32_xtest">,
Intrinsic<[llvm_i32_ty], [], []>;
}
+// AVX-512
+
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ // Mask instructions
+ // 16-bit mask
+ def int_x86_kadd_v16i1 : GCCBuiltin<"__builtin_ia32_kaddw">,
+ Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ [IntrNoMem]>;
+ def int_x86_kand_v16i1 : GCCBuiltin<"__builtin_ia32_kandw">,
+ Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ [IntrNoMem]>;
+ def int_x86_kandn_v16i1 : GCCBuiltin<"__builtin_ia32_kandnw">,
+ Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ [IntrNoMem]>;
+ def int_x86_knot_v16i1 : GCCBuiltin<"__builtin_ia32_knotw">,
+ Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty], [IntrNoMem]>;
+ def int_x86_kor_v16i1 : GCCBuiltin<"__builtin_ia32_korw">,
+ Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ [IntrNoMem]>;
+ def int_x86_kxor_v16i1 : GCCBuiltin<"__builtin_ia32_kxorw">,
+ Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ [IntrNoMem]>;
+ def int_x86_kxnor_v16i1 : GCCBuiltin<"__builtin_ia32_kxnorw">,
+ Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ [IntrNoMem]>;
+ def int_x86_mask2int_v16i1 : GCCBuiltin<"__builtin_ia32_mask2intw">,
+ Intrinsic<[llvm_i32_ty], [llvm_v16i1_ty], [IntrNoMem]>;
+ def int_x86_int2mask_v16i1 : GCCBuiltin<"__builtin_ia32_int2maskw">,
+ Intrinsic<[llvm_v16i1_ty], [llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_kunpck_v16i1 : GCCBuiltin<"__builtin_ia32_kunpckbw">,
+ Intrinsic<[llvm_v16i1_ty], [llvm_v8i1_ty, llvm_v8i1_ty],
+ [IntrNoMem]>;
+ def int_x86_avx512_kortestz : GCCBuiltin<"__builtin_ia32_kortestz">,
+ Intrinsic<[llvm_i32_ty], [llvm_i16_ty, llvm_i16_ty],
+ [IntrNoMem]>;
+ def int_x86_avx512_kortestc : GCCBuiltin<"__builtin_ia32_kortestc">,
+ Intrinsic<[llvm_i32_ty], [llvm_i16_ty, llvm_i16_ty],
+ [IntrNoMem]>;
+}
diff --git a/include/llvm/IR/IntrinsicsXCore.td b/include/llvm/IR/IntrinsicsXCore.td
index a481313..bf345d4 100644
--- a/include/llvm/IR/IntrinsicsXCore.td
+++ b/include/llvm/IR/IntrinsicsXCore.td
@@ -13,7 +13,8 @@
let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.".
// Miscellaneous instructions.
- def int_xcore_bitrev : Intrinsic<[llvm_i32_ty],[llvm_i32_ty],[IntrNoMem]>;
+ def int_xcore_bitrev : Intrinsic<[llvm_i32_ty],[llvm_i32_ty],[IntrNoMem]>,
+ GCCBuiltin<"__builtin_bitrev">;
def int_xcore_crc8 : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
[llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],
[IntrNoMem]>;
@@ -24,9 +25,12 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.".
[IntrNoMem]>;
def int_xcore_zext : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
- def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>;
- def int_xcore_getps : Intrinsic<[llvm_i32_ty],[llvm_i32_ty]>;
- def int_xcore_setps : Intrinsic<[],[llvm_i32_ty, llvm_i32_ty]>;
+ def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>,
+ GCCBuiltin<"__builtin_getid">;
+ def int_xcore_getps : Intrinsic<[llvm_i32_ty],[llvm_i32_ty]>,
+ GCCBuiltin<"__builtin_getps">;
+ def int_xcore_setps : Intrinsic<[],[llvm_i32_ty, llvm_i32_ty]>,
+ GCCBuiltin<"__builtin_setps">;
def int_xcore_geted : Intrinsic<[llvm_i32_ty],[]>;
def int_xcore_getet : Intrinsic<[llvm_i32_ty],[]>;
def int_xcore_setsr : Intrinsic<[],[llvm_i32_ty]>;
diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h
index 8c2cfac..acd84d7 100644
--- a/include/llvm/IR/Metadata.h
+++ b/include/llvm/IR/Metadata.h
@@ -22,11 +22,8 @@
#include "llvm/IR/Value.h"
namespace llvm {
-class Constant;
-class Instruction;
class LLVMContext;
class Module;
-template <typename T> class SmallVectorImpl;
template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
@@ -139,7 +136,7 @@ public:
void replaceOperandWith(unsigned i, Value *NewVal);
/// getOperand - Return specified operand.
- Value *getOperand(unsigned i) const;
+ Value *getOperand(unsigned i) const LLVM_READONLY;
/// getNumOperands - Return number of MDNode operands.
unsigned getNumOperands() const { return NumOperands; }
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index d414405..3dbc5ff 100644
--- a/include/llvm/IR/Module.h
+++ b/include/llvm/IR/Module.h
@@ -352,15 +352,22 @@ public:
/// symbol table. If it does not exist, return null. If AllowInternal is set
/// to true, this function will return types that have InternalLinkage. By
/// default, these types are not returned.
- GlobalVariable *getGlobalVariable(StringRef Name,
- bool AllowInternal = false) const;
+ const GlobalVariable *getGlobalVariable(StringRef Name,
+ bool AllowInternal = false) const {
+ return const_cast<Module *>(this)->getGlobalVariable(Name, AllowInternal);
+ }
+
+ GlobalVariable *getGlobalVariable(StringRef Name, bool AllowInternal = false);
/// getNamedGlobal - Return the global variable in the module with the
/// specified name, of arbitrary type. This method returns null if a global
/// with the specified name is not found.
- GlobalVariable *getNamedGlobal(StringRef Name) const {
+ GlobalVariable *getNamedGlobal(StringRef Name) {
return getGlobalVariable(Name, true);
}
+ const GlobalVariable *getNamedGlobal(StringRef Name) const {
+ return const_cast<Module *>(this)->getNamedGlobal(Name);
+ }
/// getOrInsertGlobal - Look up the specified global in the module symbol
/// table.
@@ -405,6 +412,10 @@ public:
/// getModuleFlagsMetadata - Returns the module flags in the provided vector.
void getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const;
+ /// Return the corresponding value if Key appears in module flags, otherwise
+ /// return null.
+ Value *getModuleFlag(StringRef Key) const;
+
/// getModuleFlagsMetadata - Returns the NamedMDNode in the module that
/// represents module-level flags. This method returns null if there are no
/// module-level flags.
diff --git a/include/llvm/IR/TypeBuilder.h b/include/llvm/IR/TypeBuilder.h
index 80c60a0..5a29e1e 100644
--- a/include/llvm/IR/TypeBuilder.h
+++ b/include/llvm/IR/TypeBuilder.h
@@ -17,7 +17,7 @@
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
-#include <limits.h>
+#include <climits>
namespace llvm {
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 072c2e4..d7d18d0 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -87,6 +87,8 @@ void initializeCFGOnlyPrinterPass(PassRegistry&);
void initializeCFGOnlyViewerPass(PassRegistry&);
void initializeCFGPrinterPass(PassRegistry&);
void initializeCFGSimplifyPassPass(PassRegistry&);
+void initializeFlattenCFGPassPass(PassRegistry&);
+void initializeStructurizeCFGPass(PassRegistry&);
void initializeCFGViewerPass(PassRegistry&);
void initializeCalculateSpillWeightsPass(PassRegistry&);
void initializeCallGraphAnalysisGroup(PassRegistry&);
@@ -239,7 +241,6 @@ void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&);
void initializeScalarEvolutionPass(PassRegistry&);
void initializeSimpleInlinerPass(PassRegistry&);
void initializeRegisterCoalescerPass(PassRegistry&);
-void initializeSimplifyLibCallsPass(PassRegistry&);
void initializeSingleLoopExtractorPass(PassRegistry&);
void initializeSinkingPass(PassRegistry&);
void initializeSlotIndexesPass(PassRegistry&);
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index ca1c139..ec39829 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -62,6 +62,7 @@ namespace {
(void) llvm::createCallGraphPrinterPass();
(void) llvm::createCallGraphViewerPass();
(void) llvm::createCFGSimplificationPass();
+ (void) llvm::createStructurizeCFGPass();
(void) llvm::createConstantMergePass();
(void) llvm::createConstantPropagationPass();
(void) llvm::createCostModelAnalysisPass();
@@ -129,7 +130,6 @@ namespace {
(void) llvm::createRegionViewerPass();
(void) llvm::createSCCPPass();
(void) llvm::createScalarReplAggregatesPass();
- (void) llvm::createSimplifyLibCallsPass();
(void) llvm::createSingleLoopExtractorPass();
(void) llvm::createStripSymbolsPass();
(void) llvm::createStripNonDebugSymbolsPass();
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 781a9d0..e83b624 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -200,13 +200,6 @@ namespace llvm {
/// on Mips or .gprel32 on Alpha.
const char *GPRel32Directive; // Defaults to NULL.
- /// getDataASDirective - Return the directive that should be used to emit
- /// data of the specified size to the specified numeric address space.
- virtual const char *getDataASDirective(unsigned Size, unsigned AS) const {
- assert(AS != 0 && "Don't know the directives for default addr space");
- return 0;
- }
-
/// SunStyleELFSectionSwitchSyntax - This is true if this target uses "Sun
/// Style" syntax for section switching ("#alloc,#write" etc) instead of the
/// normal ELF syntax (,"a,w") in .section directives.
@@ -344,8 +337,8 @@ namespace llvm {
virtual ~MCAsmInfo();
// FIXME: move these methods to DwarfPrinter when the JIT stops using them.
- static unsigned getSLEB128Size(int Value);
- static unsigned getULEB128Size(unsigned Value);
+ static unsigned getSLEB128Size(int64_t Value);
+ static unsigned getULEB128Size(uint64_t Value);
/// getPointerSize - Get the pointer size in bytes.
unsigned getPointerSize() const {
@@ -372,17 +365,17 @@ namespace llvm {
// Data directive accessors.
//
- const char *getData8bitsDirective(unsigned AS = 0) const {
- return AS == 0 ? Data8bitsDirective : getDataASDirective(8, AS);
+ const char *getData8bitsDirective() const {
+ return Data8bitsDirective;
}
- const char *getData16bitsDirective(unsigned AS = 0) const {
- return AS == 0 ? Data16bitsDirective : getDataASDirective(16, AS);
+ const char *getData16bitsDirective() const {
+ return Data16bitsDirective;
}
- const char *getData32bitsDirective(unsigned AS = 0) const {
- return AS == 0 ? Data32bitsDirective : getDataASDirective(32, AS);
+ const char *getData32bitsDirective() const {
+ return Data32bitsDirective;
}
- const char *getData64bitsDirective(unsigned AS = 0) const {
- return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS);
+ const char *getData64bitsDirective() const {
+ return Data64bitsDirective;
}
const char *getGPRel64Directive() const { return GPRel64Directive; }
const char *getGPRel32Directive() const { return GPRel32Directive; }
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 0db3dee..c012ed0 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -11,6 +11,7 @@
#define LLVM_MC_MCCONTEXT_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/MC/MCDwarf.h"
@@ -37,6 +38,7 @@ namespace llvm {
class Twine;
class MCSectionMachO;
class MCSectionELF;
+ class MCSectionCOFF;
/// MCContext - Context object for machine code objects. This class owns all
/// of the sections that it creates.
@@ -51,10 +53,10 @@ namespace llvm {
const SourceMgr *SrcMgr;
/// The MCAsmInfo for this target.
- const MCAsmInfo &MAI;
+ const MCAsmInfo *MAI;
/// The MCRegisterInfo for this target.
- const MCRegisterInfo &MRI;
+ const MCRegisterInfo *MRI;
/// The MCObjectFileInfo for this target.
const MCObjectFileInfo *MOFI;
@@ -97,7 +99,7 @@ namespace llvm {
bool SecureLogUsed;
/// The compilation directory to use for DW_AT_comp_dir.
- std::string CompilationDir;
+ SmallString<128> CompilationDir;
/// The main file name if passed in explicitly.
std::string MainFileName;
@@ -163,16 +165,16 @@ namespace llvm {
MCSymbol *CreateSymbol(StringRef Name);
public:
- explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
+ explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0,
bool DoAutoReset = true);
~MCContext();
const SourceMgr *getSourceManager() const { return SrcMgr; }
- const MCAsmInfo &getAsmInfo() const { return MAI; }
+ const MCAsmInfo *getAsmInfo() const { return MAI; }
- const MCRegisterInfo &getRegisterInfo() const { return MRI; }
+ const MCRegisterInfo *getRegisterInfo() const { return MRI; }
const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; }
@@ -254,14 +256,12 @@ namespace llvm {
const MCSectionELF *CreateELFGroupSection();
- const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
- int Selection, SectionKind Kind);
-
- const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
- SectionKind Kind) {
- return getCOFFSection (Section, Characteristics, 0, Kind);
- }
+ const MCSectionCOFF *getCOFFSection(StringRef Section,
+ unsigned Characteristics,
+ SectionKind Kind, int Selection = 0,
+ const MCSectionCOFF *Assoc = 0);
+ const MCSectionCOFF *getCOFFSection(StringRef Section);
/// @}
@@ -272,7 +272,7 @@ namespace llvm {
/// This can be overridden by clients which want to control the reported
/// compilation directory and have it be something other than the current
/// working directory.
- const std::string &getCompilationDir() const { return CompilationDir; }
+ StringRef getCompilationDir() const { return CompilationDir; }
/// \brief Set the compilation directory for DW_AT_comp_dir
/// Override the default (CWD) compilation directory.
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
index 55c05b0..7565c15 100644
--- a/include/llvm/MC/MCELFStreamer.h
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -77,8 +77,7 @@ public:
uint64_t Size = 0, unsigned ByteAlignment = 0);
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment = 0);
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace);
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size);
virtual void EmitFileDirective(StringRef Filename);
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index d851f64..5d55974 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -171,24 +171,56 @@ public:
VK_ARM_TARGET2,
VK_ARM_PREL31,
- VK_PPC_TOC, // TOC base
- VK_PPC_TOC_ENTRY, // TOC entry
- VK_PPC_ADDR16_HA, // symbol@ha
- VK_PPC_ADDR16_LO, // symbol@l
- VK_PPC_TPREL16_HA, // symbol@tprel@ha
- VK_PPC_TPREL16_LO, // symbol@tprel@l
- VK_PPC_DTPREL16_HA, // symbol@dtprel@ha
- VK_PPC_DTPREL16_LO, // symbol@dtprel@l
- VK_PPC_TOC16_HA, // symbol@toc@ha
- VK_PPC_TOC16_LO, // symbol@toc@l
- VK_PPC_GOT_TPREL16_HA, // symbol@got@tprel@ha
- VK_PPC_GOT_TPREL16_LO, // symbol@got@tprel@l
+ VK_PPC_LO, // symbol@l
+ VK_PPC_HI, // symbol@h
+ VK_PPC_HA, // symbol@ha
+ VK_PPC_HIGHER, // symbol@higher
+ VK_PPC_HIGHERA, // symbol@highera
+ VK_PPC_HIGHEST, // symbol@highest
+ VK_PPC_HIGHESTA, // symbol@highesta
+ VK_PPC_GOT_LO, // symbol@got@l
+ VK_PPC_GOT_HI, // symbol@got@h
+ VK_PPC_GOT_HA, // symbol@got@ha
+ VK_PPC_TOCBASE, // symbol@tocbase
+ VK_PPC_TOC, // symbol@toc
+ VK_PPC_TOC_LO, // symbol@toc@l
+ VK_PPC_TOC_HI, // symbol@toc@h
+ VK_PPC_TOC_HA, // symbol@toc@ha
+ VK_PPC_DTPMOD, // symbol@dtpmod
+ VK_PPC_TPREL, // symbol@tprel
+ VK_PPC_TPREL_LO, // symbol@tprel@l
+ VK_PPC_TPREL_HI, // symbol@tprel@h
+ VK_PPC_TPREL_HA, // symbol@tprel@ha
+ VK_PPC_TPREL_HIGHER, // symbol@tprel@higher
+ VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera
+ VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest
+ VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta
+ VK_PPC_DTPREL, // symbol@dtprel
+ VK_PPC_DTPREL_LO, // symbol@dtprel@l
+ VK_PPC_DTPREL_HI, // symbol@dtprel@h
+ VK_PPC_DTPREL_HA, // symbol@dtprel@ha
+ VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher
+ VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera
+ VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest
+ VK_PPC_DTPREL_HIGHESTA,// symbol@dtprel@highesta
+ VK_PPC_GOT_TPREL, // symbol@got@tprel
+ VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l
+ VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h
+ VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha
+ VK_PPC_GOT_DTPREL, // symbol@got@dtprel
+ VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l
+ VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h
+ VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha
VK_PPC_TLS, // symbol@tls
- VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha
- VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l
+ VK_PPC_GOT_TLSGD, // symbol@got@tlsgd
+ VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l
+ VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h
+ VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha
VK_PPC_TLSGD, // symbol@tlsgd
- VK_PPC_GOT_TLSLD16_HA, // symbol@got@tlsld@ha
- VK_PPC_GOT_TLSLD16_LO, // symbol@got@tlsld@l
+ VK_PPC_GOT_TLSLD, // symbol@got@tlsld
+ VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l
+ VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h
+ VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha
VK_PPC_TLSLD, // symbol@tlsld
VK_Mips_GPREL,
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
index a18cbd9..cb7225f 100644
--- a/include/llvm/MC/MCInstPrinter.h
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -21,6 +21,13 @@ class MCInstrInfo;
class MCRegisterInfo;
class StringRef;
+namespace HexStyle {
+ enum Style {
+ C, ///< 0xff
+ Asm ///< 0ffh
+ };
+}
+
/// MCInstPrinter - This is an instance of a target assembly language printer
/// that converts an MCInst to valid target assembly syntax.
class MCInstPrinter {
@@ -42,13 +49,16 @@ protected:
/// True if we are printing immediates as hex.
bool PrintImmHex;
+ /// Which style to use for printing hexadecimal values.
+ HexStyle::Style PrintHexStyle;
+
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
public:
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
const MCRegisterInfo &mri)
: CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0),
- UseMarkup(0), PrintImmHex(0) {}
+ UseMarkup(0), PrintImmHex(0), PrintHexStyle(HexStyle::C) {}
virtual ~MCInstPrinter();
@@ -80,8 +90,16 @@ 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; }
+
/// Utility function to print immediates in decimal or hex.
- format_object1<int64_t> formatImm(const int64_t Value) const;
+ format_object1<int64_t> formatImm(const int64_t Value) const { return PrintImmHex ? formatHex(Value) : formatDec(Value); }
+
+ /// Utility functions to print decimal/hexadecimal values.
+ format_object1<int64_t> formatDec(const int64_t Value) const;
+ format_object1<int64_t> formatHex(const int64_t Value) const;
+ format_object1<uint64_t> formatHex(const uint64_t Value) const;
};
} // namespace llvm
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index 9b5415a..310f706 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -268,8 +268,20 @@ public:
if (isBranch() || isCall() || isReturn() || isIndirectBranch())
return true;
unsigned PC = RI.getProgramCounter();
- if (PC == 0) return false;
- return hasDefOfPhysReg(MI, PC, RI);
+ if (PC == 0)
+ return false;
+ if (hasDefOfPhysReg(MI, PC, RI))
+ return true;
+ // A variadic instruction may define PC in the variable operand list.
+ // There's currently no indication of which entries in a variable
+ // list are defs and which are uses. While that's the case, this function
+ // needs to assume they're defs in order to be conservatively correct.
+ for (int i = NumOperands, e = MI.getNumOperands(); i != e; ++i) {
+ if (MI.getOperand(i).isReg() &&
+ RI.isSubRegisterEq(PC, MI.getOperand(i).getReg()))
+ return true;
+ }
+ return false;
}
/// \brief Return true if this instruction has a predicate operand
diff --git a/include/llvm/MC/MCInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h
index 65d1559..c4f9e1c 100644
--- a/include/llvm/MC/MCInstrItineraries.h
+++ b/include/llvm/MC/MCInstrItineraries.h
@@ -157,17 +157,12 @@ public:
/// class. The latency is the maximum completion time for any stage
/// in the itinerary.
///
- /// InstrStages override the itinerary's MinLatency property. In fact, if the
- /// stage latencies, which may be zero, are less than MinLatency,
- /// getStageLatency returns a value less than MinLatency.
- ///
- /// If no stages exist, MinLatency is used. If MinLatency is invalid (<0),
- /// then it defaults to one cycle.
+ /// If no stages exist, it defaults to one cycle.
unsigned getStageLatency(unsigned ItinClassIndx) const {
// If the target doesn't provide itinerary information, use a simple
// non-zero default value for all instructions.
if (isEmpty())
- return SchedModel->MinLatency < 0 ? 1 : SchedModel->MinLatency;
+ return 1;
// Calculate the maximum completion time for any stage.
unsigned Latency = 0, StartCycle = 0;
@@ -176,7 +171,6 @@ public:
Latency = std::max(Latency, StartCycle + IS->getCycles());
StartCycle += IS->getNextCycles();
}
-
return Latency;
}
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 22a2839..0affeee 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -78,8 +78,7 @@ public:
virtual void EmitLabel(MCSymbol *Symbol);
virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace);
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size);
virtual void EmitULEB128Value(const MCExpr *Value);
virtual void EmitSLEB128Value(const MCExpr *Value);
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
@@ -94,7 +93,7 @@ public:
virtual void EmitBundleAlignMode(unsigned AlignPow2);
virtual void EmitBundleLock(bool AlignToEnd);
virtual void EmitBundleUnlock();
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0);
+ virtual void EmitBytes(StringRef Data);
virtual void EmitValueToAlignment(unsigned ByteAlignment,
int64_t Value = 0,
unsigned ValueSize = 1,
@@ -102,6 +101,10 @@ public:
virtual void EmitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit = 0);
virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
+ virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+ unsigned Column, unsigned Flags,
+ unsigned Isa, unsigned Discriminator,
+ StringRef FileName);
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
const MCSymbol *Label,
@@ -110,8 +113,8 @@ public:
const MCSymbol *Label);
virtual void EmitGPRel32Value(const MCExpr *Value);
virtual void EmitGPRel64Value(const MCExpr *Value);
- virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace = 0);
+ virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue);
+ virtual void EmitZeros(uint64_t NumBytes);
virtual void FinishImpl();
/// @}
diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h
index defa299..673cdf6 100644
--- a/include/llvm/MC/MCSchedule.h
+++ b/include/llvm/MC/MCSchedule.h
@@ -30,15 +30,18 @@ struct MCProcResourceDesc {
unsigned NumUnits; // Number of resource of this kind
unsigned SuperIdx; // Index of the resources kind that contains this kind.
- // Buffered resources may be consumed at some indeterminate cycle after
- // dispatch (e.g. for instructions that may issue out-of-order). Unbuffered
- // resources always consume their resource some fixed number of cycles after
- // dispatch (e.g. for instruction interlocking that may stall the pipeline).
- bool IsBuffered;
+ // Number of resources that may be buffered.
+ //
+ // Buffered resources (BufferSize > 0 || BufferSize == -1) may be consumed at
+ // some indeterminate cycle after dispatch (e.g. for instructions that may
+ // issue out-of-order). Unbuffered resources (BufferSize == 0) always consume
+ // their resource some fixed number of cycles after dispatch (e.g. for
+ // instruction interlocking that may stall the pipeline).
+ int BufferSize;
bool operator==(const MCProcResourceDesc &Other) const {
return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx
- && IsBuffered == Other.IsBuffered;
+ && BufferSize == Other.BufferSize;
}
};
@@ -134,28 +137,22 @@ public:
unsigned IssueWidth;
static const unsigned DefaultIssueWidth = 1;
- // MinLatency is the minimum latency between a register write
- // followed by a data dependent read. This determines which
- // instructions may be scheduled in the same per-cycle group. This
- // is distinct from *expected* latency, which determines the likely
- // critical path but does not guarantee a pipeline
- // hazard. MinLatency can always be overridden by the number of
- // InstrStage cycles.
+ // MicroOpBufferSize is the number of micro-ops that the processor may buffer
+ // for out-of-order execution.
//
- // (-1) Standard in-order processor.
- // Use InstrItinerary OperandCycles as MinLatency.
- // If no OperandCycles exist, then use the cycle of the last InstrStage.
+ // "0" means operations that are not ready in this cycle are not considered
+ // for scheduling (they go in the pending queue). Latency is paramount. This
+ // may be more efficient if many instructions are pending in a schedule.
//
- // (0) Out-of-order processor, or in-order with bundled dependencies.
- // RAW dependencies may be dispatched in the same cycle.
- // Optional InstrItinerary OperandCycles provides expected latency.
+ // "1" means all instructions are considered for scheduling regardless of
+ // whether they are ready in this cycle. Latency still causes issue stalls,
+ // but we balance those stalls against other heuristics.
//
- // (>0) In-order processor with variable latencies.
- // Use the greater of this value or the cycle of the last InstrStage.
- // Optional InstrItinerary OperandCycles provides expected latency.
- // TODO: can't yet specify both min and expected latency per operand.
- int MinLatency;
- static const int DefaultMinLatency = -1;
+ // "> 1" means the processor is out-of-order. This is a machine independent
+ // estimate of highly machine specific characteristics such are the register
+ // renaming pool and reorder buffer.
+ unsigned MicroOpBufferSize;
+ static const unsigned DefaultMicroOpBufferSize = 0;
// LoadLatency is the expected latency of load instructions.
//
@@ -172,16 +169,6 @@ public:
unsigned HighLatency;
static const unsigned DefaultHighLatency = 10;
- // ILPWindow is the number of cycles that the scheduler effectively ignores
- // before attempting to hide latency. This should be zero for in-order cpus to
- // always hide expected latency. For out-of-order cpus, it may be tweaked as
- // desired to roughly approximate instruction buffers. The actual threshold is
- // not very important for an OOO processor, as long as it isn't too high. A
- // nonzero value helps avoid rescheduling to hide latency when its is fairly
- // obviously useless and makes register pressure heuristics more effective.
- unsigned ILPWindow;
- static const unsigned DefaultILPWindow = 0;
-
// MispredictPenalty is the typical number of extra cycles the processor
// takes to recover from a branch misprediction.
unsigned MispredictPenalty;
@@ -203,10 +190,9 @@ public:
// initialized in this default ctor because some clients directly instantiate
// MCSchedModel instead of using a generated itinerary.
MCSchedModel(): IssueWidth(DefaultIssueWidth),
- MinLatency(DefaultMinLatency),
+ MicroOpBufferSize(DefaultMicroOpBufferSize),
LoadLatency(DefaultLoadLatency),
HighLatency(DefaultHighLatency),
- ILPWindow(DefaultILPWindow),
MispredictPenalty(DefaultMispredictPenalty),
ProcID(0), ProcResourceTable(0), SchedClassTable(0),
NumProcResourceKinds(0), NumSchedClasses(0),
@@ -216,12 +202,12 @@ public:
}
// Table-gen driven ctor.
- MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned ilp,
+ MCSchedModel(unsigned iw, int mbs, unsigned ll, unsigned hl,
unsigned mp, unsigned pi, const MCProcResourceDesc *pr,
const MCSchedClassDesc *sc, unsigned npr, unsigned nsc,
const InstrItinerary *ii):
- IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl),
- ILPWindow(ilp), MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),
+ IssueWidth(iw), MicroOpBufferSize(mbs), LoadLatency(ll), HighLatency(hl),
+ MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),
SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc),
InstrItineraries(ii) {}
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index 50e33a5..754e829 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -25,22 +25,33 @@ namespace llvm {
// The memory for this string is stored in the same MCContext as *this.
StringRef SectionName;
+ // FIXME: The following fields should not be mutable, but are for now so
+ // the asm parser can honor the .linkonce directive.
+
/// Characteristics - This is the Characteristics field of a section,
- // drawn from the enums below.
- unsigned Characteristics;
+ /// drawn from the enums below.
+ mutable unsigned Characteristics;
/// Selection - This is the Selection field for the section symbol, if
/// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
- int Selection;
+ mutable int Selection;
+
+ /// Assoc - This is name of the associated section, if it is a COMDAT
+ /// section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0 with an
+ /// associative Selection (IMAGE_COMDAT_SELECT_ASSOCIATIVE).
+ mutable const MCSectionCOFF *Assoc;
private:
friend class MCContext;
MCSectionCOFF(StringRef Section, unsigned Characteristics,
- int Selection, SectionKind K)
+ int Selection, const MCSectionCOFF *Assoc, SectionKind K)
: MCSection(SV_COFF, K), SectionName(Section),
- Characteristics(Characteristics), Selection (Selection) {
+ Characteristics(Characteristics), Selection(Selection), Assoc(Assoc) {
assert ((Characteristics & 0x00F00000) == 0 &&
"alignment must not be set upon section creation");
+ assert ((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ==
+ (Assoc != 0) &&
+ "associative COMDAT section must have an associated section");
}
~MCSectionCOFF();
@@ -57,7 +68,10 @@ namespace llvm {
return SectionName.str() + "_end";
}
unsigned getCharacteristics() const { return Characteristics; }
- int getSelection () const { return Selection; }
+ int getSelection() const { return Selection; }
+ const MCSectionCOFF *getAssocSection() const { return Assoc; }
+
+ void setSelection(int Selection, const MCSectionCOFF *Assoc = 0) const;
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS,
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 2cab481..970c4ed 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -407,7 +407,7 @@ namespace llvm {
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0) = 0;
+ virtual void EmitBytes(StringRef Data) = 0;
/// EmitValue - Emit the expression @p Value into the output as a native
/// integer of the given @p Size bytes.
@@ -418,22 +418,19 @@ namespace llvm {
/// @param Value - The value to emit.
/// @param Size - The size of the integer (in bytes) to emit. This must
/// match a native machine width.
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace) = 0;
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) = 0;
- void EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0);
+ void EmitValue(const MCExpr *Value, unsigned Size);
/// EmitIntValue - Special case of EmitValue that avoids the client having
/// to pass in a MCExpr for constant integers.
- virtual void EmitIntValue(uint64_t Value, unsigned Size,
- unsigned AddrSpace = 0);
+ virtual void EmitIntValue(uint64_t Value, unsigned Size);
/// EmitAbsValue - Emit the Value, but try to avoid relocations. On MachO
/// this is done by producing
/// foo = value
/// .long foo
- void EmitAbsValue(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace = 0);
+ void EmitAbsValue(const MCExpr *Value, unsigned Size);
virtual void EmitULEB128Value(const MCExpr *Value) = 0;
@@ -441,17 +438,15 @@ namespace llvm {
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
- void EmitULEB128IntValue(uint64_t Value, unsigned Padding = 0,
- unsigned AddrSpace = 0);
+ void EmitULEB128IntValue(uint64_t Value, unsigned Padding = 0);
/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
- void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0);
+ void EmitSLEB128IntValue(int64_t Value);
/// EmitSymbolValue - Special case of EmitValue that avoids the client
/// having to pass in a MCExpr for MCSymbols.
- void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
- unsigned AddrSpace = 0);
+ void EmitSymbolValue(const MCSymbol *Sym, unsigned Size);
/// EmitGPRel64Value - Emit the expression @p Value into the output as a
/// gprel64 (64-bit GP relative) value.
@@ -469,14 +464,11 @@ namespace llvm {
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
- virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace = 0);
+ virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue);
- /// EmitZeros - Emit NumBytes worth of zeros. This is a convenience
- /// function that just wraps EmitFill.
- void EmitZeros(uint64_t NumBytes, unsigned AddrSpace = 0) {
- EmitFill(NumBytes, 0, AddrSpace);
- }
+ /// \brief Emit NumBytes worth of zeros.
+ /// This function properly handles data in virtual sections.
+ virtual void EmitZeros(uint64_t NumBytes);
/// EmitValueToAlignment - Emit some number of copies of @p Value until
/// the byte alignment @p ByteAlignment is reached.
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 6e878df..ebcbd5b 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -143,7 +143,7 @@ public:
/// mnemonicIsValid - This returns true if this is a valid mnemonic and false
/// otherwise.
- virtual bool mnemonicIsValid(StringRef Mnemonic) = 0;
+ virtual bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) = 0;
/// MatchAndEmitInstruction - Recognize a series of operands of a parsed
/// instruction as an actual MCInst and emit it to the specified MCStreamer.
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h
index e2478f6..1cba519 100644
--- a/include/llvm/Object/Archive.h
+++ b/include/llvm/Object/Archive.h
@@ -14,12 +14,10 @@
#ifndef LLVM_OBJECT_ARCHIVE_H
#define LLVM_OBJECT_ARCHIVE_H
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/Object/Binary.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
namespace llvm {
@@ -33,33 +31,17 @@ struct ArchiveMemberHeader {
char Size[10]; ///< Size of data, not including header or padding.
char Terminator[2];
- ///! Get the name without looking up long names.
- llvm::StringRef getName() const {
- char EndCond;
- if (Name[0] == '/' || Name[0] == '#')
- EndCond = ' ';
- else
- EndCond = '/';
- llvm::StringRef::size_type end =
- llvm::StringRef(Name, sizeof(Name)).find(EndCond);
- if (end == llvm::StringRef::npos)
- end = sizeof(Name);
- assert(end <= sizeof(Name) && end > 0);
- // Don't include the EndCond if there is one.
- return llvm::StringRef(Name, end);
- }
+ /// Get the name without looking up long names.
+ llvm::StringRef getName() const;
- uint64_t getSize() const {
- uint64_t ret;
- if (llvm::StringRef(Size, sizeof(Size)).rtrim(" ").getAsInteger(10, ret))
- llvm_unreachable("Size is not an integer.");
- return ret;
- }
-};
+ /// Members are not larger than 4GB.
+ uint32_t getSize() const;
-static const ArchiveMemberHeader *ToHeader(const char *base) {
- return reinterpret_cast<const ArchiveMemberHeader *>(base);
-}
+ sys::fs::perms getAccessMode() const;
+ sys::TimeValue getLastModified() const;
+ unsigned getUID() const;
+ unsigned getGID() const;
+};
class Archive : public Binary {
virtual void anchor();
@@ -71,53 +53,34 @@ public:
/// \brief Offset from Data to the start of the file.
uint16_t StartOfFile;
- public:
- Child(const Archive *p, StringRef d) : Parent(p), Data(d) {
- if (!p || d.empty())
- return;
- // Setup StartOfFile and PaddingBytes.
- StartOfFile = sizeof(ArchiveMemberHeader);
- // Don't include attached name.
- StringRef Name = ToHeader(Data.data())->getName();
- if (Name.startswith("#1/")) {
- uint64_t NameSize;
- if (Name.substr(3).rtrim(" ").getAsInteger(10, NameSize))
- llvm_unreachable("Long name length is not an integer");
- StartOfFile += NameSize;
- }
+ const ArchiveMemberHeader *getHeader() const {
+ return reinterpret_cast<const ArchiveMemberHeader *>(Data.data());
}
+ public:
+ Child(const Archive *Parent, const char *Start);
+
bool operator ==(const Child &other) const {
- return (Parent == other.Parent) && (Data.begin() == other.Data.begin());
+ assert(Parent == other.Parent);
+ return Data.begin() == other.Data.begin();
}
bool operator <(const Child &other) const {
return Data.begin() < other.Data.begin();
}
- Child getNext() const {
- size_t SpaceToSkip = Data.size();
- // If it's odd, add 1 to make it even.
- if (SpaceToSkip & 1)
- ++SpaceToSkip;
-
- const char *NextLoc = Data.data() + SpaceToSkip;
-
- // Check to see if this is past the end of the archive.
- if (NextLoc >= Parent->Data->getBufferEnd())
- return Child(Parent, StringRef(0, 0));
-
- size_t NextSize =
- sizeof(ArchiveMemberHeader) + ToHeader(NextLoc)->getSize();
-
- return Child(Parent, StringRef(NextLoc, NextSize));
- }
+ Child getNext() const;
error_code getName(StringRef &Result) const;
- int getLastModified() const;
- int getUID() const;
- int getGID() const;
- int getAccessMode() const;
+ StringRef getRawName() const { return getHeader()->getName(); }
+ sys::TimeValue getLastModified() const {
+ return getHeader()->getLastModified();
+ }
+ unsigned getUID() const { return getHeader()->getUID(); }
+ unsigned getGID() const { return getHeader()->getGID(); }
+ sys::fs::perms getAccessMode() const {
+ return getHeader()->getAccessMode();
+ }
/// \return the size of the archive member without the header or padding.
uint64_t getSize() const { return Data.size() - StartOfFile; }
@@ -126,16 +89,7 @@ public:
}
error_code getMemoryBuffer(OwningPtr<MemoryBuffer> &Result,
- bool FullPath = false) const {
- StringRef Name;
- if (error_code ec = getName(Name))
- return ec;
- SmallString<128> Path;
- Result.reset(MemoryBuffer::getMemBuffer(
- getBuffer(), FullPath ? (Twine(Parent->getFileName()) + "(" + Name +
- ")").toStringRef(Path) : Name, false));
- return error_code::success();
- }
+ bool FullPath = false) const;
error_code getAsBinary(OwningPtr<Binary> &Result) const;
};
@@ -143,7 +97,7 @@ public:
class child_iterator {
Child child;
public:
- child_iterator() : child(Child(0, StringRef())) {}
+ child_iterator() : child(Child(0, 0)) {}
child_iterator(const Child &c) : child(c) {}
const Child* operator->() const {
return &child;
@@ -220,7 +174,7 @@ public:
return Format;
}
- child_iterator begin_children(bool skip_internal = true) const;
+ child_iterator begin_children(bool SkipInternal = true) const;
child_iterator end_children() const;
symbol_iterator begin_symbols() const;
@@ -234,9 +188,12 @@ public:
// check if a symbol is in the archive
child_iterator findSym(StringRef name) const;
+ bool hasSymbolTable() const;
+
private:
child_iterator SymbolTable;
child_iterator StringTable;
+ child_iterator FirstRegular;
Kind Format;
};
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
index 78fcf6f..a3f5625 100644
--- a/include/llvm/Object/Binary.h
+++ b/include/llvm/Object/Binary.h
@@ -38,6 +38,7 @@ protected:
enum {
ID_Archive,
+ ID_MachOUniversalBinary,
// Object and children.
ID_StartObjects,
ID_COFF,
@@ -87,6 +88,10 @@ public:
return TypeID == ID_Archive;
}
+ bool isMachOUniversalBinary() const {
+ return TypeID == ID_MachOUniversalBinary;
+ }
+
bool isELF() const {
return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
}
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
index 209aa76..2190067 100644
--- a/include/llvm/Object/COFF.h
+++ b/include/llvm/Object/COFF.h
@@ -129,6 +129,14 @@ struct data_directory {
support::ulittle32_t Size;
};
+struct import_directory_table_entry {
+ support::ulittle32_t ImportLookupTableRVA;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle32_t ForwarderChain;
+ support::ulittle32_t NameRVA;
+ support::ulittle32_t ImportAddressTableRVA;
+};
+
struct coff_symbol {
struct StringTableOffset {
support::ulittle32_t Zeroes;
@@ -188,7 +196,9 @@ struct coff_aux_section_definition {
class COFFObjectFile : public ObjectFile {
private:
- const coff_file_header *Header;
+ const coff_file_header *COFFHeader;
+ const pe32_header *PE32Header;
+ const data_directory *DataDirectory;
const coff_section *SectionTable;
const coff_symbol *SymbolTable;
const char *StringTable;
@@ -272,6 +282,9 @@ public:
virtual StringRef getLoadName() const;
error_code getHeader(const coff_file_header *&Res) const;
+ error_code getCOFFHeader(const coff_file_header *&Res) const;
+ error_code getPE32Header(const pe32_header *&Res) const;
+ error_code getDataDirectory(uint32_t index, const data_directory *&Res) const;
error_code getSection(int32_t index, const coff_section *&Res) const;
error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
template <typename T>
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index eb8e22e..2063809 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -1234,7 +1234,8 @@ error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb,
Result |= SymbolRef::SF_Absolute;
if (symb->getType() == ELF::STT_FILE ||
- symb->getType() == ELF::STT_SECTION)
+ symb->getType() == ELF::STT_SECTION ||
+ Symb == begin_symbols()->getRawDataRefImpl())
Result |= SymbolRef::SF_FormatSpecific;
if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF)
@@ -1667,6 +1668,8 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_UNUSED1);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_UNUSED2);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT5);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT6);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_64);
@@ -2030,9 +2033,45 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRTAKEN);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRNTAKEN);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HI);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HA);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TLS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPMOD32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HI);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16_HI);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16_HI);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSLD16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSLD16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSLD16_HI);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSLD16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TPREL16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TPREL16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TPREL16_HI);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TPREL16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16_HI);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TLSGD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TLSLD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16_HI);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16_HA);
default: break;
}
break;
@@ -2052,32 +2091,74 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL14);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL14_BRTAKEN);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL14_BRNTAKEN);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16_HI);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16_HA);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHER);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHERA);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHEST);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHESTA);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL64);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_HI);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_HA);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_DS);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO_DS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16_DS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16_LO_DS);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_DS);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO_DS);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPMOD64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HI);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HI);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_HI);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_HI);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_DS);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_LO_DS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_HI);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_DTPREL16_DS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_DTPREL16_LO_DS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_DTPREL16_HI);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_DTPREL16_HA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_DS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_LO_DS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HIGHER);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HIGHERA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HIGHEST);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HIGHESTA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_DS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_LO_DS);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HIGHER);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HIGHERA);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HIGHEST);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HIGHESTA);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSGD);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSLD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16_LO);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16_HI);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16_HA);
default: break;
}
break;
@@ -2272,7 +2353,16 @@ error_code ELFObjectFile<ELFT>::getRelocationValueString(
res = "Unknown";
}
break;
- case ELF::EM_AARCH64:
+ 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_ARM:
case ELF::EM_HEXAGON:
res = symname;
@@ -2708,7 +2798,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
return (ELFT::TargetEndianness == support::little) ?
Triple::mipsel : Triple::mips;
case ELF::EM_PPC64:
- return Triple::ppc64;
+ return (ELFT::TargetEndianness == support::little) ?
+ Triple::ppc64le : Triple::ppc64;
case ELF::EM_S390:
return Triple::systemz;
default:
diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h
index 029a8ab..fca965f 100644
--- a/include/llvm/Object/ELFYAML.h
+++ b/include/llvm/Object/ELFYAML.h
@@ -36,23 +36,59 @@ LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
+// Just use 64, since it can hold 32-bit values too.
+LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
// since 64-bit can hold 32-bit values too.
struct FileHeader {
ELF_ELFCLASS Class;
ELF_ELFDATA Data;
+ ELF_ELFOSABI OSABI;
ELF_ET Type;
ELF_EM Machine;
llvm::yaml::Hex64 Entry;
};
+struct Symbol {
+ StringRef Name;
+ ELF_STT Type;
+ StringRef Section;
+ llvm::yaml::Hex64 Value;
+ llvm::yaml::Hex64 Size;
+};
+struct LocalGlobalWeakSymbols {
+ std::vector<Symbol> Local;
+ std::vector<Symbol> Global;
+ std::vector<Symbol> Weak;
+};
+struct Section {
+ StringRef Name;
+ ELF_SHT Type;
+ ELF_SHF Flags;
+ llvm::yaml::Hex64 Address;
+ object::yaml::BinaryRef Content;
+ StringRef Link;
+ llvm::yaml::Hex64 AddressAlign;
+};
struct Object {
FileHeader Header;
+ std::vector<Section> Sections;
+ // Although in reality the symbols reside in a section, it is a lot
+ // cleaner and nicer if we read them from the YAML as a separate
+ // top-level key, which automatically ensures that invariants like there
+ // being a single SHT_SYMTAB section are upheld.
+ LocalGlobalWeakSymbols Symbols;
};
} // end namespace ELFYAML
} // end namespace llvm
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Section)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
+
namespace llvm {
namespace yaml {
@@ -77,11 +113,46 @@ struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
};
template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
+ static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
+ static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
+};
+
+template <>
+struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
+ static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
+ static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
+};
+
+template <>
struct MappingTraits<ELFYAML::FileHeader> {
static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
};
template <>
+struct MappingTraits<ELFYAML::Symbol> {
+ static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
+};
+
+template <>
+struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
+ static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
+};
+
+template <>
+struct MappingTraits<ELFYAML::Section> {
+ static void mapping(IO &IO, ELFYAML::Section &Section);
+};
+
+template <>
struct MappingTraits<ELFYAML::Object> {
static void mapping(IO &IO, ELFYAML::Object &Object);
};
diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h
index fbaf71c..8b0570b 100644
--- a/include/llvm/Object/Error.h
+++ b/include/llvm/Object/Error.h
@@ -22,17 +22,17 @@ namespace object {
const error_category &object_category();
struct object_error {
-enum _ {
- success = 0,
- invalid_file_type,
- parse_failed,
- unexpected_eof
-};
- _ v_;
-
- object_error(_ v) : v_(v) {}
- explicit object_error(int v) : v_(_(v)) {}
- operator int() const {return v_;}
+ enum Impl {
+ success = 0,
+ arch_not_found,
+ invalid_file_type,
+ parse_failed,
+ unexpected_eof
+ };
+ Impl V;
+
+ object_error(Impl V) : V(V) {}
+ operator Impl() const { return V; }
};
inline error_code make_error_code(object_error e) {
@@ -43,7 +43,8 @@ inline error_code make_error_code(object_error e) {
template <> struct is_error_code_enum<object::object_error> : true_type { };
-template <> struct is_error_code_enum<object::object_error::_> : true_type { };
+template <> struct is_error_code_enum<object::object_error::Impl> : true_type {
+};
} // end namespace llvm.
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index 1b9faaa..50435d6 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Object/MachOFormat.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/MachO.h"
@@ -196,6 +197,8 @@ public:
bool is64Bit() const;
void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
+ static Triple::ArchType getArch(uint32_t CPUType);
+
static bool classof(const Binary *v) {
return v->isMachO();
}
diff --git a/include/llvm/Object/MachOFormat.h b/include/llvm/Object/MachOFormat.h
index ffca391..96ee8a7 100644
--- a/include/llvm/Object/MachOFormat.h
+++ b/include/llvm/Object/MachOFormat.h
@@ -95,6 +95,8 @@ namespace macho {
enum StructureSizes {
Header32Size = 28,
Header64Size = 32,
+ FatHeaderSize = 8,
+ FatArchHeaderSize = 20,
SegmentLoadCommand32Size = 56,
SegmentLoadCommand64Size = 72,
Section32Size = 68,
@@ -130,6 +132,22 @@ namespace macho {
uint32_t Reserved;
};
+ /// \brief Header for universal object files.
+ struct FatHeader {
+ uint32_t Magic;
+ uint32_t NumFatArch;
+ };
+
+ /// \brief Header for a single-architecture object file in a
+ /// universal binary.
+ struct FatArchHeader {
+ uint32_t CPUType;
+ uint32_t CPUSubtype;
+ uint32_t Offset;
+ uint32_t Size;
+ uint32_t Align;
+ };
+
// See <mach-o/loader.h>.
enum HeaderFileType {
HFT_Object = 0x1
diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h
new file mode 100644
index 0000000..5743282
--- /dev/null
+++ b/include/llvm/Object/MachOUniversal.h
@@ -0,0 +1,102 @@
+//===- MachOUniversal.h - Mach-O universal binaries -------------*- 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 Mach-O fat/universal binaries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
+#define LLVM_OBJECT_MACHOUNIVERSAL_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/MachOFormat.h"
+
+namespace llvm {
+namespace object {
+
+class ObjectFile;
+
+class MachOUniversalBinary : public Binary {
+ virtual void anchor();
+
+ uint32_t NumberOfObjects;
+public:
+ class ObjectForArch {
+ const MachOUniversalBinary *Parent;
+ /// \brief Index of object in the universal binary.
+ uint32_t Index;
+ /// \brief Descriptor of the object.
+ macho::FatArchHeader Header;
+
+ public:
+ ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
+
+ void clear() {
+ Parent = 0;
+ Index = 0;
+ }
+
+ bool operator==(const ObjectForArch &Other) const {
+ return (Parent == Other.Parent) && (Index == Other.Index);
+ }
+
+ ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
+ uint32_t getCPUType() const { return Header.CPUType; }
+
+ error_code getAsObjectFile(OwningPtr<ObjectFile> &Result) const;
+ };
+
+ class object_iterator {
+ ObjectForArch Obj;
+ public:
+ object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
+ const ObjectForArch* operator->() const {
+ return &Obj;
+ }
+
+ bool operator==(const object_iterator &Other) const {
+ return Obj == Other.Obj;
+ }
+ bool operator!=(const object_iterator &Other) const {
+ return !(*this == Other);
+ }
+
+ object_iterator& operator++() { // Preincrement
+ Obj = Obj.getNext();
+ return *this;
+ }
+ };
+
+ MachOUniversalBinary(MemoryBuffer *Source, error_code &ec);
+
+ object_iterator begin_objects() const {
+ return ObjectForArch(this, 0);
+ }
+ object_iterator end_objects() const {
+ return ObjectForArch(0, 0);
+ }
+
+ uint32_t getNumberOfObjects() const { return NumberOfObjects; }
+
+ // Cast methods.
+ static inline bool classof(Binary const *V) {
+ return V->isMachOUniversalBinary();
+ }
+
+ error_code getObjectForArch(Triple::ArchType Arch,
+ OwningPtr<ObjectFile> &Result) const;
+};
+
+}
+}
+
+#endif
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index 52e4d6f..b1eb4e6 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -81,6 +81,8 @@ public:
switch (RelocType) {
case llvm::ELF::R_PPC64_ADDR32:
return visitELF_PPC64_ADDR32(R, Value);
+ case llvm::ELF::R_PPC64_ADDR64:
+ return visitELF_PPC64_ADDR64(R, Value);
default:
HasError = true;
return RelocToApply();
@@ -217,6 +219,10 @@ private:
uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
return RelocToApply(Res, 4);
}
+ RelocToApply visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) {
+ int64_t Addend = getAddend64BE(R);
+ return RelocToApply(Value + Addend, 8);
+ }
/// PPC32 ELF
RelocToApply visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) {
diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h
index d3accfe..06ba679 100644
--- a/include/llvm/Option/ArgList.h
+++ b/include/llvm/Option/ArgList.h
@@ -222,8 +222,17 @@ public:
/// negation are present, the last one wins.
bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
+ /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative
+ /// form \p Neg, return true if the option or its alias is present, false if
+ /// the negation is present, and \p Default if none of the options are
+ /// given. If multiple options are present, the last one wins.
+ bool hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
+ bool Default = true) const;
+
/// AddLastArg - Render only the last argument match \p Id0, if present.
void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
+ void AddLastArg(ArgStringList &Output, OptSpecifier Id0,
+ OptSpecifier Id1) const;
/// AddAllArgs - Render all arguments matching the given ids.
void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
diff --git a/include/llvm/Option/OptParser.td b/include/llvm/Option/OptParser.td
index e781fa0..32cc2c0 100644
--- a/include/llvm/Option/OptParser.td
+++ b/include/llvm/Option/OptParser.td
@@ -14,10 +14,10 @@
// Define the kinds of options.
-class OptionKind<string name, int predecence = 0, bit sentinel = 0> {
+class OptionKind<string name, int precedence = 0, bit sentinel = 0> {
string Name = name;
// The kind precedence, kinds with lower precedence are matched first.
- int Precedence = predecence;
+ int Precedence = precedence;
// Indicate a sentinel option.
bit Sentinel = sentinel;
}
@@ -89,6 +89,7 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
list<OptionFlag> Flags = [];
OptionGroup Group = ?;
Option Alias = ?;
+ list<string> AliasArgs = [];
}
// Helpers for defining options.
@@ -113,6 +114,7 @@ class JoinedAndSeparate<list<string> prefixes, string name>
// Mix-ins for adding optional attributes.
class Alias<Option alias> { Option Alias = alias; }
+class AliasArgs<list<string> aliasargs> { list<string> AliasArgs = aliasargs; }
class EnumName<string name> { string EnumName = name; }
class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
class Group<OptionGroup group> { OptionGroup Group = group; }
diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h
index a93acbf..a5b59ce 100644
--- a/include/llvm/Option/OptTable.h
+++ b/include/llvm/Option/OptTable.h
@@ -44,6 +44,7 @@ public:
unsigned short Flags;
unsigned short GroupID;
unsigned short AliasID;
+ const char *AliasArgs;
};
private:
@@ -99,9 +100,6 @@ public:
return getInfo(id).GroupID;
}
- /// \brief Should the help for the given option be hidden by default.
- bool isOptionHelpHidden(OptSpecifier id) const;
-
/// \brief Get the help text to use to describe this option.
const char *getOptionHelpText(OptSpecifier id) const {
return getInfo(id).HelpText;
@@ -119,11 +117,17 @@ public:
/// \param [in,out] Index - The current parsing position in the argument
/// string list; on return this will be the index of the next argument
/// string to parse.
+ /// \param [in] FlagsToInclude - Only parse options with any of these flags.
+ /// Zero is the default which includes all flags.
+ /// \param [in] FlagsToExclude - Don't parse options with this flag. Zero
+ /// is the default and means exclude nothing.
///
/// \return The parsed argument, or 0 if the argument is missing values
/// (in which case Index still points at the conceptual next argument string
/// to parse).
- Arg *ParseOneArg(const ArgList &Args, unsigned &Index) const;
+ Arg *ParseOneArg(const ArgList &Args, unsigned &Index,
+ unsigned FlagsToInclude = 0,
+ unsigned FlagsToExclude = 0) const;
/// \brief Parse an list of arguments into an InputArgList.
///
@@ -139,19 +143,31 @@ public:
/// \param MissingArgIndex - On error, the index of the option which could
/// not be parsed.
/// \param MissingArgCount - On error, the number of missing options.
+ /// \param FlagsToInclude - Only parse options with any of these flags.
+ /// Zero is the default which includes all flags.
+ /// \param FlagsToExclude - Don't parse options with this flag. Zero
+ /// is the default and means exclude nothing.
/// \return An InputArgList; on error this will contain all the options
/// which could be parsed.
InputArgList *ParseArgs(const char* const *ArgBegin,
const char* const *ArgEnd,
unsigned &MissingArgIndex,
- unsigned &MissingArgCount) const;
+ unsigned &MissingArgCount,
+ unsigned FlagsToInclude = 0,
+ unsigned FlagsToExclude = 0) const;
/// \brief Render the help text for an option table.
///
/// \param OS - The stream to write the help text to.
/// \param Name - The name to use in the usage line.
/// \param Title - The title to use in the usage line.
- /// \param ShowHidden - Whether help-hidden arguments should be shown.
+ /// \param FlagsToInclude - If non-zero, only include options with any
+ /// of these flags set.
+ /// \param FlagsToExclude - Exclude options with any of these flags set.
+ void PrintHelp(raw_ostream &OS, const char *Name,
+ const char *Title, unsigned FlagsToInclude,
+ unsigned FlagsToExclude) const;
+
void PrintHelp(raw_ostream &OS, const char *Name,
const char *Title, bool ShowHidden = false) const;
};
diff --git a/include/llvm/Option/Option.h b/include/llvm/Option/Option.h
index 4861b59..47fd817 100644
--- a/include/llvm/Option/Option.h
+++ b/include/llvm/Option/Option.h
@@ -103,6 +103,16 @@ public:
return Owner->getOption(Info->AliasID);
}
+ /// \brief Get the alias arguments as a \0 separated list.
+ /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
+ const char *getAliasArgs() const {
+ assert(Info && "Must have a valid info!");
+ assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
+ "AliasArgs should be either 0 or non-empty.");
+
+ return Info->AliasArgs;
+ }
+
/// \brief Get the default prefix for this option.
StringRef getPrefix() const {
const char *Prefix = *Info->Prefixes;
diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h
index 839cf93..666b3c8 100644
--- a/include/llvm/Support/BlockFrequency.h
+++ b/include/llvm/Support/BlockFrequency.h
@@ -25,17 +25,35 @@ class BranchProbability;
class BlockFrequency {
uint64_t Frequency;
- static const int64_t ENTRY_FREQ = 1024;
+ static const int64_t ENTRY_FREQ = 1 << 14;
+
+ // Scale frequency by N/D, saturating on overflow.
+ void scale(uint32_t N, uint32_t D);
public:
BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }
+ /// \brief Returns the frequency of the entry block of the function.
static uint64_t getEntryFrequency() { return ENTRY_FREQ; }
+
+ /// \brief Returns the maximum possible frequency, the saturation value.
+ static uint64_t getMaxFrequency() { return -1ULL; }
+
+ /// \brief Returns the frequency as a fixpoint number scaled by the entry
+ /// frequency.
uint64_t getFrequency() const { return Frequency; }
+ /// \brief Multiplies with a branch probability. The computation will never
+ /// overflow.
BlockFrequency &operator*=(const BranchProbability &Prob);
const BlockFrequency operator*(const BranchProbability &Prob) const;
+ /// \brief Divide by a non-zero branch probability using saturating
+ /// arithmetic.
+ BlockFrequency &operator/=(const BranchProbability &Prob);
+ BlockFrequency operator/(const BranchProbability &Prob) const;
+
+ /// \brief Adds another block frequency using saturating arithmetic.
BlockFrequency &operator+=(const BlockFrequency &Freq);
const BlockFrequency operator+(const BlockFrequency &Freq) const;
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
index 71a83e9..74ec726 100644
--- a/include/llvm/Support/CFG.h
+++ b/include/llvm/Support/CFG.h
@@ -328,7 +328,7 @@ template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
typedef Function::iterator nodes_iterator;
static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
static nodes_iterator nodes_end (Function *F) { return F->end(); }
- static unsigned size (Function *F) { return F->size(); }
+ static size_t size (Function *F) { return F->size(); }
};
template <> struct GraphTraits<const Function*> :
public GraphTraits<const BasicBlock*> {
@@ -338,7 +338,7 @@ template <> struct GraphTraits<const Function*> :
typedef Function::const_iterator nodes_iterator;
static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
static nodes_iterator nodes_end (const Function *F) { return F->end(); }
- static unsigned size (const Function *F) { return F->size(); }
+ static size_t size (const Function *F) { return F->size(); }
};
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index d348b76..a39a3f9 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -488,6 +488,24 @@ namespace COFF {
uint32_t Size;
};
+ enum DataDirectoryIndex {
+ EXPORT_TABLE = 0,
+ IMPORT_TABLE,
+ RESOURCE_TABLE,
+ EXCEPTION_TABLE,
+ CERTIFICATE_TABLE,
+ BASE_RELOCATION_TABLE,
+ DEBUG,
+ ARCHITECTURE,
+ GLOBAL_PTR,
+ TLS_TABLE,
+ LOAD_CONFIG_TABLE,
+ BOUND_IMPORT,
+ IAT,
+ DELAY_IMPORT_DESCRIPTOR,
+ CLR_RUNTIME_HEADER
+ };
+
enum WindowsSubsystem {
IMAGE_SUBSYSTEM_UNKNOWN = 0, ///< An unknown subsystem.
IMAGE_SUBSYSTEM_NATIVE = 1, ///< Device drivers and native Windows processes
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index d80d9d8..2a1c5ca 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -198,6 +198,12 @@ public:
CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
}
+ /// \brief Return true if the call should not be treated as a call to a
+ /// builtin.
+ bool isNoBuiltin() const {
+ CALLSITE_DELEGATE_GETTER(isNoBuiltin());
+ }
+
/// @brief Return true if the call should not be inlined.
bool isNoInline() const {
CALLSITE_DELEGATE_GETTER(isNoInline());
@@ -251,6 +257,15 @@ public:
return paramHasAttr(ArgNo + 1, Attribute::ByVal);
}
+ bool doesNotAccessMemory(unsigned ArgNo) const {
+ return paramHasAttr(ArgNo + 1, Attribute::ReadNone);
+ }
+
+ bool onlyReadsMemory(unsigned ArgNo) const {
+ return paramHasAttr(ArgNo + 1, Attribute::ReadOnly) ||
+ paramHasAttr(ArgNo + 1, Attribute::ReadNone);
+ }
+
/// hasArgument - Returns true if this CallSite passes the given Value* as an
/// argument to the called function.
bool hasArgument(const Value *Arg) const {
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index 0d2d6c9..d70acbf 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -206,7 +206,10 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
}
};
-
+template <class X> struct is_simple_type {
+ static const bool value =
+ is_same<X, typename simplify_type<X>::SimpleType>::value;
+};
// cast<X> - Return the argument parameter cast to the specified type. This
// casting operator asserts that the type is correct, so it does not return null
@@ -216,10 +219,12 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
// cast<Instruction>(myVal)->getParent()
//
template <class X, class Y>
-inline typename cast_retty<X, const Y>::ret_type cast(const Y &Val) {
+inline typename enable_if_c<!is_simple_type<Y>::value,
+ typename cast_retty<X, const Y>::ret_type>::type
+cast(const Y &Val) {
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
- return cast_convert_val<X, const Y,
- typename simplify_type<const Y>::SimpleType>::doit(Val);
+ return cast_convert_val<
+ X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val);
}
template <class X, class Y>
@@ -230,10 +235,7 @@ inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
}
template <class X, class Y>
-inline typename enable_if<
- is_same<Y, typename simplify_type<Y>::SimpleType>,
- typename cast_retty<X, Y*>::ret_type
->::type cast(Y *Val) {
+inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
return cast_convert_val<X, Y*,
typename simplify_type<Y*>::SimpleType>::doit(Val);
@@ -259,7 +261,9 @@ inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
//
template <class X, class Y>
-inline typename cast_retty<X, const Y>::ret_type dyn_cast(const Y &Val) {
+inline typename enable_if_c<!is_simple_type<Y>::value,
+ typename cast_retty<X, const Y>::ret_type>::type
+dyn_cast(const Y &Val) {
return isa<X>(Val) ? cast<X>(Val) : 0;
}
@@ -269,10 +273,7 @@ inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
}
template <class X, class Y>
-inline typename enable_if<
- is_same<Y, typename simplify_type<Y>::SimpleType>,
- typename cast_retty<X, Y*>::ret_type
->::type dyn_cast(Y *Val) {
+inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
return isa<X>(Val) ? cast<X>(Val) : 0;
}
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 531760b..c0bfbae 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -1745,6 +1745,59 @@ void PrintHelpMessage(bool Hidden=false, bool Categorized=false);
/// llvm::cl::ParseCommandLineOptions().
void getRegisteredOptions(StringMap<Option*> &Map);
+//===----------------------------------------------------------------------===//
+// Standalone command line processing utilities.
+//
+
+/// \brief Saves strings in the inheritor's stable storage and returns a stable
+/// raw character pointer.
+class StringSaver {
+public:
+ virtual const char *SaveString(const char *Str) = 0;
+ virtual ~StringSaver() {}; // Pacify -Wnon-virtual-dtor.
+};
+
+/// \brief Tokenizes a command line that can contain escapes and quotes.
+//
+/// The quoting rules match those used by GCC and other tools that use
+/// libiberty's buildargv() or expandargv() utilities, and do not match bash.
+/// They differ from buildargv() on treatment of backslashes that do not escape
+/// a special character to make it possible to accept most Windows file paths.
+///
+/// \param [in] Source The string to be split on whitespace with quotes.
+/// \param [in] Saver Delegates back to the caller for saving parsed strings.
+/// \param [out] NewArgv All parsed strings are appended to NewArgv.
+void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv);
+
+/// \brief Tokenizes a Windows command line which may contain quotes and escaped
+/// quotes.
+///
+/// See MSDN docs for CommandLineToArgvW for information on the quoting rules.
+/// http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft(v=vs.85).aspx
+///
+/// \param [in] Source The string to be split on whitespace with quotes.
+/// \param [in] Saver Delegates back to the caller for saving parsed strings.
+/// \param [out] NewArgv All parsed strings are appended to NewArgv.
+void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv);
+
+/// \brief String tokenization function type. Should be compatible with either
+/// Windows or Unix command line tokenizers.
+typedef void (*TokenizerCallback)(StringRef Source, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv);
+
+/// \brief Expand response files on a command line recursively using the given
+/// StringSaver and tokenization strategy. Argv should contain the command line
+/// before expansion and will be modified in place.
+///
+/// \param [in] Saver Delegates back to the caller for saving parsed strings.
+/// \param [in] Tokenizer Tokenization strategy. Typically Unix or Windows.
+/// \param [in,out] Argv Command line into which to expand response files.
+/// \return true if all @files were expanded successfully or there were none.
+bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
+ SmallVectorImpl<const char *> &Argv);
+
} // End namespace cl
} // End namespace llvm
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 13d057b..feac934 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -21,6 +21,25 @@
# define __has_feature(x) 0
#endif
+#ifndef __has_attribute
+# define __has_attribute(x) 0
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+/// \macro __GNUC_PREREQ
+/// \brief Defines __GNUC_PREREQ if glibc's features.h isn't available.
+#ifndef __GNUC_PREREQ
+# if defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define __GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+# else
+# define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
/// \brief Does the compiler support r-value references?
/// This implies that <utility> provides the one-argument std::move; it
/// does not imply the existence of any other C++ library features.
@@ -146,13 +165,15 @@
/// into a shared library, then the class should be private to the library and
/// not accessible from outside it. Can also be used to mark variables and
/// functions, making them private to any shared library they are linked into.
-#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+/// On PE/COFF targets, library visibility is the default, so this isn't needed.
+#if (__has_attribute(visibility) || __GNUC_PREREQ(4, 0)) && \
+ !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32)
#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
#else
#define LLVM_LIBRARY_VISIBILITY
#endif
-#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+#if __has_attribute(used) || __GNUC_PREREQ(3, 1)
#define LLVM_ATTRIBUTE_USED __attribute__((__used__))
#else
#define LLVM_ATTRIBUTE_USED
@@ -166,31 +187,37 @@
// more portable solution:
// (void)unused_var_name;
// Prefer cast-to-void wherever it is sufficient.
-#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+#if __has_attribute(unused) || __GNUC_PREREQ(3, 1)
#define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
#else
#define LLVM_ATTRIBUTE_UNUSED
#endif
-#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+// FIXME: Provide this for PE/COFF targets.
+#if (__has_attribute(weak) || __GNUC_PREREQ(4, 0)) && \
+ (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32))
#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
#else
#define LLVM_ATTRIBUTE_WEAK
#endif
-#ifdef __GNUC__ // aka 'CONST' but following LLVM Conventions.
+// Prior to clang 3.2, clang did not accept any spelling of
+// __has_attribute(const), so assume it is supported.
+#if defined(__clang__) || defined(__GNUC__)
+// aka 'CONST' but following LLVM Conventions.
#define LLVM_READNONE __attribute__((__const__))
#else
#define LLVM_READNONE
#endif
-#ifdef __GNUC__ // aka 'PURE' but following LLVM Conventions.
+#if __has_attribute(pure) || defined(__GNUC__)
+// aka 'PURE' but following LLVM Conventions.
#define LLVM_READONLY __attribute__((__pure__))
#else
#define LLVM_READONLY
#endif
-#if (__GNUC__ >= 4)
+#if __has_builtin(__builtin_expect) || __GNUC_PREREQ(4, 0)
#define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
#define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
#else
@@ -213,7 +240,7 @@
/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
/// mark a method "not for inlining".
-#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#if __has_attribute(noinline) || __GNUC_PREREQ(3, 4)
#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER)
#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
@@ -225,7 +252,7 @@
/// so, mark a method "always inline" because it is performance sensitive. GCC
/// 3.4 supported this but is buggy in various cases and produces unimplemented
/// errors, just use it in GCC 4.0 and later.
-#if __GNUC__ > 3
+#if __has_attribute(always_inline) || __GNUC_PREREQ(4, 0)
#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
#elif defined(_MSC_VER)
#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
@@ -267,8 +294,7 @@
/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
/// to an expression which states that it is undefined behavior for the
/// compiler to reach this point. Otherwise is not defined.
-#if defined(__clang__) || (__GNUC__ > 4) \
- || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#if __has_builtin(__builtin_unreachable) || __GNUC_PREREQ(4, 5)
# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
#elif defined(_MSC_VER)
# define LLVM_BUILTIN_UNREACHABLE __assume(false)
@@ -276,8 +302,7 @@
/// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
/// which causes the program to exit abnormally.
-#if defined(__clang__) || (__GNUC__ > 4) \
- || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+#if __has_builtin(__builtin_trap) || __GNUC_PREREQ(4, 3)
# define LLVM_BUILTIN_TRAP __builtin_trap()
#else
# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
@@ -285,11 +310,10 @@
/// \macro LLVM_ASSUME_ALIGNED
/// \brief Returns a pointer with an assumed alignment.
-#if !defined(__clang__) && ((__GNUC__ > 4) \
- || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
-// FIXME: Enable on clang when it supports it.
+#if __has_builtin(__builtin_assume_aligned) && __GNUC_PREREQ(4, 7)
# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
#elif defined(LLVM_BUILTIN_UNREACHABLE)
+// As of today, clang does not support __builtin_assume_aligned.
# define LLVM_ASSUME_ALIGNED(p, a) \
(((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p)))
#else
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
index 0f29256..f757c6e 100644
--- a/include/llvm/Support/ConstantRange.h
+++ b/include/llvm/Support/ConstantRange.h
@@ -42,6 +42,14 @@ namespace llvm {
class ConstantRange {
APInt Lower, Upper;
+#if LLVM_HAS_RVALUE_REFERENCES
+ // If we have move semantics, pass APInts by value and move them into place.
+ typedef APInt APIntMoveTy;
+#else
+ // Otherwise pass by const ref to save one copy.
+ typedef const APInt &APIntMoveTy;
+#endif
+
public:
/// Initialize a full (the default) or empty set for the specified bit width.
///
@@ -49,12 +57,12 @@ public:
/// Initialize a range to hold the single specified value.
///
- ConstantRange(const APInt &Value);
+ ConstantRange(APIntMoveTy Value);
/// @brief Initialize a range of values explicitly. This will assert out if
/// Lower==Upper and Lower != Min or Max value for its type. It will also
/// assert out if the two APInt's are not the same bit width.
- ConstantRange(const APInt &Lower, const APInt &Upper);
+ ConstantRange(APIntMoveTy Lower, APIntMoveTy Upper);
/// makeICmpRegion - Produce the smallest range that contains all values that
/// might satisfy the comparison specified by Pred when compared to any value
diff --git a/include/llvm/Support/ConvertUTF.h b/include/llvm/Support/ConvertUTF.h
index 1eae6d6..2820366 100644
--- a/include/llvm/Support/ConvertUTF.h
+++ b/include/llvm/Support/ConvertUTF.h
@@ -87,8 +87,8 @@
------------------------------------------------------------------------ */
-#ifndef CLANG_BASIC_CONVERTUTF_H
-#define CLANG_BASIC_CONVERTUTF_H
+#ifndef LLVM_SUPPORT_CONVERTUTF_H
+#define LLVM_SUPPORT_CONVERTUTF_H
/* ---------------------------------------------------------------------
The following 4 definitions are compiler-specific.
@@ -112,6 +112,9 @@ typedef unsigned char Boolean; /* 0 or 1 */
#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4
+#define UNI_UTF16_BYTE_ORDER_MARK_NATIVE 0xFEFF
+#define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+
typedef enum {
conversionOK, /* conversion successful */
sourceExhausted, /* partial character in source, but hit end */
@@ -165,6 +168,7 @@ unsigned getNumBytesForUTF8(UTF8 firstByte);
/*************************************************************************/
/* Below are LLVM-specific wrappers of the functions above. */
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
namespace llvm {
@@ -219,6 +223,22 @@ static inline ConversionResult convertUTF8Sequence(const UTF8 **source,
return sourceExhausted;
return ConvertUTF8toUTF32(source, *source + size, &target, target + 1, flags);
}
+
+/**
+ * Returns true if a blob of text starts with a UTF-16 big or little endian byte
+ * order mark.
+ */
+bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
+
+/**
+ * Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-16 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
+
} /* end namespace llvm */
#endif
diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
index 7484abd..a26070c 100644
--- a/include/llvm/Support/DataTypes.h.cmake
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -26,7 +26,6 @@
#ifndef SUPPORT_DATATYPES_H
#define SUPPORT_DATATYPES_H
-#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
#cmakedefine HAVE_UINT64_T ${HAVE_UINT64_T}
@@ -54,9 +53,7 @@
#endif
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
-#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
-#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
@@ -101,7 +98,11 @@ typedef short int16_t;
typedef unsigned short uint16_t;
typedef signed char int8_t;
typedef unsigned char uint8_t;
-typedef signed int ssize_t;
+#if defined(_WIN64)
+ typedef signed __int64 ssize_t;
+#else
+ typedef signed int ssize_t;
+#endif
#ifndef INT8_MAX
# define INT8_MAX 127
#endif
diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
index b9fb48a..7fc9b72 100644
--- a/include/llvm/Support/DataTypes.h.in
+++ b/include/llvm/Support/DataTypes.h.in
@@ -26,7 +26,6 @@
#ifndef SUPPORT_DATATYPES_H
#define SUPPORT_DATATYPES_H
-#undef HAVE_SYS_TYPES_H
#undef HAVE_INTTYPES_H
#undef HAVE_STDINT_H
#undef HAVE_UINT64_T
@@ -54,9 +53,7 @@
#endif
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
-#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
-#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
@@ -98,7 +95,12 @@ typedef short int16_t;
typedef unsigned short uint16_t;
typedef signed char int8_t;
typedef unsigned char uint8_t;
-typedef signed int ssize_t;
+#if defined(_WIN64)
+ typedef signed __int64 ssize_t;
+#else
+ typedef signed int ssize_t;
+#endif
+
#ifndef INT8_MAX
# define INT8_MAX 127
#endif
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index b52914f..d0e2322 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -272,6 +272,8 @@ enum dwarf_constants {
DW_AT_GNU_vector = 0x2107,
DW_AT_GNU_template_name = 0x2110,
+ DW_AT_GNU_odr_signature = 0x210f,
+
// Extensions for Fission proposal.
DW_AT_GNU_dwo_name = 0x2130,
DW_AT_GNU_dwo_id = 0x2131,
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index ac11f0a..54da31c 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -276,7 +276,6 @@ enum {
EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller
EM_TILE64 = 187, // Tilera TILE64 multicore architecture family
EM_TILEPRO = 188, // Tilera TILEPro multicore architecture family
- EM_MICROBLAZE = 189, // Xilinx MicroBlaze 32-bit RISC soft processor core
EM_CUDA = 190, // NVIDIA CUDA architecture
EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture family
EM_CLOUDSHIELD = 192, // CloudShield architecture family
@@ -287,8 +286,7 @@ enum {
EM_RL78 = 197, // Renesas RL78 family
EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor
EM_78KOR = 199, // Renesas 78KOR family
- EM_56800EX = 200, // Freescale 56800EX Digital Signal Controller (DSC)
- EM_MBLAZE = 47787 // Xilinx MicroBlaze
+ EM_56800EX = 200 // Freescale 56800EX Digital Signal Controller (DSC)
};
// Object file classes.
@@ -418,32 +416,6 @@ enum {
R_386_NUM = 43
};
-// MBlaze relocations.
-enum {
- R_MICROBLAZE_NONE = 0,
- R_MICROBLAZE_32 = 1,
- R_MICROBLAZE_32_PCREL = 2,
- R_MICROBLAZE_64_PCREL = 3,
- R_MICROBLAZE_32_PCREL_LO = 4,
- R_MICROBLAZE_64 = 5,
- R_MICROBLAZE_32_LO = 6,
- R_MICROBLAZE_SRO32 = 7,
- R_MICROBLAZE_SRW32 = 8,
- R_MICROBLAZE_64_NONE = 9,
- R_MICROBLAZE_32_SYM_OP_SYM = 10,
- R_MICROBLAZE_GNU_VTINHERIT = 11,
- R_MICROBLAZE_GNU_VTENTRY = 12,
- R_MICROBLAZE_GOTPC_64 = 13,
- R_MICROBLAZE_GOT_64 = 14,
- R_MICROBLAZE_PLT_64 = 15,
- R_MICROBLAZE_REL = 16,
- R_MICROBLAZE_JUMP_SLOT = 17,
- R_MICROBLAZE_GLOB_DAT = 18,
- R_MICROBLAZE_GOTOFF_64 = 19,
- R_MICROBLAZE_GOTOFF_32 = 20,
- R_MICROBLAZE_COPY = 21
-};
-
// ELF Relocation types for PPC32
enum {
R_PPC_NONE = 0, /* No relocation. */
@@ -460,9 +432,45 @@ enum {
R_PPC_REL14 = 11,
R_PPC_REL14_BRTAKEN = 12,
R_PPC_REL14_BRNTAKEN = 13,
+ R_PPC_GOT16 = 14,
+ R_PPC_GOT16_LO = 15,
+ R_PPC_GOT16_HI = 16,
+ R_PPC_GOT16_HA = 17,
R_PPC_REL32 = 26,
+ R_PPC_TLS = 67,
+ R_PPC_DTPMOD32 = 68,
+ R_PPC_TPREL16 = 69,
R_PPC_TPREL16_LO = 70,
- R_PPC_TPREL16_HA = 72
+ R_PPC_TPREL16_HI = 71,
+ R_PPC_TPREL16_HA = 72,
+ R_PPC_TPREL32 = 73,
+ R_PPC_DTPREL16 = 74,
+ R_PPC_DTPREL16_LO = 75,
+ R_PPC_DTPREL16_HI = 76,
+ R_PPC_DTPREL16_HA = 77,
+ R_PPC_DTPREL32 = 78,
+ R_PPC_GOT_TLSGD16 = 79,
+ R_PPC_GOT_TLSGD16_LO = 80,
+ R_PPC_GOT_TLSGD16_HI = 81,
+ R_PPC_GOT_TLSGD16_HA = 82,
+ R_PPC_GOT_TLSLD16 = 83,
+ R_PPC_GOT_TLSLD16_LO = 84,
+ R_PPC_GOT_TLSLD16_HI = 85,
+ R_PPC_GOT_TLSLD16_HA = 86,
+ R_PPC_GOT_TPREL16 = 87,
+ R_PPC_GOT_TPREL16_LO = 88,
+ R_PPC_GOT_TPREL16_HI = 89,
+ R_PPC_GOT_TPREL16_HA = 90,
+ R_PPC_GOT_DTPREL16 = 91,
+ R_PPC_GOT_DTPREL16_LO = 92,
+ R_PPC_GOT_DTPREL16_HI = 93,
+ R_PPC_GOT_DTPREL16_HA = 94,
+ R_PPC_TLSGD = 95,
+ R_PPC_TLSLD = 96,
+ R_PPC_REL16 = 249,
+ R_PPC_REL16_LO = 250,
+ R_PPC_REL16_HI = 251,
+ R_PPC_REL16_HA = 252
};
// ELF Relocation types for PPC64
@@ -481,32 +489,74 @@ enum {
R_PPC64_REL14 = 11,
R_PPC64_REL14_BRTAKEN = 12,
R_PPC64_REL14_BRNTAKEN = 13,
+ R_PPC64_GOT16 = 14,
+ R_PPC64_GOT16_LO = 15,
+ R_PPC64_GOT16_HI = 16,
+ R_PPC64_GOT16_HA = 17,
R_PPC64_REL32 = 26,
R_PPC64_ADDR64 = 38,
R_PPC64_ADDR16_HIGHER = 39,
+ R_PPC64_ADDR16_HIGHERA = 40,
R_PPC64_ADDR16_HIGHEST = 41,
+ R_PPC64_ADDR16_HIGHESTA = 42,
R_PPC64_REL64 = 44,
R_PPC64_TOC16 = 47,
R_PPC64_TOC16_LO = 48,
+ R_PPC64_TOC16_HI = 49,
R_PPC64_TOC16_HA = 50,
R_PPC64_TOC = 51,
R_PPC64_ADDR16_DS = 56,
R_PPC64_ADDR16_LO_DS = 57,
+ R_PPC64_GOT16_DS = 58,
+ R_PPC64_GOT16_LO_DS = 59,
R_PPC64_TOC16_DS = 63,
R_PPC64_TOC16_LO_DS = 64,
R_PPC64_TLS = 67,
+ R_PPC64_DTPMOD64 = 68,
+ R_PPC64_TPREL16 = 69,
R_PPC64_TPREL16_LO = 70,
+ R_PPC64_TPREL16_HI = 71,
R_PPC64_TPREL16_HA = 72,
+ R_PPC64_TPREL64 = 73,
+ R_PPC64_DTPREL16 = 74,
R_PPC64_DTPREL16_LO = 75,
+ R_PPC64_DTPREL16_HI = 76,
R_PPC64_DTPREL16_HA = 77,
+ R_PPC64_DTPREL64 = 78,
+ R_PPC64_GOT_TLSGD16 = 79,
R_PPC64_GOT_TLSGD16_LO = 80,
+ R_PPC64_GOT_TLSGD16_HI = 81,
R_PPC64_GOT_TLSGD16_HA = 82,
+ R_PPC64_GOT_TLSLD16 = 83,
R_PPC64_GOT_TLSLD16_LO = 84,
+ R_PPC64_GOT_TLSLD16_HI = 85,
R_PPC64_GOT_TLSLD16_HA = 86,
+ R_PPC64_GOT_TPREL16_DS = 87,
R_PPC64_GOT_TPREL16_LO_DS = 88,
+ R_PPC64_GOT_TPREL16_HI = 89,
R_PPC64_GOT_TPREL16_HA = 90,
+ R_PPC64_GOT_DTPREL16_DS = 91,
+ R_PPC64_GOT_DTPREL16_LO_DS = 92,
+ R_PPC64_GOT_DTPREL16_HI = 93,
+ R_PPC64_GOT_DTPREL16_HA = 94,
+ R_PPC64_TPREL16_DS = 95,
+ R_PPC64_TPREL16_LO_DS = 96,
+ R_PPC64_TPREL16_HIGHER = 97,
+ R_PPC64_TPREL16_HIGHERA = 98,
+ R_PPC64_TPREL16_HIGHEST = 99,
+ R_PPC64_TPREL16_HIGHESTA = 100,
+ R_PPC64_DTPREL16_DS = 101,
+ R_PPC64_DTPREL16_LO_DS = 102,
+ R_PPC64_DTPREL16_HIGHER = 103,
+ R_PPC64_DTPREL16_HIGHERA = 104,
+ R_PPC64_DTPREL16_HIGHEST = 105,
+ R_PPC64_DTPREL16_HIGHESTA = 106,
R_PPC64_TLSGD = 107,
- R_PPC64_TLSLD = 108
+ R_PPC64_TLSLD = 108,
+ R_PPC64_REL16 = 249,
+ R_PPC64_REL16_LO = 250,
+ R_PPC64_REL16_HI = 251,
+ R_PPC64_REL16_HA = 252
};
// ELF Relocation types for AArch64
@@ -790,6 +840,8 @@ enum {
R_MIPS_PC16 = 10,
R_MIPS_CALL16 = 11,
R_MIPS_GPREL32 = 12,
+ R_MIPS_UNUSED1 = 13,
+ R_MIPS_UNUSED2 = 14,
R_MIPS_SHIFT5 = 16,
R_MIPS_SHIFT6 = 17,
R_MIPS_64 = 18,
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index 570b34b..c130b47 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -33,6 +33,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TimeValue.h"
#include "llvm/Support/system_error.h"
#include <ctime>
#include <iterator>
@@ -72,22 +73,6 @@ private:
int v_;
};
-/// copy_option - An "enum class" enumeration of copy semantics for copy
-/// operations.
-struct copy_option {
- enum _ {
- fail_if_exists,
- overwrite_if_exists
- };
-
- copy_option(_ v) : v_(v) {}
- explicit copy_option(int v) : v_(_(v)) {}
- operator int() const {return v_;}
-
-private:
- int v_;
-};
-
/// space_info - Self explanatory.
struct space_info {
uint64_t capacity;
@@ -95,30 +80,28 @@ struct space_info {
uint64_t available;
};
-
enum perms {
- no_perms = 0,
- owner_read = 0400,
- owner_write = 0200,
- owner_exe = 0100,
- owner_all = owner_read | owner_write | owner_exe,
- group_read = 040,
- group_write = 020,
- group_exe = 010,
- group_all = group_read | group_write | group_exe,
- others_read = 04,
- others_write = 02,
- others_exe = 01,
- others_all = others_read | others_write | others_exe,
- all_all = owner_all | group_all | others_all,
- set_uid_on_exe = 04000,
- set_gid_on_exe = 02000,
- sticky_bit = 01000,
- perms_mask = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit,
- perms_not_known = 0xFFFF,
- add_perms = 0x1000,
- remove_perms = 0x2000,
- symlink_perms = 0x4000
+ no_perms = 0,
+ owner_read = 0400,
+ owner_write = 0200,
+ owner_exe = 0100,
+ owner_all = owner_read | owner_write | owner_exe,
+ group_read = 040,
+ group_write = 020,
+ group_exe = 010,
+ group_all = group_read | group_write | group_exe,
+ others_read = 04,
+ others_write = 02,
+ others_exe = 01,
+ others_all = others_read | others_write | others_exe,
+ all_read = owner_read | group_read | others_read,
+ all_write = owner_write | group_write | others_write,
+ all_exe = owner_exe | group_exe | others_exe,
+ all_all = owner_all | group_all | others_all,
+ set_uid_on_exe = 04000,
+ set_gid_on_exe = 02000,
+ sticky_bit = 01000,
+ perms_not_known = 0xFFFF
};
// Helper functions so that you can use & and | to manipulate perms bits:
@@ -142,8 +125,25 @@ inline perms operator~(perms x) {
return static_cast<perms>(~static_cast<unsigned short>(x));
}
+class UniqueID {
+ uint64_t Device;
+ uint64_t File;
+
+public:
+ UniqueID() {}
+ UniqueID(uint64_t Device, uint64_t File) : Device(Device), File(File) {}
+ bool operator==(const UniqueID &Other) const {
+ return Device == Other.Device && File == Other.File;
+ }
+ bool operator!=(const UniqueID &Other) const { return !(*this == Other); }
+ bool operator<(const UniqueID &Other) const {
+ return Device < Other.Device ||
+ (Device == Other.Device && File < Other.File);
+ }
+ uint64_t getDevice() const { return Device; }
+ uint64_t getFile() const { return File; }
+};
-
/// file_status - Represents the result of a call to stat and friends. It has
/// a platform specific member to store the result.
class file_status
@@ -151,6 +151,10 @@ class file_status
#if defined(LLVM_ON_UNIX)
dev_t fs_st_dev;
ino_t fs_st_ino;
+ time_t fs_st_mtime;
+ uid_t fs_st_uid;
+ gid_t fs_st_gid;
+ off_t fs_st_size;
#elif defined (LLVM_ON_WIN32)
uint32_t LastWriteTimeHigh;
uint32_t LastWriteTimeLow;
@@ -161,18 +165,51 @@ class file_status
uint32_t FileIndexLow;
#endif
friend bool equivalent(file_status A, file_status B);
- friend error_code status(const Twine &path, file_status &result);
file_type Type;
perms Perms;
public:
- explicit file_status(file_type v=file_type::status_error,
- perms prms=perms_not_known)
- : Type(v), Perms(prms) {}
+ file_status() : Type(file_type::status_error) {}
+ file_status(file_type Type) : Type(Type) {}
+
+ #if defined(LLVM_ON_UNIX)
+ file_status(file_type Type, perms Perms, dev_t Dev, ino_t Ino, time_t MTime,
+ uid_t UID, gid_t GID, off_t Size)
+ : fs_st_dev(Dev), fs_st_ino(Ino), fs_st_mtime(MTime), fs_st_uid(UID),
+ fs_st_gid(GID), fs_st_size(Size), Type(Type), Perms(Perms) {}
+ #elif defined(LLVM_ON_WIN32)
+ file_status(file_type Type, uint32_t LastWriteTimeHigh,
+ uint32_t LastWriteTimeLow, uint32_t VolumeSerialNumber,
+ uint32_t FileSizeHigh, uint32_t FileSizeLow,
+ uint32_t FileIndexHigh, uint32_t FileIndexLow)
+ : LastWriteTimeHigh(LastWriteTimeHigh),
+ LastWriteTimeLow(LastWriteTimeLow),
+ VolumeSerialNumber(VolumeSerialNumber), FileSizeHigh(FileSizeHigh),
+ FileSizeLow(FileSizeLow), FileIndexHigh(FileIndexHigh),
+ FileIndexLow(FileIndexLow), Type(Type), Perms(perms_not_known) {}
+ #endif
// getters
file_type type() const { return Type; }
perms permissions() const { return Perms; }
-
+ TimeValue getLastModificationTime() const;
+ UniqueID getUniqueID() const;
+
+ #if defined(LLVM_ON_UNIX)
+ uint32_t getUser() const { return fs_st_uid; }
+ uint32_t getGroup() const { return fs_st_gid; }
+ uint64_t getSize() const { return fs_st_size; }
+ #elif defined (LLVM_ON_WIN32)
+ uint32_t getUser() const {
+ return 9999; // Not applicable to Windows, so...
+ }
+ uint32_t getGroup() const {
+ return 9999; // Not applicable to Windows, so...
+ }
+ uint64_t getSize() const {
+ return (uint64_t(FileSizeHigh) << 32) + FileSizeLow;
+ }
+ #endif
+
// setters
void type(file_type v) { Type = v; }
void permissions(perms p) { Perms = p; }
@@ -199,6 +236,7 @@ struct file_magic {
macho_bundle, ///< Mach-O Bundle file
macho_dynamically_linked_shared_lib_stub, ///< Mach-O Shared lib stub
macho_dsym_companion, ///< Mach-O dSYM companion file
+ macho_universal_binary, ///< Mach-O universal binary
coff_object, ///< COFF object file
pecoff_executable ///< PECOFF executable file
};
@@ -232,18 +270,6 @@ private:
/// platform specific error_code.
error_code make_absolute(SmallVectorImpl<char> &path);
-/// @brief Copy the file at \a from to the path \a to.
-///
-/// @param from The path to copy the file from.
-/// @param to The path to copy the file to.
-/// @param copt Behavior if \a to already exists.
-/// @returns errc::success if the file has been successfully copied.
-/// errc::file_exists if \a to already exists and \a copt ==
-/// copy_option::fail_if_exists. Otherwise a platform specific
-/// error_code.
-error_code copy_file(const Twine &from, const Twine &to,
- copy_option copt = copy_option::fail_if_exists);
-
/// @brief Create all the non-existent directories in path.
///
/// @param path Directories to create.
@@ -252,6 +278,13 @@ error_code copy_file(const Twine &from, const Twine &to,
/// otherwise a platform specific error_code.
error_code create_directories(const Twine &path, bool &existed);
+/// @brief Convenience function for clients that don't need to know if the
+/// directory existed or not.
+inline error_code create_directories(const Twine &Path) {
+ bool Existed;
+ return create_directories(Path, Existed);
+}
+
/// @brief Create the directory in path.
///
/// @param path Directory to create.
@@ -260,6 +293,13 @@ error_code create_directories(const Twine &path, bool &existed);
/// otherwise a platform specific error_code.
error_code create_directory(const Twine &path, bool &existed);
+/// @brief Convenience function for clients that don't need to know if the
+/// directory existed or not.
+inline error_code create_directory(const Twine &Path) {
+ bool Existed;
+ return create_directory(Path, Existed);
+}
+
/// @brief Create a hard link from \a from to \a to.
///
/// @param to The path to hard link to.
@@ -292,6 +332,13 @@ error_code current_path(SmallVectorImpl<char> &result);
/// successfully set, otherwise a platform specific error_code.
error_code remove(const Twine &path, bool &existed);
+/// @brief Convenience function for clients that don't need to know if the file
+/// existed or not.
+inline error_code remove(const Twine &Path) {
+ bool Existed;
+ return remove(Path, Existed);
+}
+
/// @brief Recursively remove all files below \a path, then \a path. Files are
/// removed as if by POSIX remove().
///
@@ -301,6 +348,13 @@ error_code remove(const Twine &path, bool &existed);
/// successfully set, otherwise a platform specific error_code.
error_code remove_all(const Twine &path, uint32_t &num_removed);
+/// @brief Convenience function for clients that don't need to know how many
+/// files were removed.
+inline error_code remove_all(const Twine &Path) {
+ uint32_t Removed;
+ return remove_all(Path, Removed);
+}
+
/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
///
/// @param from The path to rename from.
@@ -342,6 +396,18 @@ inline bool exists(const Twine &path) {
return !exists(path, result) && result;
}
+/// @brief Can we execute this file?
+///
+/// @param Path Input path.
+/// @returns True if we can execute it, false otherwise.
+bool can_execute(const Twine &Path);
+
+/// @brief Can we write this file?
+///
+/// @param Path Input path.
+/// @returns True if we can write to it, false otherwise.
+bool can_write(const Twine &Path);
+
/// @brief Do file_status's represent the same thing?
///
/// @param A Input file_status.
@@ -372,14 +438,6 @@ inline bool equivalent(const Twine &A, const Twine &B) {
return !equivalent(A, B, result) && result;
}
-/// @brief Get file size.
-///
-/// @param path Input path.
-/// @param result Set to the size of the file in \a path.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code file_size(const Twine &path, uint64_t &result);
-
/// @brief Does status represent a directory?
///
/// @param status A file_status previously returned from status.
@@ -395,6 +453,13 @@ bool is_directory(file_status status);
/// platform specific error_code.
error_code is_directory(const Twine &path, bool &result);
+/// @brief Simpler version of is_directory for clients that don't need to
+/// differentiate between an error and false.
+inline bool is_directory(const Twine &Path) {
+ bool Result;
+ return !is_directory(Path, Result) && Result;
+}
+
/// @brief Does status represent a regular file?
///
/// @param status A file_status previously returned from status.
@@ -410,6 +475,15 @@ bool is_regular_file(file_status status);
/// platform specific error_code.
error_code is_regular_file(const Twine &path, bool &result);
+/// @brief Simpler version of is_regular_file for clients that don't need to
+/// differentiate between an error and false.
+inline bool is_regular_file(const Twine &Path) {
+ bool Result;
+ if (is_regular_file(Path, Result))
+ return false;
+ return Result;
+}
+
/// @brief Does this status represent something that exists but is not a
/// directory, regular file, or symlink?
///
@@ -451,12 +525,25 @@ error_code is_symlink(const Twine &path, bool &result);
/// platform specific error_code.
error_code status(const Twine &path, file_status &result);
-/// @brief Modifies permission bits on a file
+/// @brief A version for when a file descriptor is already available.
+error_code status(int FD, file_status &Result);
+
+/// @brief Get file size.
///
-/// @param path Input path.
-/// @returns errc::success if permissions have been changed, otherwise a
+/// @param Path Input path.
+/// @param Result Set to the size of the file in \a Path.
+/// @returns errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
-error_code permissions(const Twine &path, perms prms);
+inline error_code file_size(const Twine &Path, uint64_t &Result) {
+ file_status Status;
+ error_code EC = status(Path, Status);
+ if (EC)
+ return EC;
+ Result = Status.getSize();
+ return error_code::success();
+}
+
+error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
/// @brief Is status available?
///
@@ -472,28 +559,84 @@ bool status_known(file_status s);
/// platform specific error_code.
error_code status_known(const Twine &path, bool &result);
-/// @brief Generate a unique path and open it as a file.
+/// @brief Create a uniquely named file.
///
/// Generates a unique path suitable for a temporary file and then opens it as a
/// file. The name is based on \a model with '%' replaced by a random char in
/// [0-9a-f]. If \a model is not an absolute path, a suitable temporary
/// directory will be prepended.
///
+/// Example: clang-%%-%%-%%-%%-%%.s => clang-a0-b1-c2-d3-e4.s
+///
/// This is an atomic operation. Either the file is created and opened, or the
/// file system is left untouched.
///
-/// clang-%%-%%-%%-%%-%%.s => /tmp/clang-a0-b1-c2-d3-e4.s
+/// The intendend use is for files that are to be kept, possibly after
+/// renaming them. For example, when running 'clang -c foo.o', the file can
+/// be first created as foo-abc123.o and then renamed.
///
-/// @param model Name to base unique path off of.
-/// @param result_fd Set to the opened file's file descriptor.
-/// @param result_path Set to the opened file's absolute path.
-/// @param makeAbsolute If true and \a model is not an absolute path, a temp
-/// directory will be prepended.
-/// @returns errc::success if result_{fd,path} have been successfully set,
+/// @param Model Name to base unique path off of.
+/// @param ResultFD Set to the opened file's file descriptor.
+/// @param ResultPath Set to the opened file's absolute path.
+/// @returns errc::success if Result{FD,Path} have been successfully set,
/// otherwise a platform specific error_code.
-error_code unique_file(const Twine &model, int &result_fd,
- SmallVectorImpl<char> &result_path,
- bool makeAbsolute = true, unsigned mode = 0600);
+error_code createUniqueFile(const Twine &Model, int &ResultFD,
+ SmallVectorImpl<char> &ResultPath,
+ unsigned Mode = all_read | all_write);
+
+/// @brief Simpler version for clients that don't want an open file.
+error_code createUniqueFile(const Twine &Model,
+ SmallVectorImpl<char> &ResultPath);
+
+/// @brief Create a file in the system temporary directory.
+///
+/// The filename is of the form prefix-random_chars.suffix. Since the directory
+/// is not know to the caller, Prefix and Suffix cannot have path separators.
+/// The files are created with mode 0600.
+///
+/// This should be used for things like a temporary .s that is removed after
+/// running the assembler.
+error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+ int &ResultFD,
+ SmallVectorImpl<char> &ResultPath);
+
+/// @brief Simpler version for clients that don't want an open file.
+error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+ SmallVectorImpl<char> &ResultPath);
+
+error_code createUniqueDirectory(const Twine &Prefix,
+ SmallVectorImpl<char> &ResultPath);
+
+enum OpenFlags {
+ F_None = 0,
+
+ /// F_Excl - When opening a file, this flag makes raw_fd_ostream
+ /// report an error if the file already exists.
+ F_Excl = 1,
+
+ /// F_Append - When opening a file, if it already exists append to the
+ /// existing file instead of returning an error. This may not be specified
+ /// with F_Excl.
+ F_Append = 2,
+
+ /// F_Binary - The file should be opened in binary mode on platforms that
+ /// make this distinction.
+ F_Binary = 4
+};
+
+inline OpenFlags operator|(OpenFlags A, OpenFlags B) {
+ return OpenFlags(unsigned(A) | unsigned(B));
+}
+
+inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) {
+ A = A | B;
+ return A;
+}
+
+error_code openFileForWrite(const Twine &Name, int &ResultFD, OpenFlags Flags,
+ unsigned Mode = 0666);
+
+error_code openFileForRead(const Twine &Name, int &ResultFD);
/// @brief Canonicalize path.
///
@@ -538,43 +681,7 @@ file_magic identify_magic(StringRef magic);
/// platform specific error_code.
error_code identify_magic(const Twine &path, file_magic &result);
-/// @brief Get library paths the system linker uses.
-///
-/// @param result Set to the list of system library paths.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result);
-
-/// @brief Get bitcode library paths the system linker uses
-/// + LLVM_LIB_SEARCH_PATH + LLVM_LIBDIR.
-///
-/// @param result Set to the list of bitcode library paths.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result);
-
-/// @brief Find a library.
-///
-/// Find the path to a library using its short name. Use the system
-/// dependent library paths to locate the library.
-///
-/// c => /usr/lib/libc.so
-///
-/// @param short_name Library name one would give to the system linker.
-/// @param result Set to the absolute path \a short_name represents.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
-
-/// @brief Get absolute path of main executable.
-///
-/// @param argv0 The program name as it was spelled on the command line.
-/// @param MainAddr Address of some symbol in the executable (not in a library).
-/// @param result Set to the absolute path of the current executable.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code GetMainExecutable(const char *argv0, void *MainAddr,
- SmallVectorImpl<char> &result);
+error_code getUniqueID(const Twine Path, UniqueID &Result);
/// This class represents a memory mapped file. It is based on
/// boost::iostreams::mapped_file.
@@ -648,7 +755,7 @@ public:
char *data() const;
/// Get a const view of the data. Modifying this memory has undefined
- /// behaivor.
+ /// behavior.
const char *const_data() const;
/// \returns The minimum alignment offset must be.
@@ -679,7 +786,10 @@ error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,
/// platform specific error_code.
error_code unmap_file_pages(void *base, size_t size);
-
+/// Return the path to the main executable, given the value of argv[0] from
+/// program startup and the address of main itself. In extremis, this function
+/// may fail and return an empty path.
+std::string getMainExecutable(const char *argv0, void *MainExecAddr);
/// @}
/// @name Iterators
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
index c6feb9f..79c59e4 100644
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -17,7 +17,6 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/PathV1.h"
namespace llvm {
@@ -28,8 +27,8 @@ namespace llvm {
/// option, it will set the string to an error message if an error occurs, or
/// if the files are different.
///
- int DiffFilesWithTolerance(const sys::PathWithStatus &FileA,
- const sys::PathWithStatus &FileB,
+ int DiffFilesWithTolerance(StringRef FileA,
+ StringRef FileB,
double AbsTol, double RelTol,
std::string *Error = 0);
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index e867fae..62547dd 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -26,7 +26,6 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/DOTGraphTraits.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/PathV1.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <vector>
@@ -51,7 +50,8 @@ namespace GraphProgram {
};
}
-void DisplayGraph(const sys::Path& Filename, bool wait=true, GraphProgram::Name program = GraphProgram::DOT);
+void DisplayGraph(StringRef Filename, bool wait = true,
+ GraphProgram::Name program = GraphProgram::DOT);
template<typename GraphType>
class GraphWriter {
@@ -319,34 +319,23 @@ raw_ostream &WriteGraph(raw_ostream &O, const GraphType &G,
return O;
}
-template<typename GraphType>
-sys::Path WriteGraph(const GraphType &G, const Twine &Name,
- bool ShortNames = false, const Twine &Title = "") {
- std::string ErrMsg;
- sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
- if (Filename.isEmpty()) {
- errs() << "Error: " << ErrMsg << "\n";
- return Filename;
- }
- Filename.appendComponent((Name + ".dot").str());
- if (Filename.makeUnique(true,&ErrMsg)) {
- errs() << "Error: " << ErrMsg << "\n";
- return sys::Path();
- }
+std::string createGraphFilename(const Twine &Name, int &FD);
- errs() << "Writing '" << Filename.str() << "'... ";
+template <typename GraphType>
+std::string WriteGraph(const GraphType &G, const Twine &Name,
+ bool ShortNames = false, const Twine &Title = "") {
+ int FD;
+ std::string Filename = createGraphFilename(Name, FD);
+ raw_fd_ostream O(FD, /*shouldClose=*/ true);
- std::string ErrorInfo;
- raw_fd_ostream O(Filename.c_str(), ErrorInfo);
-
- if (ErrorInfo.empty()) {
- llvm::WriteGraph(O, G, ShortNames, Title);
- errs() << " done. \n";
- } else {
- errs() << "error opening file '" << Filename.str() << "' for writing!\n";
- Filename.clear();
+ if (FD == -1) {
+ errs() << "error opening file '" << Filename << "' for writing!\n";
+ return "";
}
+ llvm::WriteGraph(O, G, ShortNames, Title);
+ errs() << " done. \n";
+
return Filename;
}
@@ -357,9 +346,9 @@ template<typename GraphType>
void ViewGraph(const GraphType &G, const Twine &Name,
bool ShortNames = false, const Twine &Title = "",
GraphProgram::Name Program = GraphProgram::DOT) {
- sys::Path Filename = llvm::WriteGraph(G, Name, ShortNames, Title);
+ std::string Filename = llvm::WriteGraph(G, Name, ShortNames, Title);
- if (Filename.isEmpty())
+ if (Filename.empty())
return;
DisplayGraph(Filename, true, Program);
diff --git a/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h
index ce34d78..64b79ee 100644
--- a/include/llvm/Support/IntegersSubset.h
+++ b/include/llvm/Support/IntegersSubset.h
@@ -361,7 +361,7 @@ public:
FlatCollection.end(),
CheckingVal) != FlatCollection.end();
- for (unsigned i = 0, e = getNumItems(); i < e; ++i) {
+ for (size_t i = 0, e = getNumItems(); i < e; ++i) {
if (RangeLinks[i].first == RangeLinks[i].second) {
if (*RangeLinks[i].first == CheckingVal)
return true;
@@ -382,7 +382,7 @@ public:
}
/// Return number of items (ranges) stored in set.
- unsigned getNumItems() const {
+ size_t getNumItems() const {
return RangeLinks.size();
}
@@ -409,7 +409,7 @@ public:
/// for range [<0>, <1>, <5>] the size will 3
unsigned getSize() const {
APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
- for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
+ for (size_t i = 0, e = getNumItems(); i != e; ++i) {
const APInt Low = getItem(i).getLow();
const APInt High = getItem(i).getHigh();
APInt S = High - Low + 1;
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
index 802b4f3..3d73792 100644
--- a/include/llvm/Support/LEB128.h
+++ b/include/llvm/Support/LEB128.h
@@ -20,7 +20,7 @@
namespace llvm {
/// Utility function to encode a SLEB128 value to an output stream.
-static inline void encodeSLEB128(int64_t Value, raw_ostream &OS) {
+inline void encodeSLEB128(int64_t Value, raw_ostream &OS) {
bool More;
do {
uint8_t Byte = Value & 0x7f;
@@ -29,19 +29,19 @@ static inline void encodeSLEB128(int64_t Value, raw_ostream &OS) {
More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
((Value == -1) && ((Byte & 0x40) != 0))));
if (More)
- Byte |= 0x80; // Mark this byte that that more bytes will follow.
+ Byte |= 0x80; // Mark this byte to show that more bytes will follow.
OS << char(Byte);
} while (More);
}
/// Utility function to encode a ULEB128 value to an output stream.
-static inline void encodeULEB128(uint64_t Value, raw_ostream &OS,
- unsigned Padding = 0) {
+inline void encodeULEB128(uint64_t Value, raw_ostream &OS,
+ unsigned Padding = 0) {
do {
uint8_t Byte = Value & 0x7f;
Value >>= 7;
if (Value != 0 || Padding != 0)
- Byte |= 0x80; // Mark this byte that that more bytes will follow.
+ Byte |= 0x80; // Mark this byte to show that more bytes will follow.
OS << char(Byte);
} while (Value != 0);
@@ -55,14 +55,14 @@ static inline void encodeULEB128(uint64_t Value, raw_ostream &OS,
/// Utility function to encode a ULEB128 value to a buffer. Returns
/// the length in bytes of the encoded value.
-static inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
- unsigned Padding = 0) {
+inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
+ unsigned Padding = 0) {
uint8_t *orig_p = p;
do {
uint8_t Byte = Value & 0x7f;
Value >>= 7;
if (Value != 0 || Padding != 0)
- Byte |= 0x80; // Mark this byte that that more bytes will follow.
+ Byte |= 0x80; // Mark this byte to show that more bytes will follow.
*p++ = Byte;
} while (Value != 0);
@@ -77,7 +77,7 @@ static inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
/// Utility function to decode a ULEB128 value.
-static inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) {
+inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) {
const uint8_t *orig_p = p;
uint64_t Value = 0;
unsigned Shift = 0;
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index a65bfbc..00c6ad7 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -45,7 +45,9 @@ enum ZeroBehavior {
template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed, std::size_t>::type
-countTrailingZeros(T Val, ZeroBehavior /*ZB*/ = ZB_Width) {
+countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
+ (void)ZB;
+
if (!Val)
return std::numeric_limits<T>::digits;
if (Val & 0x1)
@@ -78,7 +80,7 @@ inline std::size_t countTrailingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) {
if (ZB != ZB_Undefined && Val == 0)
return 32;
-#if __GNUC__ >= 4
+#if __has_builtin(__builtin_ctz) || __GNUC_PREREQ(4, 0)
return __builtin_ctz(Val);
#elif _MSC_VER
unsigned long Index;
@@ -93,7 +95,7 @@ inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
if (ZB != ZB_Undefined && Val == 0)
return 64;
-#if __GNUC__ >= 4
+#if __has_builtin(__builtin_ctzll) || __GNUC_PREREQ(4, 0)
return __builtin_ctzll(Val);
#elif _MSC_VER
unsigned long Index;
@@ -114,7 +116,9 @@ inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_integer &&
!std::numeric_limits<T>::is_signed, std::size_t>::type
-countLeadingZeros(T Val, ZeroBehavior /*ZB*/ = ZB_Width) {
+countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
+ (void)ZB;
+
if (!Val)
return std::numeric_limits<T>::digits;
@@ -142,7 +146,7 @@ inline std::size_t countLeadingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) {
if (ZB != ZB_Undefined && Val == 0)
return 32;
-#if __GNUC__ >= 4
+#if __has_builtin(__builtin_clz) || __GNUC_PREREQ(4, 0)
return __builtin_clz(Val);
#elif _MSC_VER
unsigned long Index;
@@ -157,7 +161,7 @@ inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
if (ZB != ZB_Undefined && Val == 0)
return 64;
-#if __GNUC__ >= 4
+#if __has_builtin(__builtin_clzll) || __GNUC_PREREQ(4, 0)
return __builtin_clzll(Val);
#elif _MSC_VER
unsigned long Index;
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index 0cce726..4f28da4 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -74,13 +74,18 @@ public:
int64_t FileSize = -1,
bool RequiresNullTerminator = true);
- /// getOpenFile - Given an already-open file descriptor, read the file and
- /// return a MemoryBuffer.
+ /// Given an already-open file descriptor, map some slice of it into a
+ /// MemoryBuffer. The slice is specified by an \p Offset and \p MapSize.
+ /// Since this is in the middle of a file, the buffer is not null terminated.
+ static error_code getOpenFileSlice(int FD, const char *Filename,
+ OwningPtr<MemoryBuffer> &Result,
+ uint64_t MapSize, int64_t Offset);
+
+ /// Given an already-open file descriptor, read the file and return a
+ /// MemoryBuffer.
static error_code getOpenFile(int FD, const char *Filename,
- OwningPtr<MemoryBuffer> &result,
- uint64_t FileSize = -1,
- uint64_t MapSize = -1,
- int64_t Offset = 0,
+ OwningPtr<MemoryBuffer> &Result,
+ uint64_t FileSize,
bool RequiresNullTerminator = true);
/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
@@ -119,11 +124,7 @@ public:
static error_code getFileOrSTDIN(StringRef Filename,
OwningPtr<MemoryBuffer> &result,
int64_t FileSize = -1);
- static error_code getFileOrSTDIN(const char *Filename,
- OwningPtr<MemoryBuffer> &result,
- int64_t FileSize = -1);
-
-
+
//===--------------------------------------------------------------------===//
// Provided for performance analysis.
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h
index a70498a..f9a65e5 100644
--- a/include/llvm/Support/Path.h
+++ b/include/llvm/Support/Path.h
@@ -111,6 +111,7 @@ inline reverse_iterator rend(StringRef path) {
/// @code
/// directory/filename.cpp => directory/
/// directory/ => directory
+/// filename.cpp => <empty>
/// / => /
/// @endcode
///
diff --git a/include/llvm/Support/PathV1.h b/include/llvm/Support/PathV1.h
deleted file mode 100644
index eaf2550..0000000
--- a/include/llvm/Support/PathV1.h
+++ /dev/null
@@ -1,557 +0,0 @@
-//===- llvm/Support/PathV1.h - Path Operating System Concept ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys::Path class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_PATHV1_H
-#define LLVM_SUPPORT_PATHV1_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/TimeValue.h"
-#include <set>
-#include <string>
-#include <vector>
-
-#define LLVM_PATH_DEPRECATED_MSG(replacement) \
- "PathV1 has been deprecated and will be removed as soon as all LLVM and" \
- " Clang clients have been moved over to PathV2. Please use `" #replacement \
- "` from PathV2 instead."
-
-namespace llvm {
-namespace sys {
-
- /// This structure provides basic file system information about a file. It
- /// is patterned after the stat(2) Unix operating system call but made
- /// platform independent and eliminates many of the unix-specific fields.
- /// However, to support llvm-ar, the mode, user, and group fields are
- /// retained. These pertain to unix security and may not have a meaningful
- /// value on non-Unix platforms. However, the other fields should
- /// always be applicable on all platforms. The structure is filled in by
- /// the PathWithStatus class.
- /// @brief File status structure
- class FileStatus {
- public:
- uint64_t fileSize; ///< Size of the file in bytes
- TimeValue modTime; ///< Time of file's modification
- uint32_t mode; ///< Mode of the file, if applicable
- uint32_t user; ///< User ID of owner, if applicable
- uint32_t group; ///< Group ID of owner, if applicable
- uint64_t uniqueID; ///< A number to uniquely ID this file
- bool isDir : 1; ///< True if this is a directory.
- bool isFile : 1; ///< True if this is a file.
-
- FileStatus() : fileSize(0), modTime(0,0), mode(0777), user(999),
- group(999), uniqueID(0), isDir(false), isFile(false) { }
-
- TimeValue getTimestamp() const { return modTime; }
- uint64_t getSize() const { return fileSize; }
- uint32_t getMode() const { return mode; }
- uint32_t getUser() const { return user; }
- uint32_t getGroup() const { return group; }
- uint64_t getUniqueID() const { return uniqueID; }
- };
-
- /// This class provides an abstraction for the path to a file or directory
- /// in the operating system's filesystem and provides various basic operations
- /// on it. Note that this class only represents the name of a path to a file
- /// or directory which may or may not be valid for a given machine's file
- /// system. The class is patterned after the java.io.File class with various
- /// extensions and several omissions (not relevant to LLVM). A Path object
- /// ensures that the path it encapsulates is syntactically valid for the
- /// operating system it is running on but does not ensure correctness for
- /// any particular file system. That is, a syntactically valid path might
- /// specify path components that do not exist in the file system and using
- /// such a Path to act on the file system could produce errors. There is one
- /// invalid Path value which is permitted: the empty path. The class should
- /// never allow a syntactically invalid non-empty path name to be assigned.
- /// Empty paths are required in order to indicate an error result in some
- /// situations. If the path is empty, the isValid operation will return
- /// false. All operations will fail if isValid is false. Operations that
- /// change the path will either return false if it would cause a syntactically
- /// invalid path name (in which case the Path object is left unchanged) or
- /// throw an std::string exception indicating the error. The methods are
- /// grouped into four basic categories: Path Accessors (provide information
- /// about the path without accessing disk), Disk Accessors (provide
- /// information about the underlying file or directory), Path Mutators
- /// (change the path information, not the disk), and Disk Mutators (change
- /// the disk file/directory referenced by the path). The Disk Mutator methods
- /// all have the word "disk" embedded in their method name to reinforce the
- /// notion that the operation modifies the file system.
- /// @since 1.4
- /// @brief An abstraction for operating system paths.
- class Path {
- /// @name Constructors
- /// @{
- public:
- /// Construct a path to a unique temporary directory that is created in
- /// a "standard" place for the operating system. The directory is
- /// guaranteed to be created on exit from this function. If the directory
- /// cannot be created, the function will throw an exception.
- /// @returns an invalid path (empty) on error
- /// @param ErrMsg Optional place for an error message if an error occurs
- /// @brief Construct a path to an new, unique, existing temporary
- /// directory.
- static Path GetTemporaryDirectory(std::string* ErrMsg = 0);
-
- /// Construct a path to the current directory for the current process.
- /// @returns The current working directory.
- /// @brief Returns the current working directory.
- static Path GetCurrentDirectory();
-
- /// Return the suffix commonly used on file names that contain an
- /// executable.
- /// @returns The executable file suffix for the current platform.
- /// @brief Return the executable file suffix.
- static StringRef GetEXESuffix();
-
- /// GetMainExecutable - Return the path to the main executable, given the
- /// value of argv[0] from program startup and the address of main itself.
- /// In extremis, this function may fail and return an empty path.
- static Path GetMainExecutable(const char *argv0, void *MainAddr);
-
- /// This is one of the very few ways in which a path can be constructed
- /// with a syntactically invalid name. The only *legal* invalid name is an
- /// empty one. Other invalid names are not permitted. Empty paths are
- /// provided so that they can be used to indicate null or error results in
- /// other lib/System functionality.
- /// @brief Construct an empty (and invalid) path.
- Path() : path() {}
- Path(const Path &that) : path(that.path) {}
-
- /// This constructor will accept a char* or std::string as a path. No
- /// checking is done on this path to determine if it is valid. To
- /// determine validity of the path, use the isValid method.
- /// @param p The path to assign.
- /// @brief Construct a Path from a string.
- explicit Path(StringRef p);
-
- /// This constructor will accept a character range as a path. No checking
- /// is done on this path to determine if it is valid. To determine
- /// validity of the path, use the isValid method.
- /// @param StrStart A pointer to the first character of the path name
- /// @param StrLen The length of the path name at StrStart
- /// @brief Construct a Path from a string.
- Path(const char *StrStart, unsigned StrLen);
-
- /// @}
- /// @name Operators
- /// @{
- public:
- /// Makes a copy of \p that to \p this.
- /// @returns \p this
- /// @brief Assignment Operator
- Path &operator=(const Path &that) {
- path = that.path;
- return *this;
- }
-
- /// Makes a copy of \p that to \p this.
- /// @param that A StringRef denoting the path
- /// @returns \p this
- /// @brief Assignment Operator
- Path &operator=(StringRef that);
-
- /// Compares \p this Path with \p that Path for equality.
- /// @returns true if \p this and \p that refer to the same thing.
- /// @brief Equality Operator
- bool operator==(const Path &that) const;
-
- /// Compares \p this Path with \p that Path for inequality.
- /// @returns true if \p this and \p that refer to different things.
- /// @brief Inequality Operator
- bool operator!=(const Path &that) const { return !(*this == that); }
-
- /// Determines if \p this Path is less than \p that Path. This is required
- /// so that Path objects can be placed into ordered collections (e.g.
- /// std::map). The comparison is done lexicographically as defined by
- /// the std::string::compare method.
- /// @returns true if \p this path is lexicographically less than \p that.
- /// @brief Less Than Operator
- bool operator<(const Path& that) const;
-
- /// @}
- /// @name Path Accessors
- /// @{
- public:
- /// This function will use an operating system specific algorithm to
- /// determine if the current value of \p this is a syntactically valid
- /// path name for the operating system. The path name does not need to
- /// exist, validity is simply syntactical. Empty paths are always invalid.
- /// @returns true iff the path name is syntactically legal for the
- /// host operating system.
- /// @brief Determine if a path is syntactically valid or not.
- bool isValid() const;
-
- /// This function determines if the contents of the path name are empty.
- /// That is, the path name has a zero length. This does NOT determine if
- /// if the file is empty. To get the length of the file itself, Use the
- /// PathWithStatus::getFileStatus() method and then the getSize() method
- /// on the returned FileStatus object.
- /// @returns true iff the path is empty.
- /// @brief Determines if the path name is empty (invalid).
- bool isEmpty() const { return path.empty(); }
-
-
-
- /// Obtain a 'C' string for the path name.
- /// @returns a 'C' string containing the path name.
- /// @brief Returns the path as a C string.
- const char *c_str() const { return path.c_str(); }
- const std::string &str() const { return path; }
-
-
- /// size - Return the length in bytes of this path name.
- size_t size() const { return path.size(); }
-
- /// empty - Returns true if the path is empty.
- unsigned empty() const { return path.empty(); }
-
- /// @}
- /// @name Disk Accessors
- /// @{
- public:
- /// This function determines if the path name in the object references an
- /// archive file by looking at its magic number.
- /// @returns true if the file starts with the magic number for an archive
- /// file.
- /// @brief Determine if the path references an archive file.
- bool isArchive() const;
-
- /// This function determines if the path name in the object references a
- /// native Dynamic Library (shared library, shared object) by looking at
- /// the file's magic number. The Path object must reference a file, not a
- /// directory.
- /// @returns true if the file starts with the magic number for a native
- /// shared library.
- /// @brief Determine if the path references a dynamic library.
- bool isDynamicLibrary() const;
-
- /// This function determines if the path name in the object references a
- /// native object file by looking at it's magic number. The term object
- /// file is defined as "an organized collection of separate, named
- /// sequences of binary data." This covers the obvious file formats such
- /// as COFF and ELF, but it also includes llvm ir bitcode, archives,
- /// libraries, etc...
- /// @returns true if the file starts with the magic number for an object
- /// file.
- /// @brief Determine if the path references an object file.
- bool isObjectFile() const;
-
- /// This function determines if the path name references an existing file
- /// or directory in the file system.
- /// @returns true if the pathname references an existing file or
- /// directory.
- /// @brief Determines if the path is a file or directory in
- /// the file system.
- LLVM_ATTRIBUTE_DEPRECATED(bool exists() const,
- LLVM_PATH_DEPRECATED_MSG(fs::exists));
-
- /// This function determines if the path name references an
- /// existing directory.
- /// @returns true if the pathname references an existing directory.
- /// @brief Determines if the path is a directory in the file system.
- LLVM_ATTRIBUTE_DEPRECATED(bool isDirectory() const,
- LLVM_PATH_DEPRECATED_MSG(fs::is_directory));
-
- /// This function determines if the path name references an
- /// existing symbolic link.
- /// @returns true if the pathname references an existing symlink.
- /// @brief Determines if the path is a symlink in the file system.
- LLVM_ATTRIBUTE_DEPRECATED(bool isSymLink() const,
- LLVM_PATH_DEPRECATED_MSG(fs::is_symlink));
-
- /// This function determines if the path name references a readable file
- /// or directory in the file system. This function checks for
- /// the existence and readability (by the current program) of the file
- /// or directory.
- /// @returns true if the pathname references a readable file.
- /// @brief Determines if the path is a readable file or directory
- /// in the file system.
- bool canRead() const;
-
- /// This function determines if the path name references a writable file
- /// or directory in the file system. This function checks for the
- /// existence and writability (by the current program) of the file or
- /// directory.
- /// @returns true if the pathname references a writable file.
- /// @brief Determines if the path is a writable file or directory
- /// in the file system.
- bool canWrite() const;
-
- /// This function checks that what we're trying to work only on a regular
- /// file. Check for things like /dev/null, any block special file, or
- /// other things that aren't "regular" regular files.
- /// @returns true if the file is S_ISREG.
- /// @brief Determines if the file is a regular file
- bool isRegularFile() const;
-
- /// This function determines if the path name references an executable
- /// file in the file system. This function checks for the existence and
- /// executability (by the current program) of the file.
- /// @returns true if the pathname references an executable file.
- /// @brief Determines if the path is an executable file in the file
- /// system.
- bool canExecute() const;
-
- /// This function builds a list of paths that are the names of the
- /// files and directories in a directory.
- /// @returns true if an error occurs, true otherwise
- /// @brief Build a list of directory's contents.
- bool getDirectoryContents(
- std::set<Path> &paths, ///< The resulting list of file & directory names
- std::string* ErrMsg ///< Optional place to return an error message.
- ) const;
-
- /// @}
- /// @name Path Mutators
- /// @{
- public:
- /// The path name is cleared and becomes empty. This is an invalid
- /// path name but is the *only* invalid path name. This is provided
- /// so that path objects can be used to indicate the lack of a
- /// valid path being found.
- /// @brief Make the path empty.
- void clear() { path.clear(); }
-
- /// This method sets the Path object to \p unverified_path. This can fail
- /// if the \p unverified_path does not pass the syntactic checks of the
- /// isValid() method. If verification fails, the Path object remains
- /// unchanged and false is returned. Otherwise true is returned and the
- /// Path object takes on the path value of \p unverified_path
- /// @returns true if the path was set, false otherwise.
- /// @param unverified_path The path to be set in Path object.
- /// @brief Set a full path from a StringRef
- bool set(StringRef unverified_path);
-
- /// One path component is removed from the Path. If only one component is
- /// present in the path, the Path object becomes empty. If the Path object
- /// is empty, no change is made.
- /// @returns false if the path component could not be removed.
- /// @brief Removes the last directory component of the Path.
- bool eraseComponent();
-
- /// The \p component is added to the end of the Path if it is a legal
- /// name for the operating system. A directory separator will be added if
- /// needed.
- /// @returns false if the path component could not be added.
- /// @brief Appends one path component to the Path.
- bool appendComponent(StringRef component);
-
- /// A period and the \p suffix are appended to the end of the pathname.
- /// When the \p suffix is empty, no action is performed.
- /// @brief Adds a period and the \p suffix to the end of the pathname.
- void appendSuffix(StringRef suffix);
-
- /// The suffix of the filename is erased. The suffix begins with and
- /// includes the last . character in the filename after the last directory
- /// separator and extends until the end of the name. If no . character is
- /// after the last directory separator, then the file name is left
- /// unchanged (i.e. it was already without a suffix) but the function
- /// returns false.
- /// @returns false if there was no suffix to remove, true otherwise.
- /// @brief Remove the suffix from a path name.
- bool eraseSuffix();
-
- /// The current Path name is made unique in the file system. Upon return,
- /// the Path will have been changed to make a unique file in the file
- /// system or it will not have been changed if the current path name is
- /// already unique.
- /// @throws std::string if an unrecoverable error occurs.
- /// @brief Make the current path name unique in the file system.
- bool makeUnique( bool reuse_current /*= true*/, std::string* ErrMsg );
-
- /// The current Path name is made absolute by prepending the
- /// current working directory if necessary.
- LLVM_ATTRIBUTE_DEPRECATED(
- void makeAbsolute(),
- LLVM_PATH_DEPRECATED_MSG(fs::make_absolute));
-
- /// @}
- /// @name Disk Mutators
- /// @{
- public:
- /// This method attempts to make the file referenced by the Path object
- /// available for reading so that the canRead() method will return true.
- /// @brief Make the file readable;
- bool makeReadableOnDisk(std::string* ErrMsg = 0);
-
- /// This method attempts to make the file referenced by the Path object
- /// available for writing so that the canWrite() method will return true.
- /// @brief Make the file writable;
- bool makeWriteableOnDisk(std::string* ErrMsg = 0);
-
- /// This method allows the last modified time stamp and permission bits
- /// to be set on the disk object referenced by the Path.
- /// @throws std::string if an error occurs.
- /// @returns true on error.
- /// @brief Set the status information.
- bool setStatusInfoOnDisk(const FileStatus &SI,
- std::string *ErrStr = 0) const;
-
- /// This method attempts to create a directory in the file system with the
- /// same name as the Path object. The \p create_parents parameter controls
- /// whether intermediate directories are created or not. if \p
- /// create_parents is true, then an attempt will be made to create all
- /// intermediate directories, as needed. If \p create_parents is false,
- /// then only the final directory component of the Path name will be
- /// created. The created directory will have no entries.
- /// @returns true if the directory could not be created, false otherwise
- /// @brief Create the directory this Path refers to.
- bool createDirectoryOnDisk(
- bool create_parents = false, ///< Determines whether non-existent
- ///< directory components other than the last one (the "parents")
- ///< are created or not.
- std::string* ErrMsg = 0 ///< Optional place to put error messages.
- );
-
- /// This is like createFile except that it creates a temporary file. A
- /// unique temporary file name is generated based on the contents of
- /// \p this before the call. The new name is assigned to \p this and the
- /// file is created. Note that this will both change the Path object
- /// *and* create the corresponding file. This function will ensure that
- /// the newly generated temporary file name is unique in the file system.
- /// @returns true if the file couldn't be created, false otherwise.
- /// @brief Create a unique temporary file
- bool createTemporaryFileOnDisk(
- bool reuse_current = false, ///< When set to true, this parameter
- ///< indicates that if the current file name does not exist then
- ///< it will be used without modification.
- std::string* ErrMsg = 0 ///< Optional place to put error messages
- );
-
- /// This method renames the file referenced by \p this as \p newName. The
- /// file referenced by \p this must exist. The file referenced by
- /// \p newName does not need to exist.
- /// @returns true on error, false otherwise
- /// @brief Rename one file as another.
- bool renamePathOnDisk(const Path& newName, std::string* ErrMsg);
-
- /// This method attempts to destroy the file or directory named by the
- /// last component of the Path. If the Path refers to a directory and the
- /// \p destroy_contents is false, an attempt will be made to remove just
- /// the directory (the final Path component). If \p destroy_contents is
- /// true, an attempt will be made to remove the entire contents of the
- /// directory, recursively. If the Path refers to a file, the
- /// \p destroy_contents parameter is ignored.
- /// @param destroy_contents Indicates whether the contents of a destroyed
- /// @param Err An optional string to receive an error message.
- /// directory should also be destroyed (recursively).
- /// @returns false if the file/directory was destroyed, true on error.
- /// @brief Removes the file or directory from the filesystem.
- bool eraseFromDisk(bool destroy_contents = false,
- std::string *Err = 0) const;
-
- /// @}
- /// @name Data
- /// @{
- protected:
- // Our win32 implementation relies on this string being mutable.
- mutable std::string path; ///< Storage for the path name.
-
-
- /// @}
- };
-
- /// This class is identical to Path class except it allows you to obtain the
- /// file status of the Path as well. The reason for the distinction is one of
- /// efficiency. First, the file status requires additional space and the space
- /// is incorporated directly into PathWithStatus without an additional malloc.
- /// Second, obtaining status information is an expensive operation on most
- /// operating systems so we want to be careful and explicit about where we
- /// allow this operation in LLVM.
- /// @brief Path with file status class.
- class PathWithStatus : public Path {
- /// @name Constructors
- /// @{
- public:
- /// @brief Default constructor
- PathWithStatus() : Path(), status(), fsIsValid(false) {}
-
- /// @brief Copy constructor
- PathWithStatus(const PathWithStatus &that)
- : Path(static_cast<const Path&>(that)), status(that.status),
- fsIsValid(that.fsIsValid) {}
-
- /// This constructor allows construction from a Path object
- /// @brief Path constructor
- PathWithStatus(const Path &other)
- : Path(other), status(), fsIsValid(false) {}
-
- /// This constructor will accept a char* or std::string as a path. No
- /// checking is done on this path to determine if it is valid. To
- /// determine validity of the path, use the isValid method.
- /// @brief Construct a Path from a string.
- explicit PathWithStatus(
- StringRef p ///< The path to assign.
- ) : Path(p), status(), fsIsValid(false) {}
-
- /// This constructor will accept a character range as a path. No checking
- /// is done on this path to determine if it is valid. To determine
- /// validity of the path, use the isValid method.
- /// @brief Construct a Path from a string.
- explicit PathWithStatus(
- const char *StrStart, ///< Pointer to the first character of the path
- unsigned StrLen ///< Length of the path.
- ) : Path(StrStart, StrLen), status(), fsIsValid(false) {}
-
- /// Makes a copy of \p that to \p this.
- /// @returns \p this
- /// @brief Assignment Operator
- PathWithStatus &operator=(const PathWithStatus &that) {
- static_cast<Path&>(*this) = static_cast<const Path&>(that);
- status = that.status;
- fsIsValid = that.fsIsValid;
- return *this;
- }
-
- /// Makes a copy of \p that to \p this.
- /// @returns \p this
- /// @brief Assignment Operator
- PathWithStatus &operator=(const Path &that) {
- static_cast<Path&>(*this) = static_cast<const Path&>(that);
- fsIsValid = false;
- return *this;
- }
-
- /// @}
- /// @name Methods
- /// @{
- public:
- /// This function returns status information about the file. The type of
- /// path (file or directory) is updated to reflect the actual contents
- /// of the file system.
- /// @returns 0 on failure, with Error explaining why (if non-zero),
- /// otherwise returns a pointer to a FileStatus structure on success.
- /// @brief Get file status.
- const FileStatus *getFileStatus(
- bool forceUpdate = false, ///< Force an update from the file system
- std::string *Error = 0 ///< Optional place to return an error msg.
- ) const;
-
- /// @}
- /// @name Data
- /// @{
- private:
- mutable FileStatus status; ///< Status information.
- mutable bool fsIsValid; ///< Whether we've obtained it or not
-
- /// @}
- };
-
- /// This is the OS-specific path separator: a colon on Unix or a semicolon
- /// on Windows.
- extern const char PathSeparator;
-}
-
-}
-
-#endif
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index 95d9d78..b1732b2 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/Support/PatternMatch.h
@@ -696,10 +696,17 @@ m_ZExt(const OpTy &Op) {
/// m_UIToFP
template<typename OpTy>
inline CastClass_match<OpTy, Instruction::UIToFP>
-m_UIToFp(const OpTy &Op) {
+m_UIToFP(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::UIToFP>(Op);
}
+/// m_SIToFP
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::SIToFP>
+m_SIToFP(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::SIToFP>(Op);
+}
+
//===----------------------------------------------------------------------===//
// Matchers for unary operators
//
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 08a64de..5134351 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -16,132 +16,81 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/PathV1.h"
+#include "llvm/Support/system_error.h"
namespace llvm {
class error_code;
namespace sys {
- // TODO: Add operations to communicate with the process, redirect its I/O,
- // etc.
-
- /// This class provides an abstraction for programs that are executable by the
- /// operating system. It provides a platform generic way to find executable
- /// programs from the path and to execute them in various ways. The sys::Path
- /// class is used to specify the location of the Program.
- /// @since 1.4
- /// @brief An abstraction for finding and executing programs.
- class Program {
- /// Opaque handle for target specific data.
- void *Data_;
-
- // Noncopyable.
- Program(const Program& other) LLVM_DELETED_FUNCTION;
- Program& operator=(const Program& other) LLVM_DELETED_FUNCTION;
-
- /// @name Methods
- /// @{
-
- Program();
- ~Program();
+ /// This is the OS-specific separator for PATH like environment variables:
+ // a colon on Unix or a semicolon on Windows.
+#if defined(LLVM_ON_UNIX)
+ const char EnvPathSeparator = ':';
+#elif defined (LLVM_ON_WIN32)
+ const char EnvPathSeparator = ';';
+#endif
- /// This function executes the program using the \p arguments provided. The
- /// invoked program will inherit the stdin, stdout, and stderr file
- /// descriptors, the environment and other configuration settings of the
- /// invoking program. If Path::executable() does not return true when this
- /// function is called then a std::string is thrown.
- /// @returns false in case of error, true otherwise.
- /// @see FindProgramByName
- /// @brief Executes the program with the given set of \p args.
- bool Execute
- ( const Path& path, ///< sys::Path object providing the path of the
- ///< program to be executed. It is presumed this is the result of
- ///< the FindProgramByName method.
- const char** args, ///< A vector of strings that are passed to the
+ /// This static constructor (factory) will attempt to locate a program in
+ /// the operating system's file system using some pre-determined set of
+ /// locations to search (e.g. the PATH on Unix). Paths with slashes are
+ /// returned unmodified.
+ /// @returns A Path object initialized to the path of the program or a
+ /// Path object that is empty (invalid) if the program could not be found.
+ /// @brief Construct a Program by finding it by name.
+ std::string FindProgramByName(const std::string& name);
+
+ // These functions change the specified standard stream (stdin, stdout, or
+ // stderr) to binary mode. They return errc::success if the specified stream
+ // was changed. Otherwise a platform dependent error is returned.
+ error_code ChangeStdinToBinary();
+ error_code ChangeStdoutToBinary();
+ error_code ChangeStderrToBinary();
+
+ /// This function executes the program using the arguments provided. The
+ /// invoked program will inherit the stdin, stdout, and stderr file
+ /// descriptors, the environment and other configuration settings of the
+ /// invoking program.
+ /// This function waits the program to finish.
+ /// @returns an integer result code indicating the status of the program.
+ /// A zero or positive value indicates the result code of the program.
+ /// -1 indicates failure to execute
+ /// -2 indicates a crash during execution or timeout
+ int ExecuteAndWait(
+ StringRef Program, ///< Path of the program to be executed. It is
+ /// presumed this is the result of the FindProgramByName method.
+ const char **args, ///< A vector of strings that are passed to the
///< program. The first element should be the name of the program.
///< The list *must* be terminated by a null char* entry.
- const char ** env = 0, ///< An optional vector of strings to use for
+ const char **env = 0, ///< An optional vector of strings to use for
///< the program's environment. If not provided, the current program's
///< environment will be used.
- const sys::Path** redirects = 0, ///< An optional array of pointers to
- ///< Paths. If the array is null, no redirection is done. The array
- ///< should have a size of at least three. If the pointer in the array
- ///< are not null, then the inferior process's stdin(0), stdout(1),
- ///< and stderr(2) will be redirected to the corresponding Paths.
- ///< When an empty Path is passed in, the corresponding file
+ const StringRef **redirects = 0, ///< An optional array of pointers to
+ ///< paths. If the array is null, no redirection is done. The array
+ ///< should have a size of at least three. The inferior process's
+ ///< stdin(0), stdout(1), and stderr(2) will be redirected to the
+ ///< corresponding paths.
+ ///< When an empty path is passed in, the corresponding file
///< descriptor will be disconnected (ie, /dev/null'd) in a portable
///< way.
+ unsigned secondsToWait = 0, ///< If non-zero, this specifies the amount
+ ///< of time to wait for the child process to exit. If the time
+ ///< expires, the child is killed and this call returns. If zero,
+ ///< this function will wait until the child finishes or forever if
+ ///< it doesn't.
unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
///< of memory can be allocated by process. If memory usage will be
///< higher limit, the child is killed and this call returns. If zero
///< - no memory limit.
- std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
+ std::string *ErrMsg = 0, ///< If non-zero, provides a pointer to a string
///< instance in which error messages will be returned. If the string
///< is non-empty upon return an error occurred while invoking the
///< program.
- );
-
- /// This function waits for the program to exit. This function will block
- /// the current program until the invoked program exits.
- /// @returns an integer result code indicating the status of the program.
- /// A zero or positive value indicates the result code of the program.
- /// -1 indicates failure to execute
- /// -2 indicates a crash during execution or timeout
- /// @see Execute
- /// @brief Waits for the program to exit.
- int Wait
- ( const Path& path, ///< The path to the child process executable.
- unsigned secondsToWait, ///< If non-zero, this specifies the amount
- ///< of time to wait for the child process to exit. If the time
- ///< expires, the child is killed and this call returns. If zero,
- ///< this function will wait until the child finishes or forever if
- ///< it doesn't.
- std::string* ErrMsg ///< If non-zero, provides a pointer to a string
- ///< instance in which error messages will be returned. If the string
- ///< is non-empty upon return an error occurred while waiting.
- );
-
- public:
- /// This static constructor (factory) will attempt to locate a program in
- /// the operating system's file system using some pre-determined set of
- /// locations to search (e.g. the PATH on Unix). Paths with slashes are
- /// returned unmodified.
- /// @returns A Path object initialized to the path of the program or a
- /// Path object that is empty (invalid) if the program could not be found.
- /// @brief Construct a Program by finding it by name.
- static Path FindProgramByName(const std::string& name);
-
- // These methods change the specified standard stream (stdin, stdout, or
- // stderr) to binary mode. They return errc::success if the specified stream
- // was changed. Otherwise a platform dependent error is returned.
- static error_code ChangeStdinToBinary();
- static error_code ChangeStdoutToBinary();
- static error_code ChangeStderrToBinary();
-
- /// A convenience function equivalent to Program prg; prg.Execute(..);
- /// prg.Wait(..);
- /// @see Execute, Wait
- static int ExecuteAndWait(const Path& path,
- const char** args,
- const char ** env = 0,
- const sys::Path** redirects = 0,
- unsigned secondsToWait = 0,
- unsigned memoryLimit = 0,
- std::string* ErrMsg = 0,
- bool *ExecutionFailed = 0);
-
- /// A convenience function equivalent to Program prg; prg.Execute(..);
- /// @see Execute
- static void ExecuteNoWait(const Path& path,
- const char** args,
- const char ** env = 0,
- const sys::Path** redirects = 0,
- unsigned memoryLimit = 0,
- std::string* ErrMsg = 0);
-
- /// @}
+ bool *ExecutionFailed = 0);
- };
+ /// Similar to ExecuteAndWait, but return immediately.
+ void ExecuteNoWait(StringRef Program, const char **args, const char **env = 0,
+ const StringRef **redirects = 0, unsigned memoryLimit = 0,
+ std::string *ErrMsg = 0);
// Return true if the given arguments fit within system-specific
// argument length limits.
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
index 82df2c6..3d071be 100644
--- a/include/llvm/Support/Regex.h
+++ b/include/llvm/Support/Regex.h
@@ -77,6 +77,10 @@ namespace llvm {
/// string.
std::string sub(StringRef Repl, StringRef String, std::string *Error = 0);
+ /// \brief If this function returns true, ^Str$ is an extended regular
+ /// expression that matches Str and only Str.
+ static bool isLiteralERE(StringRef Str);
+
private:
struct llvm_regex *preg;
int error;
diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h
index 29eafb6..073becd 100644
--- a/include/llvm/Support/Registry.h
+++ b/include/llvm/Support/Registry.h
@@ -14,6 +14,8 @@
#ifndef LLVM_SUPPORT_REGISTRY_H
#define LLVM_SUPPORT_REGISTRY_H
+#include "llvm/Support/Compiler.h"
+
namespace llvm {
/// A simple registry entry which provides only a name, description, and
/// no-argument constructor.
diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h
index c0a489a..58ed175 100644
--- a/include/llvm/Support/Signals.h
+++ b/include/llvm/Support/Signals.h
@@ -16,7 +16,6 @@
#define LLVM_SUPPORT_SIGNALS_H
#include "llvm/Support/Path.h"
-#include "llvm/Support/PathV1.h"
#include <cstdio>
namespace llvm {
@@ -29,11 +28,11 @@ namespace sys {
/// This function registers signal handlers to ensure that if a signal gets
/// delivered that the named file is removed.
/// @brief Remove a file if a fatal signal occurs.
- bool RemoveFileOnSignal(const Path &Filename, std::string* ErrMsg = 0);
+ bool RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg = 0);
/// This function removes a file from the list of files to be removed on
/// signal delivery.
- void DontRemoveFileOnSignal(const Path &Filename);
+ void DontRemoveFileOnSignal(StringRef Filename);
/// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
/// process, print a stack trace and then exit.
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index d67914a..5b33d42 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -39,7 +39,7 @@ public:
DK_Warning,
DK_Note
};
-
+
/// DiagHandlerTy - Clients that want to handle their own diagnostics in a
/// custom way can register a function pointer+context as a diagnostic
/// handler. It gets called each time PrintMessage is invoked.
@@ -98,7 +98,7 @@ public:
return Buffers[i].Buffer;
}
- unsigned getNumBuffers() const {
+ size_t getNumBuffers() const {
return Buffers.size();
}
@@ -109,20 +109,20 @@ public:
/// AddNewSourceBuffer - Add a new source buffer to this source manager. This
/// takes ownership of the memory buffer.
- unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
+ size_t AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
SrcBuffer NB;
NB.Buffer = F;
NB.IncludeLoc = IncludeLoc;
Buffers.push_back(NB);
- return Buffers.size()-1;
+ return Buffers.size() - 1;
}
/// AddIncludeFile - Search for a file with the specified name in the current
/// directory or in one of the IncludeDirs. If no file is found, this returns
/// ~0, otherwise it returns the buffer ID of the stacked file.
/// The full path to the included file can be found in IncludedFile.
- unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
- std::string &IncludedFile);
+ size_t AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
+ std::string &IncludedFile);
/// FindBufferContainingLoc - Return the ID of the buffer containing the
/// specified location, returning -1 if not found.
@@ -221,7 +221,7 @@ public:
SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
: SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd),
Message(Msg) {}
-
+
// Diagnostic with a location.
SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN,
int Line, int Col, SourceMgr::DiagKind Kind,
diff --git a/include/llvm/Support/SystemUtils.h b/include/llvm/Support/SystemUtils.h
index 399aee5..d2d08b2 100644
--- a/include/llvm/Support/SystemUtils.h
+++ b/include/llvm/Support/SystemUtils.h
@@ -19,7 +19,6 @@
namespace llvm {
class raw_ostream;
- namespace sys { class Path; }
/// Determine if the raw_ostream provided is connected to a terminal. If so,
/// generate a warning message to errs() advising against display of bitcode
@@ -30,15 +29,6 @@ bool CheckBitcodeOutputToConsole(
bool print_warning = true ///< Control whether warnings are printed
);
-/// PrependMainExecutablePath - Prepend the path to the program being executed
-/// to \p ExeName, given the value of argv[0] and the address of main()
-/// itself. This allows us to find another LLVM tool if it is built in the same
-/// directory. An empty string is returned on error; note that this function
-/// just mainpulates the path and doesn't check for executability.
-/// @brief Find a named executable.
-sys::Path PrependMainExecutablePath(const std::string &ExeName,
- const char *Argv0, void *MainAddr);
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h
index 4b48b84..2785408 100644
--- a/include/llvm/Support/TimeValue.h
+++ b/include/llvm/Support/TimeValue.h
@@ -253,9 +253,10 @@ namespace sys {
/// Converts the TimeValue into the corresponding number of "ticks" for
/// Win32 platforms, correcting for the difference in Win32 zero time.
- /// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601)
+ /// @brief Convert to Win32's FILETIME
+ /// (100ns intervals since 00:00:00 Jan 1, 1601 UTC)
uint64_t toWin32Time() const {
- uint64_t result = seconds_ - Win32ZeroTimeSeconds;
+ uint64_t result = (uint64_t)10000000 * (seconds_ - Win32ZeroTimeSeconds);
result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
return result;
}
diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h
index b3b7c57..a2191ad 100644
--- a/include/llvm/Support/ToolOutputFile.h
+++ b/include/llvm/Support/ToolOutputFile.h
@@ -47,7 +47,9 @@ public:
/// tool_output_file - This constructor's arguments are passed to
/// to raw_fd_ostream's constructor.
tool_output_file(const char *filename, std::string &ErrorInfo,
- unsigned Flags = 0);
+ sys::fs::OpenFlags Flags = sys::fs::F_None);
+
+ tool_output_file(const char *Filename, int FD);
/// os - Return the contained raw_fd_ostream.
raw_fd_ostream &os() { return OS; }
diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h
new file mode 100644
index 0000000..4a4d988
--- /dev/null
+++ b/include/llvm/Support/UnicodeCharRanges.h
@@ -0,0 +1,98 @@
+//===--- UnicodeCharRanges.h - Types and functions for character ranges ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_UNICODECHARRANGES_H
+#define LLVM_SUPPORT_UNICODECHARRANGES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/MutexGuard.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace {
+
+struct UnicodeCharRange {
+ uint32_t Lower;
+ uint32_t Upper;
+};
+typedef llvm::ArrayRef<UnicodeCharRange> UnicodeCharSet;
+
+/// Returns true if each of the ranges in \p CharSet is a proper closed range
+/// [min, max], and if the ranges themselves are ordered and non-overlapping.
+static inline bool isValidCharSet(UnicodeCharSet CharSet) {
+#ifndef NDEBUG
+ static llvm::SmallPtrSet<const UnicodeCharRange *, 16> Validated;
+ static llvm::sys::Mutex ValidationMutex;
+
+ // Check the validation cache.
+ {
+ llvm::MutexGuard Guard(ValidationMutex);
+ if (Validated.count(CharSet.data()))
+ return true;
+ }
+
+ // Walk through the ranges.
+ uint32_t Prev = 0;
+ for (UnicodeCharSet::iterator I = CharSet.begin(), E = CharSet.end();
+ I != E; ++I) {
+ if (I != CharSet.begin() && Prev >= I->Lower) {
+ DEBUG(llvm::dbgs() << "Upper bound 0x");
+ DEBUG(llvm::dbgs().write_hex(Prev));
+ DEBUG(llvm::dbgs() << " should be less than succeeding lower bound 0x");
+ DEBUG(llvm::dbgs().write_hex(I->Lower) << "\n");
+ return false;
+ }
+ if (I->Upper < I->Lower) {
+ DEBUG(llvm::dbgs() << "Upper bound 0x");
+ DEBUG(llvm::dbgs().write_hex(I->Lower));
+ DEBUG(llvm::dbgs() << " should not be less than lower bound 0x");
+ DEBUG(llvm::dbgs().write_hex(I->Upper) << "\n");
+ return false;
+ }
+ Prev = I->Upper;
+ }
+
+ // Update the validation cache.
+ {
+ llvm::MutexGuard Guard(ValidationMutex);
+ Validated.insert(CharSet.data());
+ }
+#endif
+ return true;
+}
+
+} // namespace
+
+
+/// Returns true if the Unicode code point \p C is within the set of
+/// characters specified by \p CharSet.
+LLVM_READONLY static inline bool isCharInSet(uint32_t C,
+ UnicodeCharSet CharSet) {
+ assert(isValidCharSet(CharSet));
+
+ size_t LowPoint = 0;
+ size_t HighPoint = CharSet.size();
+
+ // Binary search the set of char ranges.
+ while (HighPoint != LowPoint) {
+ size_t MidPoint = (HighPoint + LowPoint) / 2;
+ if (C < CharSet[MidPoint].Lower)
+ HighPoint = MidPoint;
+ else if (C > CharSet[MidPoint].Upper)
+ LowPoint = MidPoint + 1;
+ else
+ return true;
+ }
+
+ return false;
+}
+
+#endif // LLVM_SUPPORT_UNICODECHARRANGES_H
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 801868f..0f57f44 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -14,7 +14,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
@@ -760,15 +760,7 @@ private:
}
static inline bool classof(const MapHNode *) { return true; }
- struct StrMappingInfo {
- static StringRef getEmptyKey() { return StringRef(); }
- static StringRef getTombstoneKey() { return StringRef(" ", 0); }
- static unsigned getHashValue(StringRef const val) {
- return llvm::HashString(val); }
- static bool isEqual(StringRef const lhs,
- StringRef const rhs) { return lhs.equals(rhs); }
- };
- typedef llvm::DenseMap<StringRef, HNode*, StrMappingInfo> NameToNode;
+ typedef llvm::StringMap<HNode*> NameToNode;
bool isValidKey(StringRef key);
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index d2b4a2a..ec7e06b 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/FileSystem.h"
namespace llvm {
class format_object_base;
@@ -335,22 +336,6 @@ class raw_fd_ostream : public raw_ostream {
void error_detected() { Error = true; }
public:
-
- enum {
- /// F_Excl - When opening a file, this flag makes raw_fd_ostream
- /// report an error if the file already exists.
- F_Excl = 1,
-
- /// F_Append - When opening a file, if it already exists append to the
- /// existing file instead of returning an error. This may not be specified
- /// with F_Excl.
- F_Append = 2,
-
- /// F_Binary - The file should be opened in binary mode on platforms that
- /// make this distinction.
- F_Binary = 4
- };
-
/// raw_fd_ostream - Open the specified file for writing. If an error occurs,
/// information about the error is put into ErrorInfo, and the stream should
/// be immediately destroyed; the string will be empty if no error occurred.
@@ -362,7 +347,7 @@ public:
/// file descriptor when it is done (this is necessary to detect
/// output errors).
raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
- unsigned Flags = 0);
+ sys::fs::OpenFlags Flags = sys::fs::F_None);
/// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If
/// ShouldClose is true, this closes the file when the stream is destroyed.
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index 76ee69d..e17cddd 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -1731,6 +1731,86 @@ 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 {
+ SmallVector<std::pair< bool, StringRef>, 4> Parts;
+
+ RecordParts(StringRef Rec) {
+ if (Rec.empty())
+ return;
+
+ size_t Len = 0;
+ const char *Start = Rec.data();
+ const char *Curr = Start;
+ bool isDigitPart = ascii_isdigit(Curr[0]);
+ for (size_t I = 0, E = Rec.size(); I != E; ++I, ++Len) {
+ bool isDigit = ascii_isdigit(Curr[I]);
+ if (isDigit != isDigitPart) {
+ Parts.push_back(std::make_pair(isDigitPart, StringRef(Start, Len)));
+ Len = 0;
+ Start = &Curr[I];
+ isDigitPart = ascii_isdigit(Curr[I]);
+ }
+ }
+ // Push the last part.
+ Parts.push_back(std::make_pair(isDigitPart, StringRef(Start, Len)));
+ }
+
+ size_t size() { return Parts.size(); }
+
+ std::pair<bool, StringRef> getPart(size_t i) {
+ assert (i < Parts.size() && "Invalid idx!");
+ return Parts[i];
+ }
+ };
+
+ bool operator()(const Record *Rec1, const Record *Rec2) const {
+ RecordParts LHSParts(StringRef(Rec1->getName()));
+ RecordParts RHSParts(StringRef(Rec2->getName()));
+
+ size_t LHSNumParts = LHSParts.size();
+ size_t RHSNumParts = RHSParts.size();
+ assert (LHSNumParts && RHSNumParts && "Expected at least one part!");
+
+ if (LHSNumParts != RHSNumParts)
+ return LHSNumParts < RHSNumParts;
+
+ // We expect the registers to be of the form [_a-zA-z]+([0-9]*[_a-zA-Z]*)*.
+ for (size_t I = 0, E = LHSNumParts; I < E; I+=2) {
+ std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
+ std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
+ // Expect even part to always be alpha.
+ assert (LHSPart.first == false && RHSPart.first == false &&
+ "Expected both parts to be alpha.");
+ if (int Res = LHSPart.second.compare(RHSPart.second))
+ return Res < 0;
+ }
+ for (size_t I = 1, E = LHSNumParts; I < E; I+=2) {
+ std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
+ std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
+ // Expect odd part to always be numeric.
+ assert (LHSPart.first == true && RHSPart.first == true &&
+ "Expected both parts to be numeric.");
+ if (LHSPart.second.size() != RHSPart.second.size())
+ return LHSPart.second.size() < RHSPart.second.size();
+
+ unsigned LHSVal, RHSVal;
+
+ bool LHSFailed = LHSPart.second.getAsInteger(10, LHSVal); (void)LHSFailed;
+ assert(!LHSFailed && "Unable to convert LHS to integer.");
+ bool RHSFailed = RHSPart.second.getAsInteger(10, RHSVal); (void)RHSFailed;
+ assert(!RHSFailed && "Unable to convert RHS to integer.");
+
+ if (LHSVal != RHSVal)
+ return LHSVal < RHSVal;
+ }
+ return LHSNumParts < RHSNumParts;
+ }
+};
+
raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
/// QualifyName - Return an Init with a qualifier prefix referring
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index 986244f..e925cd5 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -59,13 +59,14 @@ public:
/// and the specified global variable's name. If the global variable doesn't
/// have a name, this fills in a unique name for the global.
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
- bool isImplicitlyPrivate);
+ bool isImplicitlyPrivate, bool UseGlobalPrefix = true);
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
/// and the specified name as the global variable name. GVName must not be
/// empty.
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName,
- ManglerPrefixTy PrefixTy = Mangler::Default);
+ ManglerPrefixTy PrefixTy = Mangler::Default,
+ bool UseGlobalPrefix = true);
};
} // End llvm namespace
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index a9644d4..89ca529 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -445,6 +445,11 @@ class Instruction {
string TwoOperandAliasConstraint = "";
///@}
+
+ /// UseNamedOperandTable - If set, the operand indices of this instruction
+ /// can be queried via the getNamedOperandIdx() function which is generated
+ /// by TableGen.
+ bit UseNamedOperandTable = 0;
}
/// PseudoInstExpansion - Expansion information for a pseudo-instruction.
@@ -813,6 +818,9 @@ class AsmParser {
// ShouldEmitMatchRegisterName - Set to false if the target needs a hand
// written register name matcher
bit ShouldEmitMatchRegisterName = 1;
+
+ /// Does the instruction mnemonic allow '.'
+ bit MnemonicContainsDot = 0;
}
def DefaultAsmParser : AsmParser;
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
index d5f30f4..a60147f 100644
--- a/include/llvm/Target/TargetFrameLowering.h
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -88,6 +88,11 @@ public:
///
int getOffsetOfLocalArea() const { return LocalAreaOffset; }
+ /// isFPCloseToIncomingSP - Return true if the frame pointer is close to
+ /// the incoming stack pointer, false if it is close to the post-prologue
+ /// stack pointer.
+ virtual bool isFPCloseToIncomingSP() const { return true; }
+
/// getCalleeSavedSpillSlots - This method returns a pointer to an array of
/// pairs, that contains an entry for each callee saved register that must be
/// spilled to a particular stack location if it is spilled.
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index d49ce1c..f746daf 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -173,6 +173,14 @@ public:
const MachineMemOperand *&MMO,
int &FrameIndex) const;
+ /// isStackSlotCopy - Return true if the specified machine instruction
+ /// is a copy of one stack slot to another and has no other effect.
+ /// Provide the identity of the two frame indices.
+ virtual bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex,
+ int &SrcFrameIndex) const {
+ return false;
+ }
+
/// reMaterialize - Re-issue the specified 'original' instruction at the
/// specific location targeting a new destination register.
/// The register in Orig->getOperand(0).getReg() will be substituted by
@@ -505,22 +513,6 @@ public:
return false;
}
- /// emitFrameIndexDebugValue - Emit a target-dependent form of
- /// DBG_VALUE encoding the address of a frame index. Addresses would
- /// normally be lowered the same way as other addresses on the target,
- /// e.g. in load instructions. For targets that do not support this
- /// the debug info is simply lost.
- /// If you add this for a target you should handle this DBG_VALUE in the
- /// target-specific AsmPrinter code as well; you will probably get invalid
- /// assembly output if you don't.
- virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
- int FrameIx,
- uint64_t Offset,
- const MDNode *MDPtr,
- DebugLoc dl) const {
- return 0;
- }
-
/// foldMemoryOperand - Attempt to fold a load or store of the specified stack
/// slot into the specified machine instruction for the specified operand(s).
/// If this is possible, a new instruction is returned with the specified
@@ -817,12 +809,10 @@ public:
/// computeOperandLatency - Compute and return the latency of the given data
/// dependent def and use when the operand indices are already known.
- ///
- /// FindMin may be set to get the minimum vs. expected latency.
unsigned computeOperandLatency(const InstrItineraryData *ItinData,
const MachineInstr *DefMI, unsigned DefIdx,
- const MachineInstr *UseMI, unsigned UseIdx,
- bool FindMin = false) const;
+ const MachineInstr *UseMI, unsigned UseIdx)
+ const;
/// getInstrLatency - Compute the instruction latency of a given instruction.
/// If the instruction has higher cost when predicated, it's returned via
@@ -839,7 +829,7 @@ public:
const MachineInstr *DefMI) const;
int computeDefOperandLatency(const InstrItineraryData *ItinData,
- const MachineInstr *DefMI, bool FindMin) const;
+ const MachineInstr *DefMI) const;
/// isHighLatencyDef - Return true if this opcode has high latency to its
/// result.
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
index 4b9c044..8c1f223 100644
--- a/include/llvm/Target/TargetLibraryInfo.h
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -24,8 +24,12 @@ namespace llvm {
under_IO_putc,
/// void operator delete[](void*);
ZdaPv,
+ /// void operator delete[](void*, nothrow);
+ ZdaPvRKSt9nothrow_t,
/// void operator delete(void*);
ZdlPv,
+ /// void operator delete(void*, nothrow);
+ ZdlPvRKSt9nothrow_t,
/// void *new[](unsigned int);
Znaj,
/// void *new[](unsigned int, nothrow);
@@ -308,6 +312,8 @@ namespace llvm {
getpwnam,
/// char *gets(char *s);
gets,
+ /// int gettimeofday(struct timeval *tp, void *tzp);
+ gettimeofday,
/// uint32_t htonl(uint32_t hostlong);
htonl,
/// uint16_t htons(uint16_t hostshort);
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 9483282..c3fa3cc 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -6,17 +6,18 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file describes how to lower LLVM code to machine code. This has two
-// main components:
-//
-// 1. Which ValueTypes are natively supported by the target.
-// 2. Which operations are supported for supported ValueTypes.
-// 3. Cost thresholds for alternative implementations of certain operations.
-//
-// In addition it has a few other components, like information about FP
-// immediates.
-//
+///
+/// \file
+/// This file describes how to lower LLVM code to machine code. This has two
+/// main components:
+///
+/// 1. Which ValueTypes are natively supported by the target.
+/// 2. Which operations are supported for supported ValueTypes.
+/// 3. Cost thresholds for alternative implementations of certain operations.
+///
+/// In addition it has a few other components, like information about FP
+/// immediates.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_TARGET_TARGETLOWERING_H
@@ -67,15 +68,15 @@ namespace llvm {
};
}
-/// TargetLoweringBase - This base class for TargetLowering contains the
-/// SelectionDAG-independent parts that can be used from the rest of CodeGen.
+/// This base class for TargetLowering contains the SelectionDAG-independent
+/// parts that can be used from the rest of CodeGen.
class TargetLoweringBase {
TargetLoweringBase(const TargetLoweringBase&) LLVM_DELETED_FUNCTION;
void operator=(const TargetLoweringBase&) LLVM_DELETED_FUNCTION;
public:
- /// LegalizeAction - This enum indicates whether operations are valid for a
- /// target, and if not, what action should be used to make them valid.
+ /// This enum indicates whether operations are valid for a target, and if not,
+ /// what action should be used to make them valid.
enum LegalizeAction {
Legal, // The target natively supports this operation.
Promote, // This operation should be executed in a larger type.
@@ -83,8 +84,8 @@ public:
Custom // Use the LowerOperation hook to implement custom lowering.
};
- /// LegalizeTypeAction - This enum indicates whether a types are legal for a
- /// target, and if not, what action should be used to make them valid.
+ /// This enum indicates whether a types are legal for a target, and if not,
+ /// what action should be used to make them valid.
enum LegalizeTypeAction {
TypeLegal, // The target natively supports this type.
TypePromoteInteger, // Replace this integer with a larger one.
@@ -100,12 +101,14 @@ public:
/// in order to type-legalize it.
typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind;
- enum BooleanContent { // How the target represents true/false values.
+ /// Enum that describes how the target represents true/false values.
+ enum BooleanContent {
UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage.
ZeroOrOneBooleanContent, // All bits zero except for bit 0.
ZeroOrNegativeOneBooleanContent // All bits equal to bit 0.
};
+ /// Enum that describes what type of support for selects the target has.
enum SelectSupportKind {
ScalarValSelect, // The target supports scalar selects (ex: cmov).
ScalarCondVectorVal, // The target supports selects with a scalar condition
@@ -153,112 +156,118 @@ public:
EVT getShiftAmountTy(EVT LHSTy) const;
- /// isSelectExpensive - Return true if the select operation is expensive for
- /// this target.
+ /// Returns the type to be used for the index operand of:
+ /// ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT,
+ /// ISD::INSERT_SUBVECTOR, and ISD::EXTRACT_SUBVECTOR
+ virtual MVT getVectorIdxTy() const {
+ return getPointerTy();
+ }
+
+ /// Return true if the select operation is expensive for this target.
bool isSelectExpensive() const { return SelectIsExpensive; }
virtual bool isSelectSupported(SelectSupportKind /*kind*/) const {
return true;
}
- /// shouldSplitVectorElementType - Return true if a vector of the given type
- /// should be split (TypeSplitVector) instead of promoted
- /// (TypePromoteInteger) during type legalization.
+ /// Return true if a vector of the given type should be split
+ /// (TypeSplitVector) instead of promoted (TypePromoteInteger) during type
+ /// legalization.
virtual bool shouldSplitVectorElementType(EVT /*VT*/) const { return false; }
- /// isIntDivCheap() - Return true if integer divide is usually cheaper than
- /// a sequence of several shifts, adds, and multiplies for this target.
+ /// Return true if integer divide is usually cheaper than a sequence of
+ /// several shifts, adds, and multiplies for this target.
bool isIntDivCheap() const { return IntDivIsCheap; }
- /// isSlowDivBypassed - Returns true if target has indicated at least one
- /// type should be bypassed.
+ /// Returns true if target has indicated at least one type should be bypassed.
bool isSlowDivBypassed() const { return !BypassSlowDivWidths.empty(); }
- /// getBypassSlowDivTypes - Returns map of slow types for division or
- /// remainder with corresponding fast types
+ /// Returns map of slow types for division or remainder with corresponding
+ /// fast types
const DenseMap<unsigned int, unsigned int> &getBypassSlowDivWidths() const {
return BypassSlowDivWidths;
}
- /// isPow2DivCheap() - Return true if pow2 div is cheaper than a chain of
- /// srl/add/sra.
+ /// Return true if pow2 div is cheaper than a chain of srl/add/sra.
bool isPow2DivCheap() const { return Pow2DivIsCheap; }
- /// isJumpExpensive() - Return true if Flow Control is an expensive operation
- /// that should be avoided.
+ /// Return true if Flow Control is an expensive operation that should be
+ /// avoided.
bool isJumpExpensive() const { return JumpIsExpensive; }
- /// isPredictableSelectExpensive - Return true if selects are only cheaper
- /// than branches if the branch is unlikely to be predicted right.
+ /// Return true if selects are only cheaper than branches if the branch is
+ /// unlikely to be predicted right.
bool isPredictableSelectExpensive() const {
return PredictableSelectIsExpensive;
}
- /// getSetCCResultType - Return the ValueType of the result of SETCC
- /// operations. Also used to obtain the target's preferred type for
- /// the condition operand of SELECT and BRCOND nodes. In the case of
- /// BRCOND the argument passed is MVT::Other since there are no other
- /// operands to get a type hint from.
+ /// Return the ValueType of the result of SETCC operations. Also used to
+ /// obtain the target's preferred type for the condition operand of SELECT and
+ /// BRCOND nodes. In the case of BRCOND the argument passed is MVT::Other
+ /// since there are no other operands to get a type hint from.
virtual EVT getSetCCResultType(LLVMContext &Context, EVT VT) const;
- /// getCmpLibcallReturnType - Return the ValueType for comparison
- /// libcalls. Comparions libcalls include floating point comparion calls,
- /// and Ordered/Unordered check calls on floating point numbers.
+ /// Return the ValueType for comparison libcalls. Comparions libcalls include
+ /// floating point comparion calls, and Ordered/Unordered check calls on
+ /// floating point numbers.
virtual
MVT::SimpleValueType getCmpLibcallReturnType() const;
- /// getBooleanContents - For targets without i1 registers, this gives the
- /// nature of the high-bits of boolean values held in types wider than i1.
+ /// For targets without i1 registers, this gives the nature of the high-bits
+ /// of boolean values held in types wider than i1.
+ ///
/// "Boolean values" are special true/false values produced by nodes like
/// SETCC and consumed (as the condition) by nodes like SELECT and BRCOND.
- /// Not to be confused with general values promoted from i1.
- /// Some cpus distinguish between vectors of boolean and scalars; the isVec
- /// parameter selects between the two kinds. For example on X86 a scalar
- /// boolean should be zero extended from i1, while the elements of a vector
- /// of booleans should be sign extended from i1.
+ /// Not to be confused with general values promoted from i1. Some cpus
+ /// distinguish between vectors of boolean and scalars; the isVec parameter
+ /// selects between the two kinds. For example on X86 a scalar boolean should
+ /// be zero extended from i1, while the elements of a vector of booleans
+ /// should be sign extended from i1.
BooleanContent getBooleanContents(bool isVec) const {
return isVec ? BooleanVectorContents : BooleanContents;
}
- /// getSchedulingPreference - Return target scheduling preference.
+ /// Return target scheduling preference.
Sched::Preference getSchedulingPreference() const {
return SchedPreferenceInfo;
}
- /// getSchedulingPreference - Some scheduler, e.g. hybrid, can switch to
- /// different scheduling heuristics for different nodes. This function returns
- /// the preference (or none) for the given node.
+ /// Some scheduler, e.g. hybrid, can switch to different scheduling heuristics
+ /// for different nodes. This function returns the preference (or none) for
+ /// the given node.
virtual Sched::Preference getSchedulingPreference(SDNode *) const {
return Sched::None;
}
- /// getRegClassFor - Return the register class that should be used for the
- /// specified value type.
+ /// Return the register class that should be used for the specified value
+ /// type.
virtual const TargetRegisterClass *getRegClassFor(MVT VT) const {
const TargetRegisterClass *RC = RegClassForVT[VT.SimpleTy];
assert(RC && "This value type is not natively supported!");
return RC;
}
- /// getRepRegClassFor - Return the 'representative' register class for the
- /// specified value type. The 'representative' register class is the largest
- /// legal super-reg register class for the register class of the value type.
- /// For example, on i386 the rep register class for i8, i16, and i32 are GR32;
- /// while the rep register class is GR64 on x86_64.
+ /// Return the 'representative' register class for the specified value
+ /// type.
+ ///
+ /// The 'representative' register class is the largest legal super-reg
+ /// register class for the register class of the value type. For example, on
+ /// i386 the rep register class for i8, i16, and i32 are GR32; while the rep
+ /// register class is GR64 on x86_64.
virtual const TargetRegisterClass *getRepRegClassFor(MVT VT) const {
const TargetRegisterClass *RC = RepRegClassForVT[VT.SimpleTy];
return RC;
}
- /// getRepRegClassCostFor - Return the cost of the 'representative' register
- /// class for the specified value type.
+ /// Return the cost of the 'representative' register class for the specified
+ /// value type.
virtual uint8_t getRepRegClassCostFor(MVT VT) const {
return RepRegClassCostForVT[VT.SimpleTy];
}
- /// isTypeLegal - Return true if the target has native support for the
- /// specified value type. This means that it has a register that directly
- /// holds it without promotions or expansions.
+ /// Return true if the target has native support for the specified value type.
+ /// This means that it has a register that directly holds it without
+ /// promotions or expansions.
bool isTypeLegal(EVT VT) const {
assert(!VT.isSimple() ||
(unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT));
@@ -289,10 +298,10 @@ public:
return ValueTypeActions;
}
- /// getTypeAction - Return how we should legalize values of this type, either
- /// it is already legal (return 'Legal') or we need to promote it to a larger
- /// type (return 'Promote'), or we need to expand it into multiple registers
- /// of smaller integer type (return 'Expand'). 'Custom' is not an option.
+ /// Return how we should legalize values of this type, either it is already
+ /// legal (return 'Legal') or we need to promote it to a larger type (return
+ /// 'Promote'), or we need to expand it into multiple registers of smaller
+ /// integer type (return 'Expand'). 'Custom' is not an option.
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const {
return getTypeConversion(Context, VT).first;
}
@@ -300,20 +309,20 @@ public:
return ValueTypeActions.getTypeAction(VT);
}
- /// getTypeToTransformTo - For types supported by the target, this is an
- /// identity function. For types that must be promoted to larger types, this
- /// returns the larger type to promote to. For integer types that are larger
- /// than the largest integer register, this contains one step in the expansion
- /// to get to the smaller register. For illegal floating point types, this
- /// returns the integer type to transform to.
+ /// For types supported by the target, this is an identity function. For
+ /// types that must be promoted to larger types, this returns the larger type
+ /// to promote to. For integer types that are larger than the largest integer
+ /// register, this contains one step in the expansion to get to the smaller
+ /// register. For illegal floating point types, this returns the integer type
+ /// to transform to.
EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const {
return getTypeConversion(Context, VT).second;
}
- /// getTypeToExpandTo - For types supported by the target, this is an
- /// identity function. For types that must be expanded (i.e. integer types
- /// that are larger than the largest integer register or illegal floating
- /// point types), this returns the largest legal type it will be expanded to.
+ /// For types supported by the target, this is an identity function. For
+ /// types that must be expanded (i.e. integer types that are larger than the
+ /// largest integer register or illegal floating point types), this returns
+ /// the largest legal type it will be expanded to.
EVT getTypeToExpandTo(LLVMContext &Context, EVT VT) const {
assert(!VT.isVector());
while (true) {
@@ -329,24 +338,19 @@ public:
}
}
- /// getVectorTypeBreakdown - Vector types are broken down into some number of
- /// legal first class types. For example, EVT::v8f32 maps to 2 EVT::v4f32
- /// with Altivec or SSE1, or 8 promoted EVT::f64 values with the X86 FP stack.
- /// Similarly, EVT::v2i64 turns into 4 EVT::i32 values with both PPC and X86.
+ /// Vector types are broken down into some number of legal first class types.
+ /// For example, EVT::v8f32 maps to 2 EVT::v4f32 with Altivec or SSE1, or 8
+ /// promoted EVT::f64 values with the X86 FP stack. Similarly, EVT::v2i64
+ /// turns into 4 EVT::i32 values with both PPC and X86.
///
/// This method returns the number of registers needed, and the VT for each
/// register. It also returns the VT and quantity of the intermediate values
/// before they are promoted/expanded.
- ///
unsigned getVectorTypeBreakdown(LLVMContext &Context, EVT VT,
EVT &IntermediateVT,
unsigned &NumIntermediates,
MVT &RegisterVT) const;
- /// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the
- /// intrinsic will need to map to a MemIntrinsicNode (touches memory). If
- /// this is the case, it returns true and store the intrinsic
- /// information into the IntrinsicInfo that was passed to the function.
struct IntrinsicInfo {
unsigned opc; // target opcode
EVT memVT; // memory VT
@@ -358,45 +362,48 @@ public:
bool writeMem; // writes memory?
};
+ /// Given an intrinsic, checks if on the target the intrinsic will need to map
+ /// to a MemIntrinsicNode (touches memory). If this is the case, it returns
+ /// true and store the intrinsic information into the IntrinsicInfo that was
+ /// passed to the function.
virtual bool getTgtMemIntrinsic(IntrinsicInfo &, const CallInst &,
unsigned /*Intrinsic*/) const {
return false;
}
- /// isFPImmLegal - Returns true if the target can instruction select the
- /// specified FP immediate natively. If false, the legalizer will materialize
- /// the FP immediate as a load from a constant pool.
+ /// Returns true if the target can instruction select the specified FP
+ /// immediate natively. If false, the legalizer will materialize the FP
+ /// immediate as a load from a constant pool.
virtual bool isFPImmLegal(const APFloat &/*Imm*/, EVT /*VT*/) const {
return false;
}
- /// isShuffleMaskLegal - Targets can use this to indicate that they only
- /// support *some* VECTOR_SHUFFLE operations, those with specific masks.
- /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
- /// are assumed to be legal.
+ /// Targets can use this to indicate that they only support *some*
+ /// VECTOR_SHUFFLE operations, those with specific masks. By default, if a
+ /// target supports the VECTOR_SHUFFLE node, all mask values are assumed to be
+ /// legal.
virtual bool isShuffleMaskLegal(const SmallVectorImpl<int> &/*Mask*/,
EVT /*VT*/) const {
return true;
}
- /// canOpTrap - Returns true if the operation can trap for the value type.
+ /// Returns true if the operation can trap for the value type.
+ ///
/// VT must be a legal type. By default, we optimistically assume most
/// operations don't trap except for divide and remainder.
virtual bool canOpTrap(unsigned Op, EVT VT) const;
- /// isVectorClearMaskLegal - Similar to isShuffleMaskLegal. This is
- /// used by Targets can use this to indicate if there is a suitable
- /// VECTOR_SHUFFLE that can be used to replace a VAND with a constant
- /// pool entry.
+ /// Similar to isShuffleMaskLegal. This is used by Targets can use this to
+ /// indicate if there is a suitable VECTOR_SHUFFLE that can be used to replace
+ /// a VAND with a constant pool entry.
virtual bool isVectorClearMaskLegal(const SmallVectorImpl<int> &/*Mask*/,
EVT /*VT*/) const {
return false;
}
- /// getOperationAction - Return how this operation should be treated: either
- /// it is legal, needs to be promoted to a larger size, needs to be
- /// expanded to some other code sequence, or the target has a custom expander
- /// for it.
+ /// Return how this operation should be treated: either it is legal, needs to
+ /// be promoted to a larger size, needs to be expanded to some other code
+ /// sequence, or the target has a custom expander for it.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const {
if (VT.isExtended()) return Expand;
// If a target-specific SDNode requires legalization, require the target
@@ -406,59 +413,55 @@ public:
return (LegalizeAction)OpActions[I][Op];
}
- /// isOperationLegalOrCustom - Return true if the specified operation is
- /// legal on this target or can be made legal with custom lowering. This
- /// is used to help guide high-level lowering decisions.
+ /// Return true if the specified operation is legal on this target or can be
+ /// made legal with custom lowering. This is used to help guide high-level
+ /// lowering decisions.
bool isOperationLegalOrCustom(unsigned Op, EVT VT) const {
return (VT == MVT::Other || isTypeLegal(VT)) &&
(getOperationAction(Op, VT) == Legal ||
getOperationAction(Op, VT) == Custom);
}
- /// isOperationLegalOrPromote - Return true if the specified operation is
- /// legal on this target or can be made legal using promotion. This
- /// is used to help guide high-level lowering decisions.
+ /// Return true if the specified operation is legal on this target or can be
+ /// made legal using promotion. This is used to help guide high-level lowering
+ /// decisions.
bool isOperationLegalOrPromote(unsigned Op, EVT VT) const {
return (VT == MVT::Other || isTypeLegal(VT)) &&
(getOperationAction(Op, VT) == Legal ||
getOperationAction(Op, VT) == Promote);
}
- /// isOperationExpand - Return true if the specified operation is illegal on
- /// this target or unlikely to be made legal with custom lowering. This is
- /// used to help guide high-level lowering decisions.
+ /// Return true if the specified operation is illegal on this target or
+ /// unlikely to be made legal with custom lowering. This is used to help guide
+ /// high-level lowering decisions.
bool isOperationExpand(unsigned Op, EVT VT) const {
return (!isTypeLegal(VT) || getOperationAction(Op, VT) == Expand);
}
- /// isOperationLegal - Return true if the specified operation is legal on this
- /// target.
+ /// Return true if the specified operation is legal on this target.
bool isOperationLegal(unsigned Op, EVT VT) const {
return (VT == MVT::Other || isTypeLegal(VT)) &&
getOperationAction(Op, VT) == Legal;
}
- /// getLoadExtAction - Return how this load with extension should be treated:
- /// either it is legal, needs to be promoted to a larger size, needs to be
- /// expanded to some other code sequence, or the target has a custom expander
- /// for it.
+ /// Return how this load with extension should be treated: either it is legal,
+ /// needs to be promoted to a larger size, needs to be expanded to some other
+ /// code sequence, or the target has a custom expander for it.
LegalizeAction getLoadExtAction(unsigned ExtType, MVT VT) const {
assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
return (LegalizeAction)LoadExtActions[VT.SimpleTy][ExtType];
}
- /// isLoadExtLegal - Return true if the specified load with extension is legal
- /// on this target.
+ /// Return true if the specified load with extension is legal on this target.
bool isLoadExtLegal(unsigned ExtType, EVT VT) const {
return VT.isSimple() &&
getLoadExtAction(ExtType, VT.getSimpleVT()) == Legal;
}
- /// getTruncStoreAction - Return how this store with truncation should be
- /// treated: either it is legal, needs to be promoted to a larger size, needs
- /// to be expanded to some other code sequence, or the target has a custom
- /// expander for it.
+ /// Return how this store with truncation should be treated: either it is
+ /// legal, needs to be promoted to a larger size, needs to be expanded to some
+ /// other code sequence, or the target has a custom expander for it.
LegalizeAction getTruncStoreAction(MVT ValVT, MVT MemVT) const {
assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
@@ -466,17 +469,16 @@ public:
[MemVT.SimpleTy];
}
- /// isTruncStoreLegal - Return true if the specified store with truncation is
- /// legal on this target.
+ /// Return true if the specified store with truncation is legal on this
+ /// target.
bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const {
return isTypeLegal(ValVT) && MemVT.isSimple() &&
getTruncStoreAction(ValVT.getSimpleVT(), MemVT.getSimpleVT()) == Legal;
}
- /// getIndexedLoadAction - Return how the indexed load should be treated:
- /// either it is legal, needs to be promoted to a larger size, needs to be
- /// expanded to some other code sequence, or the target has a custom expander
- /// for it.
+ /// Return how the indexed load should be treated: either it is legal, needs
+ /// to be promoted to a larger size, needs to be expanded to some other code
+ /// sequence, or the target has a custom expander for it.
LegalizeAction
getIndexedLoadAction(unsigned IdxMode, MVT VT) const {
assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE &&
@@ -485,18 +487,16 @@ public:
return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4);
}
- /// isIndexedLoadLegal - Return true if the specified indexed load is legal
- /// on this target.
+ /// Return true if the specified indexed load is legal on this target.
bool isIndexedLoadLegal(unsigned IdxMode, EVT VT) const {
return VT.isSimple() &&
(getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Legal ||
getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Custom);
}
- /// getIndexedStoreAction - Return how the indexed store should be treated:
- /// either it is legal, needs to be promoted to a larger size, needs to be
- /// expanded to some other code sequence, or the target has a custom expander
- /// for it.
+ /// Return how the indexed store should be treated: either it is legal, needs
+ /// to be promoted to a larger size, needs to be expanded to some other code
+ /// sequence, or the target has a custom expander for it.
LegalizeAction
getIndexedStoreAction(unsigned IdxMode, MVT VT) const {
assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE &&
@@ -505,17 +505,16 @@ public:
return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f);
}
- /// isIndexedStoreLegal - Return true if the specified indexed load is legal
- /// on this target.
+ /// Return true if the specified indexed load is legal on this target.
bool isIndexedStoreLegal(unsigned IdxMode, EVT VT) const {
return VT.isSimple() &&
(getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Legal ||
getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Custom);
}
- /// getCondCodeAction - Return how the condition code should be treated:
- /// either it is legal, needs to be expanded to some other code sequence,
- /// or the target has a custom expander for it.
+ /// Return how the condition code should be treated: either it is legal, needs
+ /// to be expanded to some other code sequence, or the target has a custom
+ /// expander for it.
LegalizeAction
getCondCodeAction(ISD::CondCode CC, MVT VT) const {
assert((unsigned)CC < array_lengthof(CondCodeActions) &&
@@ -530,8 +529,7 @@ public:
return Action;
}
- /// isCondCodeLegal - Return true if the specified condition code is legal
- /// on this target.
+ /// Return true if the specified condition code is legal on this target.
bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const {
return
getCondCodeAction(CC, VT) == Legal ||
@@ -539,8 +537,8 @@ public:
}
- /// getTypeToPromoteTo - If the action for this operation is to promote, this
- /// method returns the ValueType to promote to.
+ /// If the action for this operation is to promote, this method returns the
+ /// ValueType to promote to.
MVT getTypeToPromoteTo(unsigned Op, MVT VT) const {
assert(getOperationAction(Op, VT) == Promote &&
"This operation isn't promoted!");
@@ -564,10 +562,10 @@ public:
return NVT;
}
- /// getValueType - Return the EVT corresponding to this LLVM type.
- /// This is fixed by the LLVM operations except for the pointer size. If
- /// AllowUnknown is true, this will return MVT::Other for types with no EVT
- /// counterpart (e.g. structs), otherwise it will assert.
+ /// Return the EVT corresponding to this LLVM type. This is fixed by the LLVM
+ /// operations except for the pointer size. If AllowUnknown is true, this
+ /// will return MVT::Other for types with no EVT counterpart (e.g. structs),
+ /// otherwise it will assert.
EVT getValueType(Type *Ty, bool AllowUnknown = false) const {
// Lower scalar pointers to native pointer types.
if (Ty->isPointerTy()) return PointerTy;
@@ -589,20 +587,17 @@ public:
return getValueType(Ty, AllowUnknown).getSimpleVT();
}
- /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
- /// function arguments in the caller parameter area. This is the actual
- /// alignment, not its logarithm.
+ /// Return the desired alignment for ByVal aggregate function arguments in the
+ /// caller parameter area. This is the actual alignment, not its logarithm.
virtual unsigned getByValTypeAlignment(Type *Ty) const;
- /// getRegisterType - Return the type of registers that this ValueType will
- /// eventually require.
+ /// Return the type of registers that this ValueType will eventually require.
MVT getRegisterType(MVT VT) const {
assert((unsigned)VT.SimpleTy < array_lengthof(RegisterTypeForVT));
return RegisterTypeForVT[VT.SimpleTy];
}
- /// getRegisterType - Return the type of registers that this ValueType will
- /// eventually require.
+ /// Return the type of registers that this ValueType will eventually require.
MVT getRegisterType(LLVMContext &Context, EVT VT) const {
if (VT.isSimple()) {
assert((unsigned)VT.getSimpleVT().SimpleTy <
@@ -623,12 +618,14 @@ public:
llvm_unreachable("Unsupported extended type!");
}
- /// getNumRegisters - Return the number of registers that this ValueType will
- /// eventually require. This is one for any types promoted to live in larger
- /// registers, but may be more than one for types (like i64) that are split
- /// into pieces. For types like i140, which are first promoted then expanded,
- /// it is the number of registers needed to hold all the bits of the original
- /// type. For an i140 on a 32 bit machine this means 5 registers.
+ /// Return the number of registers that this ValueType will eventually
+ /// require.
+ ///
+ /// This is one for any types promoted to live in larger registers, but may be
+ /// more than one for types (like i64) that are split into pieces. For types
+ /// like i140, which are first promoted then expanded, it is the number of
+ /// registers needed to hold all the bits of the original type. For an i140
+ /// on a 32 bit machine this means 5 registers.
unsigned getNumRegisters(LLVMContext &Context, EVT VT) const {
if (VT.isSimple()) {
assert((unsigned)VT.getSimpleVT().SimpleTy <
@@ -649,68 +646,72 @@ public:
llvm_unreachable("Unsupported extended type!");
}
- /// ShouldShrinkFPConstant - If true, then instruction selection should
- /// seek to shrink the FP constant of the specified type to a smaller type
- /// in order to save space and / or reduce runtime.
+ /// If true, then instruction selection should seek to shrink the FP constant
+ /// of the specified type to a smaller type in order to save space and / or
+ /// reduce runtime.
virtual bool ShouldShrinkFPConstant(EVT) const { return true; }
- /// hasTargetDAGCombine - If true, the target has custom DAG combine
- /// transformations that it can perform for the specified node.
+ /// If true, the target has custom DAG combine transformations that it can
+ /// perform for the specified node.
bool hasTargetDAGCombine(ISD::NodeType NT) const {
assert(unsigned(NT >> 3) < array_lengthof(TargetDAGCombineArray));
return TargetDAGCombineArray[NT >> 3] & (1 << (NT&7));
}
+ /// \brief Get maximum # of store operations permitted for llvm.memset
+ ///
/// This function returns the maximum number of store operations permitted
/// to replace a call to llvm.memset. The value is set by the target at the
/// performance threshold for such a replacement. If OptSize is true,
/// return the limit for functions that have OptSize attribute.
- /// @brief Get maximum # of store operations permitted for llvm.memset
unsigned getMaxStoresPerMemset(bool OptSize) const {
return OptSize ? MaxStoresPerMemsetOptSize : MaxStoresPerMemset;
}
+ /// \brief Get maximum # of store operations permitted for llvm.memcpy
+ ///
/// This function returns the maximum number of store operations permitted
/// to replace a call to llvm.memcpy. The value is set by the target at the
/// performance threshold for such a replacement. If OptSize is true,
/// return the limit for functions that have OptSize attribute.
- /// @brief Get maximum # of store operations permitted for llvm.memcpy
unsigned getMaxStoresPerMemcpy(bool OptSize) const {
return OptSize ? MaxStoresPerMemcpyOptSize : MaxStoresPerMemcpy;
}
+ /// \brief Get maximum # of store operations permitted for llvm.memmove
+ ///
/// This function returns the maximum number of store operations permitted
/// to replace a call to llvm.memmove. The value is set by the target at the
/// performance threshold for such a replacement. If OptSize is true,
/// return the limit for functions that have OptSize attribute.
- /// @brief Get maximum # of store operations permitted for llvm.memmove
unsigned getMaxStoresPerMemmove(bool OptSize) const {
return OptSize ? MaxStoresPerMemmoveOptSize : MaxStoresPerMemmove;
}
+ /// \brief Determine if the target supports unaligned memory accesses.
+ ///
/// This function returns true if the target allows unaligned memory accesses.
/// of the specified type. If true, it also returns whether the unaligned
/// memory access is "fast" in the second argument by reference. This is used,
- /// for example, in situations where an array copy/move/set is converted to a
+ /// for example, in situations where an array copy/move/set is converted to a
/// sequence of store operations. It's use helps to ensure that such
- /// replacements don't generate code that causes an alignment error (trap) on
+ /// replacements don't generate code that causes an alignment error (trap) on
/// the target machine.
- /// @brief Determine if the target supports unaligned memory accesses.
virtual bool allowsUnalignedMemoryAccesses(EVT, bool * /*Fast*/ = 0) const {
return false;
}
- /// getOptimalMemOpType - Returns the target specific optimal type for load
- /// and store operations as a result of memset, memcpy, and memmove
- /// lowering. If DstAlign is zero that means it's safe to destination
- /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
- /// means there isn't a need to check it against alignment requirement,
- /// probably because the source does not need to be loaded. If 'IsMemset' is
- /// true, that means it's expanding a memset. If 'ZeroMemset' is true, that
- /// means it's a memset of zero. 'MemcpyStrSrc' indicates whether the memcpy
- /// source is constant so it does not need to be loaded.
- /// It returns EVT::Other if the type should be determined using generic
- /// target-independent logic.
+ /// Returns the target specific optimal type for load and store operations as
+ /// a result of memset, memcpy, and memmove lowering.
+ ///
+ /// If DstAlign is zero that means it's safe to destination alignment can
+ /// satisfy any constraint. Similarly if SrcAlign is zero it means there isn't
+ /// a need to check it against alignment requirement, probably because the
+ /// source does not need to be loaded. If 'IsMemset' is true, that means it's
+ /// expanding a memset. If 'ZeroMemset' is true, that means it's a memset of
+ /// zero. 'MemcpyStrSrc' indicates whether the memcpy source is constant so it
+ /// does not need to be loaded. It returns EVT::Other if the type should be
+ /// determined using generic target-independent logic.
virtual EVT getOptimalMemOpType(uint64_t /*Size*/,
unsigned /*DstAlign*/, unsigned /*SrcAlign*/,
bool /*IsMemset*/,
@@ -720,113 +721,102 @@ public:
return MVT::Other;
}
- /// isSafeMemOpType - Returns true if it's safe to use load / store of the
- /// specified type to expand memcpy / memset inline. This is mostly true
- /// for all types except for some special cases. For example, on X86
- /// targets without SSE2 f64 load / store are done with fldl / fstpl which
- /// also does type conversion. Note the specified type doesn't have to be
- /// legal as the hook is used before type legalization.
+ /// Returns true if it's safe to use load / store of the specified type to
+ /// expand memcpy / memset inline.
+ ///
+ /// This is mostly true for all types except for some special cases. For
+ /// example, on X86 targets without SSE2 f64 load / store are done with fldl /
+ /// fstpl which also does type conversion. Note the specified type doesn't
+ /// have to be legal as the hook is used before type legalization.
virtual bool isSafeMemOpType(MVT /*VT*/) const { return true; }
- /// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp
- /// to implement llvm.setjmp.
+ /// Determine if we should use _setjmp or setjmp to implement llvm.setjmp.
bool usesUnderscoreSetJmp() const {
return UseUnderscoreSetJmp;
}
- /// usesUnderscoreLongJmp - Determine if we should use _longjmp or longjmp
- /// to implement llvm.longjmp.
+ /// Determine if we should use _longjmp or longjmp to implement llvm.longjmp.
bool usesUnderscoreLongJmp() const {
return UseUnderscoreLongJmp;
}
- /// supportJumpTables - return whether the target can generate code for
- /// jump tables.
+ /// Return whether the target can generate code for jump tables.
bool supportJumpTables() const {
return SupportJumpTables;
}
- /// getMinimumJumpTableEntries - return integer threshold on number of
- /// blocks to use jump tables rather than if sequence.
+ /// Return integer threshold on number of blocks to use jump tables rather
+ /// than if sequence.
int getMinimumJumpTableEntries() const {
return MinimumJumpTableEntries;
}
- /// getStackPointerRegisterToSaveRestore - If a physical register, this
- /// specifies the register that llvm.savestack/llvm.restorestack should save
- /// and restore.
+ /// If a physical register, this specifies the register that
+ /// llvm.savestack/llvm.restorestack should save and restore.
unsigned getStackPointerRegisterToSaveRestore() const {
return StackPointerRegisterToSaveRestore;
}
- /// getExceptionPointerRegister - If a physical register, this returns
- /// the register that receives the exception address on entry to a landing
- /// pad.
+ /// If a physical register, this returns the register that receives the
+ /// exception address on entry to a landing pad.
unsigned getExceptionPointerRegister() const {
return ExceptionPointerRegister;
}
- /// getExceptionSelectorRegister - If a physical register, this returns
- /// the register that receives the exception typeid on entry to a landing
- /// pad.
+ /// If a physical register, this returns the register that receives the
+ /// exception typeid on entry to a landing pad.
unsigned getExceptionSelectorRegister() const {
return ExceptionSelectorRegister;
}
- /// getJumpBufSize - returns the target's jmp_buf size in bytes (if never
- /// set, the default is 200)
+ /// Returns the target's jmp_buf size in bytes (if never set, the default is
+ /// 200)
unsigned getJumpBufSize() const {
return JumpBufSize;
}
- /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
- /// (if never set, the default is 0)
+ /// Returns the target's jmp_buf alignment in bytes (if never set, the default
+ /// is 0)
unsigned getJumpBufAlignment() const {
return JumpBufAlignment;
}
- /// getMinStackArgumentAlignment - return the minimum stack alignment of an
- /// argument.
+ /// Return the minimum stack alignment of an argument.
unsigned getMinStackArgumentAlignment() const {
return MinStackArgumentAlignment;
}
- /// getMinFunctionAlignment - return the minimum function alignment.
- ///
+ /// Return the minimum function alignment.
unsigned getMinFunctionAlignment() const {
return MinFunctionAlignment;
}
- /// getPrefFunctionAlignment - return the preferred function alignment.
- ///
+ /// Return the preferred function alignment.
unsigned getPrefFunctionAlignment() const {
return PrefFunctionAlignment;
}
- /// getPrefLoopAlignment - return the preferred loop alignment.
- ///
+ /// Return the preferred loop alignment.
unsigned getPrefLoopAlignment() const {
return PrefLoopAlignment;
}
- /// getInsertFencesFor - return whether the DAG builder should automatically
- /// insert fences and reduce ordering for atomics.
- ///
+ /// Return whether the DAG builder should automatically insert fences and
+ /// reduce ordering for atomics.
bool getInsertFencesForAtomic() const {
return InsertFencesForAtomic;
}
- /// getStackCookieLocation - Return true if the target stores stack
- /// protector cookies at a fixed offset in some non-standard address
- /// space, and populates the address space and offset as
- /// appropriate.
+ /// Return true if the target stores stack protector cookies at a fixed offset
+ /// in some non-standard address space, and populates the address space and
+ /// offset as appropriate.
virtual bool getStackCookieLocation(unsigned &/*AddressSpace*/,
unsigned &/*Offset*/) const {
return false;
}
- /// getMaximalGlobalOffset - Returns the maximal possible offset which can be
- /// used for loads / stores from the global.
+ /// Returns the maximal possible offset which can be used for loads / stores
+ /// from the global.
virtual unsigned getMaximalGlobalOffset() const {
return 0;
}
@@ -852,106 +842,98 @@ public:
virtual void resetOperationActions() {}
protected:
- /// setBooleanContents - Specify how the target extends the result of a
- /// boolean value from i1 to a wider type. See getBooleanContents.
+ /// Specify how the target extends the result of a boolean value from i1 to a
+ /// wider type. See getBooleanContents.
void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; }
- /// setBooleanVectorContents - Specify how the target extends the result
- /// of a vector boolean value from a vector of i1 to a wider type. See
- /// getBooleanContents.
+
+ /// Specify how the target extends the result of a vector boolean value from a
+ /// vector of i1 to a wider type. See getBooleanContents.
void setBooleanVectorContents(BooleanContent Ty) {
BooleanVectorContents = Ty;
}
- /// setSchedulingPreference - Specify the target scheduling preference.
+ /// Specify the target scheduling preference.
void setSchedulingPreference(Sched::Preference Pref) {
SchedPreferenceInfo = Pref;
}
- /// setUseUnderscoreSetJmp - Indicate whether this target prefers to
- /// use _setjmp to implement llvm.setjmp or the non _ version.
- /// Defaults to false.
+ /// Indicate whether this target prefers to use _setjmp to implement
+ /// llvm.setjmp or the non _ version. Defaults to false.
void setUseUnderscoreSetJmp(bool Val) {
UseUnderscoreSetJmp = Val;
}
- /// setUseUnderscoreLongJmp - Indicate whether this target prefers to
- /// use _longjmp to implement llvm.longjmp or the non _ version.
- /// Defaults to false.
+ /// Indicate whether this target prefers to use _longjmp to implement
+ /// llvm.longjmp or the non _ version. Defaults to false.
void setUseUnderscoreLongJmp(bool Val) {
UseUnderscoreLongJmp = Val;
}
- /// setSupportJumpTables - Indicate whether the target can generate code for
- /// jump tables.
+ /// Indicate whether the target can generate code for jump tables.
void setSupportJumpTables(bool Val) {
SupportJumpTables = Val;
}
- /// setMinimumJumpTableEntries - Indicate the number of blocks to generate
- /// jump tables rather than if sequence.
+ /// Indicate the number of blocks to generate jump tables rather than if
+ /// sequence.
void setMinimumJumpTableEntries(int Val) {
MinimumJumpTableEntries = Val;
}
- /// setStackPointerRegisterToSaveRestore - If set to a physical register, this
- /// specifies the register that llvm.savestack/llvm.restorestack should save
- /// and restore.
+ /// If set to a physical register, this specifies the register that
+ /// llvm.savestack/llvm.restorestack should save and restore.
void setStackPointerRegisterToSaveRestore(unsigned R) {
StackPointerRegisterToSaveRestore = R;
}
- /// setExceptionPointerRegister - If set to a physical register, this sets
- /// the register that receives the exception address on entry to a landing
- /// pad.
+ /// If set to a physical register, this sets the register that receives the
+ /// exception address on entry to a landing pad.
void setExceptionPointerRegister(unsigned R) {
ExceptionPointerRegister = R;
}
- /// setExceptionSelectorRegister - If set to a physical register, this sets
- /// the register that receives the exception typeid on entry to a landing
- /// pad.
+ /// If set to a physical register, this sets the register that receives the
+ /// exception typeid on entry to a landing pad.
void setExceptionSelectorRegister(unsigned R) {
ExceptionSelectorRegister = R;
}
- /// SelectIsExpensive - Tells the code generator not to expand operations
- /// into sequences that use the select operations if possible.
+ /// Tells the code generator not to expand operations into sequences that use
+ /// the select operations if possible.
void setSelectIsExpensive(bool isExpensive = true) {
SelectIsExpensive = isExpensive;
}
- /// JumpIsExpensive - Tells the code generator not to expand sequence of
- /// operations into a separate sequences that increases the amount of
- /// flow control.
+ /// Tells the code generator not to expand sequence of operations into a
+ /// separate sequences that increases the amount of flow control.
void setJumpIsExpensive(bool isExpensive = true) {
JumpIsExpensive = isExpensive;
}
- /// setIntDivIsCheap - Tells the code generator that integer divide is
- /// expensive, and if possible, should be replaced by an alternate sequence
- /// of instructions not containing an integer divide.
+ /// Tells the code generator that integer divide is expensive, and if
+ /// possible, should be replaced by an alternate sequence of instructions not
+ /// containing an integer divide.
void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; }
- /// addBypassSlowDiv - Tells the code generator which bitwidths to bypass.
+ /// Tells the code generator which bitwidths to bypass.
void addBypassSlowDiv(unsigned int SlowBitWidth, unsigned int FastBitWidth) {
BypassSlowDivWidths[SlowBitWidth] = FastBitWidth;
}
- /// setPow2DivIsCheap - Tells the code generator that it shouldn't generate
- /// srl/add/sra for a signed divide by power of two, and let the target handle
- /// it.
+ /// Tells the code generator that it shouldn't generate srl/add/sra for a
+ /// signed divide by power of two, and let the target handle it.
void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; }
- /// addRegisterClass - Add the specified register class as an available
- /// regclass for the specified value type. This indicates the selector can
- /// handle values of that class natively.
+ /// Add the specified register class as an available regclass for the
+ /// specified value type. This indicates the selector can handle values of
+ /// that class natively.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC) {
assert((unsigned)VT.SimpleTy < array_lengthof(RegClassForVT));
AvailableRegClasses.push_back(std::make_pair(VT, RC));
RegClassForVT[VT.SimpleTy] = RC;
}
- /// clearRegisterClasses - Remove all register classes.
+ /// Remove all register classes.
void clearRegisterClasses() {
memset(RegClassForVT, 0,MVT::LAST_VALUETYPE * sizeof(TargetRegisterClass*));
@@ -962,25 +944,25 @@ protected:
void clearOperationActions() {
}
- /// findRepresentativeClass - Return the largest legal super-reg register class
- /// of the register class for the specified type and its associated "cost".
+ /// Return the largest legal super-reg register class of the register class
+ /// for the specified type and its associated "cost".
virtual std::pair<const TargetRegisterClass*, uint8_t>
findRepresentativeClass(MVT VT) const;
- /// computeRegisterProperties - Once all of the register classes are added,
- /// this allows us to compute derived properties we expose.
+ /// Once all of the register classes are added, this allows us to compute
+ /// derived properties we expose.
void computeRegisterProperties();
- /// setOperationAction - Indicate that the specified operation does not work
- /// with the specified type and indicate what to do about it.
+ /// Indicate that the specified operation does not work with the specified
+ /// type and indicate what to do about it.
void setOperationAction(unsigned Op, MVT VT,
LegalizeAction Action) {
assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
OpActions[(unsigned)VT.SimpleTy][Op] = (uint8_t)Action;
}
- /// setLoadExtAction - Indicate that the specified load with extension does
- /// not work with the specified type and indicate what to do about it.
+ /// Indicate that the specified load with extension does not work with the
+ /// specified type and indicate what to do about it.
void setLoadExtAction(unsigned ExtType, MVT VT,
LegalizeAction Action) {
assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE &&
@@ -988,8 +970,8 @@ protected:
LoadExtActions[VT.SimpleTy][ExtType] = (uint8_t)Action;
}
- /// setTruncStoreAction - Indicate that the specified truncating store does
- /// not work with the specified type and indicate what to do about it.
+ /// Indicate that the specified truncating store does not work with the
+ /// specified type and indicate what to do about it.
void setTruncStoreAction(MVT ValVT, MVT MemVT,
LegalizeAction Action) {
assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE &&
@@ -997,9 +979,10 @@ protected:
TruncStoreActions[ValVT.SimpleTy][MemVT.SimpleTy] = (uint8_t)Action;
}
- /// setIndexedLoadAction - Indicate that the specified indexed load does or
- /// does not work with the specified type and indicate what to do abort
- /// it. NOTE: All indexed mode loads are initialized to Expand in
+ /// Indicate that the specified indexed load does or does not work with the
+ /// specified type and indicate what to do abort it.
+ ///
+ /// NOTE: All indexed mode loads are initialized to Expand in
/// TargetLowering.cpp
void setIndexedLoadAction(unsigned IdxMode, MVT VT,
LegalizeAction Action) {
@@ -1010,9 +993,10 @@ protected:
IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action) <<4;
}
- /// setIndexedStoreAction - Indicate that the specified indexed store does or
- /// does not work with the specified type and indicate what to do about
- /// it. NOTE: All indexed mode stores are initialized to Expand in
+ /// Indicate that the specified indexed store does or does not work with the
+ /// specified type and indicate what to do about it.
+ ///
+ /// NOTE: All indexed mode stores are initialized to Expand in
/// TargetLowering.cpp
void setIndexedStoreAction(unsigned IdxMode, MVT VT,
LegalizeAction Action) {
@@ -1023,8 +1007,8 @@ protected:
IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action);
}
- /// setCondCodeAction - Indicate that the specified condition code is or isn't
- /// supported on the target and indicate what to do about it.
+ /// Indicate that the specified condition code is or isn't supported on the
+ /// target and indicate what to do about it.
void setCondCodeAction(ISD::CondCode CC, MVT VT,
LegalizeAction Action) {
assert(VT < MVT::LAST_VALUETYPE &&
@@ -1039,63 +1023,59 @@ protected:
|= (uint64_t)Action << (VT.SimpleTy & 0x1F)*2;
}
- /// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the
- /// promotion code defaults to trying a larger integer/fp until it can find
- /// one that works. If that default is insufficient, this method can be used
- /// by the target to override the default.
+ /// If Opc/OrigVT is specified as being promoted, the promotion code defaults
+ /// to trying a larger integer/fp until it can find one that works. If that
+ /// default is insufficient, this method can be used by the target to override
+ /// the default.
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT) {
PromoteToType[std::make_pair(Opc, OrigVT.SimpleTy)] = DestVT.SimpleTy;
}
- /// setTargetDAGCombine - Targets should invoke this method for each target
- /// independent node that they want to provide a custom DAG combiner for by
- /// implementing the PerformDAGCombine virtual method.
+ /// Targets should invoke this method for each target independent node that
+ /// they want to provide a custom DAG combiner for by implementing the
+ /// PerformDAGCombine virtual method.
void setTargetDAGCombine(ISD::NodeType NT) {
assert(unsigned(NT >> 3) < array_lengthof(TargetDAGCombineArray));
TargetDAGCombineArray[NT >> 3] |= 1 << (NT&7);
}
- /// setJumpBufSize - Set the target's required jmp_buf buffer size (in
- /// bytes); default is 200
+ /// Set the target's required jmp_buf buffer size (in bytes); default is 200
void setJumpBufSize(unsigned Size) {
JumpBufSize = Size;
}
- /// setJumpBufAlignment - Set the target's required jmp_buf buffer
- /// alignment (in bytes); default is 0
+ /// Set the target's required jmp_buf buffer alignment (in bytes); default is
+ /// 0
void setJumpBufAlignment(unsigned Align) {
JumpBufAlignment = Align;
}
- /// setMinFunctionAlignment - Set the target's minimum function alignment (in
- /// log2(bytes))
+ /// Set the target's minimum function alignment (in log2(bytes))
void setMinFunctionAlignment(unsigned Align) {
MinFunctionAlignment = Align;
}
- /// setPrefFunctionAlignment - Set the target's preferred function alignment.
- /// This should be set if there is a performance benefit to
- /// higher-than-minimum alignment (in log2(bytes))
+ /// Set the target's preferred function alignment. This should be set if
+ /// there is a performance benefit to higher-than-minimum alignment (in
+ /// log2(bytes))
void setPrefFunctionAlignment(unsigned Align) {
PrefFunctionAlignment = Align;
}
- /// setPrefLoopAlignment - Set the target's preferred loop alignment. Default
- /// alignment is zero, it means the target does not care about loop alignment.
- /// The alignment is specified in log2(bytes).
+ /// Set the target's preferred loop alignment. Default alignment is zero, it
+ /// means the target does not care about loop alignment. The alignment is
+ /// specified in log2(bytes).
void setPrefLoopAlignment(unsigned Align) {
PrefLoopAlignment = Align;
}
- /// setMinStackArgumentAlignment - Set the minimum stack alignment of an
- /// argument (in log2(bytes)).
+ /// Set the minimum stack alignment of an argument (in log2(bytes)).
void setMinStackArgumentAlignment(unsigned Align) {
MinStackArgumentAlignment = Align;
}
- /// setInsertFencesForAtomic - Set if the DAG builder should
- /// automatically insert fences and reduce the order of atomic memory
- /// operations to Monotonic.
+ /// Set if the DAG builder should automatically insert fences and reduce the
+ /// order of atomic memory operations to Monotonic.
void setInsertFencesForAtomic(bool fence) {
InsertFencesForAtomic = fence;
}
@@ -1105,25 +1085,24 @@ public:
// Addressing mode description hooks (used by LSR etc).
//
- /// GetAddrModeArguments - CodeGenPrepare sinks address calculations into the
- /// same BB as Load/Store instructions reading the address. This allows as
- /// much computation as possible to be done in the address mode for that
- /// operand. This hook lets targets also pass back when this should be done
- /// on intrinsics which load/store.
+ /// CodeGenPrepare sinks address calculations into the same BB as Load/Store
+ /// instructions reading the address. This allows as much computation as
+ /// possible to be done in the address mode for that operand. This hook lets
+ /// targets also pass back when this should be done on intrinsics which
+ /// load/store.
virtual bool GetAddrModeArguments(IntrinsicInst * /*I*/,
SmallVectorImpl<Value*> &/*Ops*/,
Type *&/*AccessTy*/) const {
return false;
}
- /// AddrMode - This represents an addressing mode of:
+ /// This represents an addressing mode of:
/// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
/// If BaseGV is null, there is no BaseGV.
/// If BaseOffs is zero, there is no base offset.
/// If HasBaseReg is false, there is no base register.
/// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with
/// no scale.
- ///
struct AddrMode {
GlobalValue *BaseGV;
int64_t BaseOffs;
@@ -1132,16 +1111,17 @@ public:
AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
};
- /// isLegalAddressingMode - Return true if the addressing mode represented by
- /// AM is legal for this target, for a load/store of the specified type.
+ /// Return true if the addressing mode represented by AM is legal for this
+ /// target, for a load/store of the specified type.
+ ///
/// The type may be VoidTy, in which case only return true if the addressing
- /// mode is legal for a load/store of any legal type.
- /// TODO: Handle pre/postinc as well.
+ /// 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;
- /// \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.
+ /// \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.
+ ///
/// 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.
@@ -1151,41 +1131,48 @@ public:
return -1;
}
- /// isLegalICmpImmediate - Return true if the specified immediate is legal
- /// icmp immediate, that is the target has icmp instructions which can compare
- /// a register against the immediate without having to materialize the
- /// immediate into a register.
+ /// Return true if the specified immediate is legal icmp immediate, that is
+ /// the target has icmp instructions which can compare a register against the
+ /// immediate without having to materialize the immediate into a register.
virtual bool isLegalICmpImmediate(int64_t) const {
return true;
}
- /// isLegalAddImmediate - Return true if the specified immediate is legal
- /// add immediate, that is the target has add instructions which can add
- /// a register with the immediate without having to materialize the
- /// immediate into a register.
+ /// Return true if the specified immediate is legal add immediate, that is the
+ /// target has add instructions which can add a register with the immediate
+ /// without having to materialize the immediate into a register.
virtual bool isLegalAddImmediate(int64_t) const {
return true;
}
- /// isTruncateFree - Return true if it's free to truncate a value of
- /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in
- /// register EAX to i16 by referencing its sub-register AX.
+ /// Return true if it's free to truncate a value of type Ty1 to type
+ /// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16
+ /// by referencing its sub-register AX.
virtual bool isTruncateFree(Type * /*Ty1*/, Type * /*Ty2*/) const {
return false;
}
+ /// Return true if a truncation from Ty1 to Ty2 is permitted when deciding
+ /// whether a call is in tail position. Typically this means that both results
+ /// would be assigned to the same register or stack slot, but it could mean
+ /// the target performs adequate checks of its own before proceeding with the
+ /// tail call.
+ virtual bool allowTruncateForTailCall(Type * /*Ty1*/, Type * /*Ty2*/) const {
+ return false;
+ }
+
virtual bool isTruncateFree(EVT /*VT1*/, EVT /*VT2*/) const {
return false;
}
- /// isZExtFree - Return true if any actual instruction that defines a
- /// value of type Ty1 implicitly zero-extends the value to Ty2 in the result
- /// register. This does not necessarily include registers defined in
- /// unknown ways, such as incoming arguments, or copies from unknown
- /// virtual registers. Also, if isTruncateFree(Ty2, Ty1) is true, this
- /// does not necessarily apply to truncate instructions. e.g. on x86-64,
- /// all instructions that define 32-bit values implicit zero-extend the
- /// result out to 64 bits.
+ /// Return true if any actual instruction that defines a value of type Ty1
+ /// implicitly zero-extends the value to Ty2 in the result register.
+ ///
+ /// This does not necessarily include registers defined in unknown ways, such
+ /// as incoming arguments, or copies from unknown virtual registers. Also, if
+ /// isTruncateFree(Ty2, Ty1) is true, this does not necessarily apply to
+ /// truncate instructions. e.g. on x86-64, all instructions that define 32-bit
+ /// values implicit zero-extend the result out to 64 bits.
virtual bool isZExtFree(Type * /*Ty1*/, Type * /*Ty2*/) const {
return false;
}
@@ -1194,36 +1181,42 @@ public:
return false;
}
- /// isZExtFree - Return true if zero-extending the specific node Val to type
- /// VT2 is free (either because it's implicitly zero-extended such as ARM
- /// ldrb / ldrh or because it's folded such as X86 zero-extending loads).
+ /// Return true if zero-extending the specific node Val to type VT2 is free
+ /// (either because it's implicitly zero-extended such as ARM ldrb / ldrh or
+ /// because it's folded such as X86 zero-extending loads).
virtual bool isZExtFree(SDValue Val, EVT VT2) const {
return isZExtFree(Val.getValueType(), VT2);
}
- /// isFNegFree - Return true if an fneg operation is free to the point where
- /// it is never worthwhile to replace it with a bitwise operation.
- virtual bool isFNegFree(EVT) const {
+ /// Return true if an fneg operation is free to the point where it is never
+ /// worthwhile to replace it with a bitwise operation.
+ virtual bool isFNegFree(EVT VT) const {
+ assert(VT.isFloatingPoint());
return false;
}
- /// isFAbsFree - Return true if an fneg operation is free to the point where
- /// it is never worthwhile to replace it with a bitwise operation.
- virtual bool isFAbsFree(EVT) const {
+ /// Return true if an fabs operation is free to the point where it is never
+ /// worthwhile to replace it with a bitwise operation.
+ virtual bool isFAbsFree(EVT VT) const {
+ assert(VT.isFloatingPoint());
return false;
}
- /// isFMAFasterThanMulAndAdd - Return true if an FMA operation is faster than
- /// a pair of mul and add instructions. fmuladd intrinsics will be expanded to
- /// FMAs when this method returns true (and FMAs are legal), otherwise fmuladd
- /// is expanded to mul + add.
- virtual bool isFMAFasterThanMulAndAdd(EVT) const {
+ /// Return true if an FMA operation is faster than a pair of fmul and fadd
+ /// instructions. fmuladd intrinsics will be expanded to FMAs when this method
+ /// returns true, otherwise fmuladd is expanded to fmul + fadd.
+ ///
+ /// NOTE: This may be called before legalization on types for which FMAs are
+ /// not legal, but should return true if those types will eventually legalize
+ /// to types that support FMAs. After legalization, it will only be called on
+ /// types that support FMAs (via Legal or Custom actions)
+ virtual bool isFMAFasterThanFMulAndFAdd(EVT) const {
return false;
}
- /// isNarrowingProfitable - Return true if it's profitable to narrow
- /// operations of type VT1 to VT2. e.g. on x86, it's profitable to narrow
- /// from i32 to i8 but not from i32 to i16.
+ /// Return true if it's profitable to narrow operations of type VT1 to
+ /// VT2. e.g. on x86, it's profitable to narrow from i32 to i8 but not from
+ /// i32 to i16.
virtual bool isNarrowingProfitable(EVT /*VT1*/, EVT /*VT2*/) const {
return false;
}
@@ -1232,38 +1225,34 @@ public:
// Runtime Library hooks
//
- /// setLibcallName - Rename the default libcall routine name for the specified
- /// libcall.
+ /// Rename the default libcall routine name for the specified libcall.
void setLibcallName(RTLIB::Libcall Call, const char *Name) {
LibcallRoutineNames[Call] = Name;
}
- /// getLibcallName - Get the libcall routine name for the specified libcall.
- ///
+ /// Get the libcall routine name for the specified libcall.
const char *getLibcallName(RTLIB::Libcall Call) const {
return LibcallRoutineNames[Call];
}
- /// setCmpLibcallCC - Override the default CondCode to be used to test the
- /// result of the comparison libcall against zero.
+ /// Override the default CondCode to be used to test the result of the
+ /// comparison libcall against zero.
void setCmpLibcallCC(RTLIB::Libcall Call, ISD::CondCode CC) {
CmpLibcallCCs[Call] = CC;
}
- /// getCmpLibcallCC - Get the CondCode that's to be used to test the result of
- /// the comparison libcall against zero.
+ /// Get the CondCode that's to be used to test the result of the comparison
+ /// libcall against zero.
ISD::CondCode getCmpLibcallCC(RTLIB::Libcall Call) const {
return CmpLibcallCCs[Call];
}
- /// setLibcallCallingConv - Set the CallingConv that should be used for the
- /// specified libcall.
+ /// Set the CallingConv that should be used for the specified libcall.
void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
LibcallCallingConvs[Call] = CC;
}
- /// getLibcallCallingConv - Get the CallingConv that should be used for the
- /// specified libcall.
+ /// Get the CallingConv that should be used for the specified libcall.
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
return LibcallCallingConvs[Call];
}
@@ -1273,171 +1262,160 @@ private:
const DataLayout *TD;
const TargetLoweringObjectFile &TLOF;
- /// PointerTy - The type to use for pointers for the default address space,
- /// usually i32 or i64.
- ///
+ /// The type to use for pointers for the default address space, usually i32 or
+ /// i64.
MVT PointerTy;
- /// IsLittleEndian - True if this is a little endian target.
- ///
+ /// True if this is a little endian target.
bool IsLittleEndian;
- /// SelectIsExpensive - Tells the code generator not to expand operations
- /// into sequences that use the select operations if possible.
+ /// Tells the code generator not to expand operations into sequences that use
+ /// the select operations if possible.
bool SelectIsExpensive;
- /// IntDivIsCheap - Tells the code generator not to expand integer divides by
- /// constants into a sequence of muls, adds, and shifts. This is a hack until
- /// a real cost model is in place. If we ever optimize for size, this will be
- /// set to true unconditionally.
+ /// Tells the code generator not to expand integer divides by constants into a
+ /// sequence of muls, adds, and shifts. This is a hack until a real cost
+ /// model is in place. If we ever optimize for size, this will be set to true
+ /// unconditionally.
bool IntDivIsCheap;
- /// BypassSlowDivMap - Tells the code generator to bypass slow divide or
- /// remainder instructions. For example, BypassSlowDivWidths[32,8] tells the
- /// code generator to bypass 32-bit integer div/rem with an 8-bit unsigned
- /// integer div/rem when the operands are positive and less than 256.
+ /// Tells the code generator to bypass slow divide or remainder
+ /// instructions. For example, BypassSlowDivWidths[32,8] tells the code
+ /// generator to bypass 32-bit integer div/rem with an 8-bit unsigned integer
+ /// div/rem when the operands are positive and less than 256.
DenseMap <unsigned int, unsigned int> BypassSlowDivWidths;
- /// Pow2DivIsCheap - Tells the code generator that it shouldn't generate
- /// srl/add/sra for a signed divide by power of two, and let the target handle
- /// it.
+ /// Tells the code generator that it shouldn't generate srl/add/sra for a
+ /// signed divide by power of two, and let the target handle it.
bool Pow2DivIsCheap;
- /// JumpIsExpensive - Tells the code generator that it shouldn't generate
- /// extra flow control instructions and should attempt to combine flow
- /// control instructions via predication.
+ /// Tells the code generator that it shouldn't generate extra flow control
+ /// instructions and should attempt to combine flow control instructions via
+ /// predication.
bool JumpIsExpensive;
- /// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement
- /// llvm.setjmp. Defaults to false.
+ /// This target prefers to use _setjmp to implement llvm.setjmp.
+ ///
+ /// Defaults to false.
bool UseUnderscoreSetJmp;
- /// UseUnderscoreLongJmp - This target prefers to use _longjmp to implement
- /// llvm.longjmp. Defaults to false.
+ /// This target prefers to use _longjmp to implement llvm.longjmp.
+ ///
+ /// Defaults to false.
bool UseUnderscoreLongJmp;
- /// SupportJumpTables - Whether the target can generate code for jumptables.
- /// If it's not true, then each jumptable must be lowered into if-then-else's.
+ /// Whether the target can generate code for jumptables. If it's not true,
+ /// then each jumptable must be lowered into if-then-else's.
bool SupportJumpTables;
- /// MinimumJumpTableEntries - Number of blocks threshold to use jump tables.
+ /// Number of blocks threshold to use jump tables.
int MinimumJumpTableEntries;
- /// BooleanContents - Information about the contents of the high-bits in
- /// boolean values held in a type wider than i1. See getBooleanContents.
+ /// Information about the contents of the high-bits in boolean values held in
+ /// a type wider than i1. See getBooleanContents.
BooleanContent BooleanContents;
- /// BooleanVectorContents - Information about the contents of the high-bits
- /// in boolean vector values when the element type is wider than i1. See
- /// getBooleanContents.
+
+ /// Information about the contents of the high-bits in boolean vector values
+ /// when the element type is wider than i1. See getBooleanContents.
BooleanContent BooleanVectorContents;
- /// SchedPreferenceInfo - The target scheduling preference: shortest possible
- /// total cycles or lowest register usage.
+ /// The target scheduling preference: shortest possible total cycles or lowest
+ /// register usage.
Sched::Preference SchedPreferenceInfo;
- /// JumpBufSize - The size, in bytes, of the target's jmp_buf buffers
+ /// The size, in bytes, of the target's jmp_buf buffers
unsigned JumpBufSize;
- /// JumpBufAlignment - The alignment, in bytes, of the target's jmp_buf
- /// buffers
+ /// The alignment, in bytes, of the target's jmp_buf buffers
unsigned JumpBufAlignment;
- /// MinStackArgumentAlignment - The minimum alignment that any argument
- /// on the stack needs to have.
- ///
+ /// The minimum alignment that any argument on the stack needs to have.
unsigned MinStackArgumentAlignment;
- /// MinFunctionAlignment - The minimum function alignment (used when
- /// optimizing for size, and to prevent explicitly provided alignment
- /// from leading to incorrect code).
- ///
+ /// The minimum function alignment (used when optimizing for size, and to
+ /// prevent explicitly provided alignment from leading to incorrect code).
unsigned MinFunctionAlignment;
- /// PrefFunctionAlignment - The preferred function alignment (used when
- /// alignment unspecified and optimizing for speed).
- ///
+ /// The preferred function alignment (used when alignment unspecified and
+ /// optimizing for speed).
unsigned PrefFunctionAlignment;
- /// PrefLoopAlignment - The preferred loop alignment.
- ///
+ /// The preferred loop alignment.
unsigned PrefLoopAlignment;
- /// InsertFencesForAtomic - Whether the DAG builder should automatically
- /// insert fences and reduce ordering for atomics. (This will be set for
- /// for most architectures with weak memory ordering.)
+ /// Whether the DAG builder should automatically insert fences and reduce
+ /// ordering for atomics. (This will be set for for most architectures with
+ /// weak memory ordering.)
bool InsertFencesForAtomic;
- /// StackPointerRegisterToSaveRestore - If set to a physical register, this
- /// specifies the register that llvm.savestack/llvm.restorestack should save
- /// and restore.
+ /// If set to a physical register, this specifies the register that
+ /// llvm.savestack/llvm.restorestack should save and restore.
unsigned StackPointerRegisterToSaveRestore;
- /// ExceptionPointerRegister - If set to a physical register, this specifies
- /// the register that receives the exception address on entry to a landing
- /// pad.
+ /// If set to a physical register, this specifies the register that receives
+ /// the exception address on entry to a landing pad.
unsigned ExceptionPointerRegister;
- /// ExceptionSelectorRegister - If set to a physical register, this specifies
- /// the register that receives the exception typeid on entry to a landing
- /// pad.
+ /// If set to a physical register, this specifies the register that receives
+ /// the exception typeid on entry to a landing pad.
unsigned ExceptionSelectorRegister;
- /// RegClassForVT - This indicates the default register class to use for
- /// each ValueType the target supports natively.
+ /// This indicates the default register class to use for each ValueType the
+ /// target supports natively.
const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE];
MVT RegisterTypeForVT[MVT::LAST_VALUETYPE];
- /// RepRegClassForVT - This indicates the "representative" register class to
- /// use for each ValueType the target supports natively. This information is
- /// used by the scheduler to track register pressure. By default, the
- /// representative register class is the largest legal super-reg register
- /// class of the register class of the specified type. e.g. On x86, i8, i16,
- /// and i32's representative class would be GR32.
+ /// This indicates the "representative" register class to use for each
+ /// ValueType the target supports natively. This information is used by the
+ /// scheduler to track register pressure. By default, the representative
+ /// register class is the largest legal super-reg register class of the
+ /// register class of the specified type. e.g. On x86, i8, i16, and i32's
+ /// representative class would be GR32.
const TargetRegisterClass *RepRegClassForVT[MVT::LAST_VALUETYPE];
- /// RepRegClassCostForVT - This indicates the "cost" of the "representative"
- /// register class for each ValueType. The cost is used by the scheduler to
- /// approximate register pressure.
+ /// This indicates the "cost" of the "representative" register class for each
+ /// ValueType. The cost is used by the scheduler to approximate register
+ /// pressure.
uint8_t RepRegClassCostForVT[MVT::LAST_VALUETYPE];
- /// TransformToType - For any value types we are promoting or expanding, this
- /// contains the value type that we are changing to. For Expanded types, this
- /// contains one step of the expand (e.g. i64 -> i32), even if there are
- /// multiple steps required (e.g. i64 -> i16). For types natively supported
- /// by the system, this holds the same type (e.g. i32 -> i32).
+ /// For any value types we are promoting or expanding, this contains the value
+ /// type that we are changing to. For Expanded types, this contains one step
+ /// of the expand (e.g. i64 -> i32), even if there are multiple steps required
+ /// (e.g. i64 -> i16). For types natively supported by the system, this holds
+ /// the same type (e.g. i32 -> i32).
MVT TransformToType[MVT::LAST_VALUETYPE];
- /// OpActions - For each operation and each value type, keep a LegalizeAction
- /// that indicates how instruction selection should deal with the operation.
- /// Most operations are Legal (aka, supported natively by the target), but
+ /// For each operation and each value type, keep a LegalizeAction that
+ /// indicates how instruction selection should deal with the operation. Most
+ /// operations are Legal (aka, supported natively by the target), but
/// operations that are not should be described. Note that operations on
/// non-legal value types are not described here.
uint8_t OpActions[MVT::LAST_VALUETYPE][ISD::BUILTIN_OP_END];
- /// LoadExtActions - For each load extension type and each value type,
- /// keep a LegalizeAction that indicates how instruction selection should deal
- /// with a load of a specific value type and extension type.
+ /// For each load extension type and each value type, keep a LegalizeAction
+ /// that indicates how instruction selection should deal with a load of a
+ /// specific value type and extension type.
uint8_t LoadExtActions[MVT::LAST_VALUETYPE][ISD::LAST_LOADEXT_TYPE];
- /// TruncStoreActions - For each value type pair keep a LegalizeAction that
- /// indicates whether a truncating store of a specific value type and
- /// truncating type is legal.
+ /// For each value type pair keep a LegalizeAction that indicates whether a
+ /// truncating store of a specific value type and truncating type is legal.
uint8_t TruncStoreActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE];
- /// IndexedModeActions - For each indexed mode and each value type,
- /// keep a pair of LegalizeAction that indicates how instruction
- /// selection should deal with the load / store. The first dimension is the
- /// value_type for the reference. The second dimension represents the various
- /// modes for load store.
+ /// For each indexed mode and each value type, keep a pair of LegalizeAction
+ /// that indicates how instruction selection should deal with the load /
+ /// store.
+ ///
+ /// The first dimension is the value_type for the reference. The second
+ /// dimension represents the various modes for load store.
uint8_t IndexedModeActions[MVT::LAST_VALUETYPE][ISD::LAST_INDEXED_MODE];
- /// CondCodeActions - For each condition code (ISD::CondCode) keep a
- /// LegalizeAction that indicates how instruction selection should
- /// deal with the condition code.
- /// Because each CC action takes up 2 bits, we need to have the array size
- /// be large enough to fit all of the value types. This can be done by
- /// dividing the MVT::LAST_VALUETYPE by 32 and adding one.
+ /// For each condition code (ISD::CondCode) keep a LegalizeAction that
+ /// indicates how instruction selection should deal with the condition code.
+ ///
+ /// Because each CC action takes up 2 bits, we need to have the array size be
+ /// large enough to fit all of the value types. This can be done by dividing
+ /// the MVT::LAST_VALUETYPE by 32 and adding one.
uint64_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE / 32) + 1];
ValueTypeActionImpl ValueTypeActions;
@@ -1573,34 +1551,34 @@ public:
private:
std::vector<std::pair<MVT, const TargetRegisterClass*> > AvailableRegClasses;
- /// TargetDAGCombineArray - Targets can specify ISD nodes that they would
- /// like PerformDAGCombine callbacks for by calling setTargetDAGCombine(),
- /// which sets a bit in this array.
+ /// Targets can specify ISD nodes that they would like PerformDAGCombine
+ /// callbacks for by calling setTargetDAGCombine(), which sets a bit in this
+ /// array.
unsigned char
TargetDAGCombineArray[(ISD::BUILTIN_OP_END+CHAR_BIT-1)/CHAR_BIT];
- /// PromoteToType - For operations that must be promoted to a specific type,
- /// this holds the destination type. This map should be sparse, so don't hold
- /// it as an array.
+ /// For operations that must be promoted to a specific type, this holds the
+ /// destination type. This map should be sparse, so don't hold it as an
+ /// array.
///
/// Targets add entries to this map with AddPromotedToType(..), clients access
/// this with getTypeToPromoteTo(..).
std::map<std::pair<unsigned, MVT::SimpleValueType>, MVT::SimpleValueType>
PromoteToType;
- /// LibcallRoutineNames - Stores the name each libcall.
- ///
+ /// Stores the name each libcall.
const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL];
- /// CmpLibcallCCs - The ISD::CondCode that should be used to test the result
- /// of each of the comparison libcall against zero.
+ /// The ISD::CondCode that should be used to test the result of each of the
+ /// comparison libcall against zero.
ISD::CondCode CmpLibcallCCs[RTLIB::UNKNOWN_LIBCALL];
- /// LibcallCallingConvs - Stores the CallingConv that should be used for each
- /// libcall.
+ /// Stores the CallingConv that should be used for each libcall.
CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL];
protected:
+ /// \brief Specify maximum number of store instructions per memset call.
+ ///
/// When lowering \@llvm.memset this field specifies the maximum number of
/// store operations that may be substituted for the call to memset. Targets
/// must set this value based on the cost threshold for that target. Targets
@@ -1609,13 +1587,14 @@ protected:
/// alignment restrictions. For example, storing 9 bytes on a 32-bit machine
/// with 16-bit alignment would result in four 2-byte stores and one 1-byte
/// store. This only applies to setting a constant array of a constant size.
- /// @brief Specify maximum number of store instructions per memset call.
unsigned MaxStoresPerMemset;
/// Maximum number of stores operations that may be substituted for the call
/// to memset, used for functions with OptSize attribute.
unsigned MaxStoresPerMemsetOptSize;
+ /// \brief Specify maximum bytes of store instructions per memcpy call.
+ ///
/// When lowering \@llvm.memcpy this field specifies the maximum number of
/// store operations that may be substituted for a call to memcpy. Targets
/// must set this value based on the cost threshold for that target. Targets
@@ -1625,13 +1604,14 @@ protected:
/// with 32-bit alignment would result in one 4-byte store, a one 2-byte store
/// and one 1-byte store. This only applies to copying a constant array of
/// constant size.
- /// @brief Specify maximum bytes of store instructions per memcpy call.
unsigned MaxStoresPerMemcpy;
- /// Maximum number of store operations that may be substituted for a call
- /// to memcpy, used for functions with OptSize attribute.
+ /// Maximum number of store operations that may be substituted for a call to
+ /// memcpy, used for functions with OptSize attribute.
unsigned MaxStoresPerMemcpyOptSize;
+ /// \brief Specify maximum bytes of store instructions per memmove call.
+ ///
/// When lowering \@llvm.memmove this field specifies the maximum number of
/// store instructions that may be substituted for a call to memmove. Targets
/// must set this value based on the cost threshold for that target. Targets
@@ -1640,31 +1620,27 @@ protected:
/// alignment restrictions. For example, moving 9 bytes on a 32-bit machine
/// with 8-bit alignment would result in nine 1-byte stores. This only
/// applies to copying a constant array of constant size.
- /// @brief Specify maximum bytes of store instructions per memmove call.
unsigned MaxStoresPerMemmove;
- /// Maximum number of store instructions that may be substituted for a call
- /// to memmove, used for functions with OpSize attribute.
+ /// Maximum number of store instructions that may be substituted for a call to
+ /// memmove, used for functions with OpSize attribute.
unsigned MaxStoresPerMemmoveOptSize;
- /// PredictableSelectIsExpensive - Tells the code generator that select is
- /// more expensive than a branch if the branch is usually predicted right.
+ /// Tells the code generator that select is more expensive than a branch if
+ /// the branch is usually predicted right.
bool PredictableSelectIsExpensive;
protected:
- /// isLegalRC - Return true if the value types that can be represented by the
- /// specified register class are all legal.
+ /// Return true if the value types that can be represented by the specified
+ /// register class are all legal.
bool isLegalRC(const TargetRegisterClass *RC) const;
};
-//===----------------------------------------------------------------------===//
-/// TargetLowering - This class defines information used to lower LLVM code to
-/// legal SelectionDAG operators that the target instruction selector can accept
-/// natively.
+/// This class defines information used to lower LLVM code to legal SelectionDAG
+/// operators that the target instruction selector can accept natively.
///
/// This class also defines callbacks that targets must implement to lower
/// target-specific constructs to SelectionDAG operators.
-///
class TargetLowering : public TargetLoweringBase {
TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION;
void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION;
@@ -1674,9 +1650,9 @@ public:
explicit TargetLowering(const TargetMachine &TM,
const TargetLoweringObjectFile *TLOF);
- /// getPreIndexedAddressParts - returns true by value, base pointer and
- /// offset pointer and addressing mode by reference if the node's address
- /// can be legally represented as pre-indexed load / store address.
+ /// Returns true by value, base pointer and offset pointer and addressing mode
+ /// by reference if the node's address can be legally represented as
+ /// pre-indexed load / store address.
virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/,
SDValue &/*Offset*/,
ISD::MemIndexedMode &/*AM*/,
@@ -1684,9 +1660,9 @@ public:
return false;
}
- /// getPostIndexedAddressParts - returns true by value, base pointer and
- /// offset pointer and addressing mode by reference if this node can be
- /// combined with a load / store to form a post-indexed load / store.
+ /// Returns true by value, base pointer and offset pointer and addressing mode
+ /// by reference if this node can be combined with a load / store to form a
+ /// post-indexed load / store.
virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/,
SDValue &/*Base*/, SDValue &/*Offset*/,
ISD::MemIndexedMode &/*AM*/,
@@ -1694,9 +1670,8 @@ public:
return false;
}
- /// getJumpTableEncoding - Return the entry encoding for a jump table in the
- /// current function. The returned value is a member of the
- /// MachineJumpTableInfo::JTEntryKind enum.
+ /// Return the entry encoding for a jump table in the current function. The
+ /// returned value is a member of the MachineJumpTableInfo::JTEntryKind enum.
virtual unsigned getJumpTableEncoding() const;
virtual const MCExpr *
@@ -1706,21 +1681,18 @@ public:
llvm_unreachable("Need to implement this hook if target has custom JTIs");
}
- /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
- /// jumptable.
+ /// Returns relocation base for the given PIC jumptable.
virtual SDValue getPICJumpTableRelocBase(SDValue Table,
SelectionDAG &DAG) const;
- /// getPICJumpTableRelocBaseExpr - This returns the relocation base for the
- /// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an
- /// MCExpr.
+ /// This returns the relocation base for the given PIC jumptable, the same as
+ /// getPICJumpTableRelocBase, but as an MCExpr.
virtual const MCExpr *
getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
unsigned JTI, MCContext &Ctx) const;
- /// isOffsetFoldingLegal - Return true if folding a constant offset
- /// with the given GlobalAddress is legal. It is frequently not legal in
- /// PIC relocation models.
+ /// Return true if folding a constant offset with the given GlobalAddress is
+ /// legal. It is frequently not legal in PIC relocation models.
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
@@ -1738,9 +1710,9 @@ public:
// TargetLowering Optimization Methods
//
- /// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two
- /// SDValues for returning information from TargetLowering to its clients
- /// that want to combine
+ /// A convenience struct that encapsulates a DAG, and two SDValues for
+ /// returning information from TargetLowering to its clients that want to
+ /// combine.
struct TargetLoweringOpt {
SelectionDAG &DAG;
bool LegalTys;
@@ -1761,44 +1733,40 @@ public:
return true;
}
- /// ShrinkDemandedConstant - Check to see if the specified operand of the
- /// specified instruction is a constant integer. If so, check to see if
- /// there are any bits set in the constant that are not demanded. If so,
- /// shrink the constant and return true.
+ /// Check to see if the specified operand of the specified instruction is a
+ /// constant integer. If so, check to see if there are any bits set in the
+ /// constant that are not demanded. If so, shrink the constant and return
+ /// true.
bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
- /// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the
- /// casts are free. This uses isZExtFree and ZERO_EXTEND for the widening
- /// cast, but it could be generalized for targets with other types of
- /// implicit widening casts.
+ /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free. This
+ /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
+ /// generalized for targets with other types of implicit widening casts.
bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
SDLoc dl);
};
- /// SimplifyDemandedBits - Look at Op. At this point, we know that only the
- /// DemandedMask bits of the result of Op are ever used downstream. If we can
- /// use this information to simplify Op, create a new simplified DAG node and
- /// return true, returning the original and new nodes in Old and New.
- /// Otherwise, analyze the expression and return a mask of KnownOne and
- /// KnownZero bits for the expression (used to simplify the caller).
- /// The KnownZero/One bits may only be accurate for those bits in the
- /// DemandedMask.
+ /// Look at Op. At this point, we know that only the DemandedMask bits of the
+ /// result of Op are ever used downstream. If we can use this information to
+ /// simplify Op, create a new simplified DAG node and return true, returning
+ /// the original and new nodes in Old and New. Otherwise, analyze the
+ /// expression and return a mask of KnownOne and KnownZero bits for the
+ /// expression (used to simplify the caller). The KnownZero/One bits may only
+ /// be accurate for those bits in the DemandedMask.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
APInt &KnownZero, APInt &KnownOne,
TargetLoweringOpt &TLO, unsigned Depth = 0) const;
- /// computeMaskedBitsForTargetNode - Determine which of the bits specified in
- /// Mask are known to be either zero or one and return them in the
- /// KnownZero/KnownOne bitsets.
+ /// Determine which of the bits specified in Mask are known to be either zero
+ /// or one and return them in the KnownZero/KnownOne bitsets.
virtual void computeMaskedBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,
unsigned Depth = 0) const;
- /// ComputeNumSignBitsForTargetNode - This method can be implemented by
- /// targets that want to expose additional information about sign bits to the
- /// DAG Combiner.
+ /// This method can be implemented by targets that want to expose additional
+ /// information about sign bits to the DAG Combiner.
virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
unsigned Depth = 0) const;
@@ -1830,20 +1798,20 @@ public:
void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
};
- /// SimplifySetCC - Try to simplify a setcc built with the specified operands
- /// and cc. If it is unable to simplify it, return a null SDValue.
+ /// Try to simplify a setcc built with the specified operands and cc. If it is
+ /// unable to simplify it, return a null SDValue.
SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
ISD::CondCode Cond, bool foldBooleans,
DAGCombinerInfo &DCI, SDLoc dl) const;
- /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
- /// node is a GlobalAddress + offset.
+ /// Returns true (and the GlobalValue and the offset) if the node is a
+ /// GlobalAddress + offset.
virtual bool
isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const;
- /// PerformDAGCombine - This method will be invoked for all target nodes and
- /// for any target-independent nodes that the target has registered with
- /// invoke it for.
+ /// This method will be invoked for all target nodes and for any
+ /// target-independent nodes that the target has registered with invoke it
+ /// for.
///
/// The semantics are as follows:
/// Return Value:
@@ -1856,26 +1824,26 @@ public:
///
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
- /// isTypeDesirableForOp - Return true if the target has native support for
- /// the specified value type and it is 'desirable' to use the type for the
- /// given node type. e.g. On x86 i16 is legal, but undesirable since i16
- /// instruction encodings are longer and some i16 instructions are slow.
+ /// Return true if the target has native support for the specified value type
+ /// and it is 'desirable' to use the type for the given node type. e.g. On x86
+ /// i16 is legal, but undesirable since i16 instruction encodings are longer
+ /// and some i16 instructions are slow.
virtual bool isTypeDesirableForOp(unsigned /*Opc*/, EVT VT) const {
// By default, assume all legal types are desirable.
return isTypeLegal(VT);
}
- /// isDesirableToPromoteOp - Return true if it is profitable for dag combiner
- /// to transform a floating point op of specified opcode to a equivalent op of
- /// an integer type. e.g. f32 load -> i32 load can be profitable on ARM.
+ /// Return true if it is profitable for dag combiner to transform a floating
+ /// point op of specified opcode to a equivalent op of an integer
+ /// type. e.g. f32 load -> i32 load can be profitable on ARM.
virtual bool isDesirableToTransformToIntegerOp(unsigned /*Opc*/,
EVT /*VT*/) const {
return false;
}
- /// IsDesirableToPromoteOp - This method query the target whether it is
- /// beneficial for dag combiner to promote the specified node. If true, it
- /// should return the desired promotion type by reference.
+ /// This method query the target whether it is beneficial for dag combiner to
+ /// promote the specified node. If true, it should return the desired
+ /// promotion type by reference.
virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const {
return false;
}
@@ -1885,11 +1853,10 @@ public:
// the SelectionDAGBuilder code knows how to lower these.
//
- /// LowerFormalArguments - This hook must be implemented to lower the
- /// incoming (formal) arguments, described by the Ins array, into the
- /// specified DAG. The implementation should fill in the InVals array
- /// with legal-type argument values, and return the resulting token
- /// chain value.
+ /// This hook must be implemented to lower the incoming (formal) arguments,
+ /// described by the Ins array, into the specified DAG. The implementation
+ /// should fill in the InVals array with legal-type argument values, and
+ /// return the resulting token chain value.
///
virtual SDValue
LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
@@ -1918,10 +1885,10 @@ public:
};
typedef std::vector<ArgListEntry> ArgListTy;
- /// CallLoweringInfo - This structure contains all information that is
- /// necessary for lowering calls. It is passed to TLI::LowerCallTo when the
- /// SelectionDAG builder needs to lower a call, and targets will see this
- /// struct in their LowerCall implementation.
+ /// This structure contains all information that is necessary for lowering
+ /// calls. It is passed to TLI::LowerCallTo when the SelectionDAG builder
+ /// needs to lower a call, and targets will see this struct in their LowerCall
+ /// implementation.
struct CallLoweringInfo {
SDValue Chain;
Type *RetTy;
@@ -1948,8 +1915,7 @@ public:
SmallVector<ISD::InputArg, 32> Ins;
- /// CallLoweringInfo - Constructs a call lowering context based on the
- /// ImmutableCallSite \p cs.
+ /// Constructs a call lowering context based on the ImmutableCallSite \p cs.
CallLoweringInfo(SDValue chain, Type *retTy,
FunctionType *FTy, bool isTailCall, SDValue callee,
ArgListTy &args, SelectionDAG &dag, SDLoc dl,
@@ -1963,8 +1929,8 @@ public:
CallConv(cs.getCallingConv()), Callee(callee), Args(args), DAG(dag),
DL(dl), CS(&cs) {}
- /// CallLoweringInfo - Constructs a call lowering context based on the
- /// provided call information.
+ /// Constructs a call lowering context based on the provided call
+ /// information.
CallLoweringInfo(SDValue chain, Type *retTy, bool retSExt, bool retZExt,
bool isVarArg, bool isInReg, unsigned numFixedArgs,
CallingConv::ID callConv, bool isTailCall,
@@ -1977,32 +1943,29 @@ public:
Args(args), DAG(dag), DL(dl), CS(NULL) {}
};
- /// LowerCallTo - This function lowers an abstract call to a function into an
- /// actual call. This returns a pair of operands. The first element is the
- /// return value for the function (if RetTy is not VoidTy). The second
- /// element is the outgoing token chain. It calls LowerCall to do the actual
- /// lowering.
+ /// This function lowers an abstract call to a function into an actual call.
+ /// This returns a pair of operands. The first element is the return value
+ /// for the function (if RetTy is not VoidTy). The second element is the
+ /// outgoing token chain. It calls LowerCall to do the actual lowering.
std::pair<SDValue, SDValue> LowerCallTo(CallLoweringInfo &CLI) const;
- /// LowerCall - This hook must be implemented to lower calls into the
- /// the specified DAG. The outgoing arguments to the call are described
- /// by the Outs array, and the values to be returned by the call are
- /// described by the Ins array. The implementation should fill in the
- /// InVals array with legal-type return values from the call, and return
- /// the resulting token chain value.
+ /// This hook must be implemented to lower calls into the the specified
+ /// DAG. The outgoing arguments to the call are described by the Outs array,
+ /// and the values to be returned by the call are described by the Ins
+ /// array. The implementation should fill in the InVals array with legal-type
+ /// return values from the call, and return the resulting token chain value.
virtual SDValue
LowerCall(CallLoweringInfo &/*CLI*/,
SmallVectorImpl<SDValue> &/*InVals*/) const {
llvm_unreachable("Not Implemented");
}
- /// HandleByVal - Target-specific cleanup for formal ByVal parameters.
+ /// Target-specific cleanup for formal ByVal parameters.
virtual void HandleByVal(CCState *, unsigned &, unsigned) const {}
- /// CanLowerReturn - This hook should be implemented to check whether the
- /// return values described by the Outs array can fit into the return
- /// registers. If false is returned, an sret-demotion is performed.
- ///
+ /// This hook should be implemented to check whether the return values
+ /// described by the Outs array can fit into the return registers. If false
+ /// is returned, an sret-demotion is performed.
virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/,
MachineFunction &/*MF*/, bool /*isVarArg*/,
const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
@@ -2012,11 +1975,9 @@ public:
return true;
}
- /// LowerReturn - This hook must be implemented to lower outgoing
- /// return values, described by the Outs array, into the specified
- /// DAG. The implementation should return the resulting token chain
- /// value.
- ///
+ /// This hook must be implemented to lower outgoing return values, described
+ /// by the Outs array, into the specified DAG. The implementation should
+ /// return the resulting token chain value.
virtual SDValue
LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
bool /*isVarArg*/,
@@ -2026,42 +1987,42 @@ public:
llvm_unreachable("Not Implemented");
}
- /// isUsedByReturnOnly - Return true if result of the specified node is used
- /// by a return node only. It also compute and return the input chain for the
- /// tail call.
- /// This is used to determine whether it is possible
- /// to codegen a libcall as tail call at legalization time.
+ /// Return true if result of the specified node is used by a return node
+ /// only. It also compute and return the input chain for the tail call.
+ ///
+ /// This is used to determine whether it is possible to codegen a libcall as
+ /// tail call at legalization time.
virtual bool isUsedByReturnOnly(SDNode *, SDValue &/*Chain*/) const {
return false;
}
- /// mayBeEmittedAsTailCall - Return true if the target may be able emit the
- /// call instruction as a tail call. This is used by optimization passes to
- /// determine if it's profitable to duplicate return instructions to enable
- /// tailcall optimization.
+ /// Return true if the target may be able emit the call instruction as a tail
+ /// call. This is used by optimization passes to determine if it's profitable
+ /// to duplicate return instructions to enable tailcall optimization.
virtual bool mayBeEmittedAsTailCall(CallInst *) const {
return false;
}
- /// getTypeForExtArgOrReturn - Return the type that should be used to zero or
- /// sign extend a zeroext/signext integer argument or return value.
- /// FIXME: Most C calling convention requires the return type to be promoted,
- /// but this is not true all the time, e.g. i1 on x86-64. It is also not
- /// necessary for non-C calling conventions. The frontend should handle this
- /// and include all of the necessary information.
+ /// Return the type that should be used to zero or sign extend a
+ /// zeroext/signext integer argument or return value. FIXME: Most C calling
+ /// convention requires the return type to be promoted, but this is not true
+ /// all the time, e.g. i1 on x86-64. It is also not necessary for non-C
+ /// calling conventions. The frontend should handle this and include all of
+ /// the necessary information.
virtual MVT getTypeForExtArgOrReturn(MVT VT,
ISD::NodeType /*ExtendKind*/) const {
MVT MinVT = getRegisterType(MVT::i32);
return VT.bitsLT(MinVT) ? MinVT : VT;
}
- /// LowerOperationWrapper - This callback is invoked by the type legalizer
- /// to legalize nodes with an illegal operand type but legal result types.
- /// It replaces the LowerOperation callback in the type Legalizer.
- /// The reason we can not do away with LowerOperation entirely is that
- /// LegalizeDAG isn't yet ready to use this callback.
+ /// This callback is invoked by the type legalizer to legalize nodes with an
+ /// illegal operand type but legal result types. It replaces the
+ /// LowerOperation callback in the type Legalizer. The reason we can not do
+ /// away with LowerOperation entirely is that LegalizeDAG isn't yet ready to
+ /// use this callback.
+ ///
/// TODO: Consider merging with ReplaceNodeResults.
-
+ ///
/// The target places new result values for the node in Results (their number
/// and types must exactly match those of the original return values of
/// the node), or leaves Results empty, which indicates that the node is not
@@ -2071,19 +2032,19 @@ public:
SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const;
- /// LowerOperation - This callback is invoked for operations that are
- /// unsupported by the target, which are registered to use 'custom' lowering,
- /// and whose defined values are all legal.
- /// If the target has no operations that require custom lowering, it need not
- /// implement this. The default implementation of this aborts.
+ /// This callback is invoked for operations that are unsupported by the
+ /// target, which are registered to use 'custom' lowering, and whose defined
+ /// values are all legal. If the target has no operations that require custom
+ /// lowering, it need not implement this. The default implementation of this
+ /// aborts.
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
- /// ReplaceNodeResults - This callback is invoked when a node result type is
- /// illegal for the target, and the operation was registered to use 'custom'
- /// lowering for that result type. The target places new result values for
- /// the node in Results (their number and types must exactly match those of
- /// the original return values of the node), or leaves Results empty, which
- /// indicates that the node is not to be custom lowered after all.
+ /// This callback is invoked when a node result type is illegal for the
+ /// target, and the operation was registered to use 'custom' lowering for that
+ /// result type. The target places new result values for the node in Results
+ /// (their number and types must exactly match those of the original return
+ /// values of the node), or leaves Results empty, which indicates that the
+ /// node is not to be custom lowered after all.
///
/// If the target has no operations that require custom lowering, it need not
/// implement this. The default implementation aborts.
@@ -2093,12 +2054,11 @@ public:
llvm_unreachable("ReplaceNodeResults not implemented for this target!");
}
- /// getTargetNodeName() - This method returns the name of a target specific
- /// DAG node.
+ /// This method returns the name of a target specific DAG node.
virtual const char *getTargetNodeName(unsigned Opcode) const;
- /// createFastISel - This method returns a target specific FastISel object,
- /// or null if the target does not support "fast" ISel.
+ /// This method returns a target specific FastISel object, or null if the
+ /// target does not support "fast" ISel.
virtual FastISel *createFastISel(FunctionLoweringInfo &,
const TargetLibraryInfo *) const {
return 0;
@@ -2108,10 +2068,10 @@ public:
// Inline Asm Support hooks
//
- /// ExpandInlineAsm - This hook allows the target to expand an inline asm
- /// call to be explicit llvm code if it wants to. This is useful for
- /// turning simple inline asms into LLVM intrinsics, which gives the
- /// compiler more information about the behavior of the code.
+ /// This hook allows the target to expand an inline asm call to be explicit
+ /// llvm code if it wants to. This is useful for turning simple inline asms
+ /// into LLVM intrinsics, which gives the compiler more information about the
+ /// behavior of the code.
virtual bool ExpandInlineAsm(CallInst *) const {
return false;
}
@@ -2140,32 +2100,31 @@ public:
CW_Default = CW_Okay // Default or don't know type.
};
- /// AsmOperandInfo - This contains information for each constraint that we are
- /// lowering.
+ /// This contains information for each constraint that we are lowering.
struct AsmOperandInfo : public InlineAsm::ConstraintInfo {
- /// ConstraintCode - This contains the actual string for the code, like "m".
- /// TargetLowering picks the 'best' code from ConstraintInfo::Codes that
- /// most closely matches the operand.
+ /// This contains the actual string for the code, like "m". TargetLowering
+ /// picks the 'best' code from ConstraintInfo::Codes that most closely
+ /// matches the operand.
std::string ConstraintCode;
- /// ConstraintType - Information about the constraint code, e.g. Register,
- /// RegisterClass, Memory, Other, Unknown.
+ /// Information about the constraint code, e.g. Register, RegisterClass,
+ /// Memory, Other, Unknown.
TargetLowering::ConstraintType ConstraintType;
- /// CallOperandval - If this is the result output operand or a
- /// clobber, this is null, otherwise it is the incoming operand to the
- /// CallInst. This gets modified as the asm is processed.
+ /// If this is the result output operand or a clobber, this is null,
+ /// otherwise it is the incoming operand to the CallInst. This gets
+ /// modified as the asm is processed.
Value *CallOperandVal;
- /// ConstraintVT - The ValueType for the operand value.
+ /// The ValueType for the operand value.
MVT ConstraintVT;
- /// isMatchingInputConstraint - Return true of this is an input operand that
- /// is a matching constraint like "4".
+ /// Return true of this is an input operand that is a matching constraint
+ /// like "4".
bool isMatchingInputConstraint() const;
- /// getMatchedOperand - If this is an input matching constraint, this method
- /// returns the output operand it matches.
+ /// If this is an input matching constraint, this method returns the output
+ /// operand it matches.
unsigned getMatchedOperand() const;
/// Copy constructor for copying from an AsmOperandInfo.
@@ -2187,11 +2146,10 @@ public:
typedef std::vector<AsmOperandInfo> AsmOperandInfoVector;
- /// ParseConstraints - Split up the constraint string from the inline
- /// assembly value into the specific constraints and their prefixes,
- /// and also tie in the associated operand values.
- /// If this returns an empty vector, and if the constraint string itself
- /// isn't empty, there was an error parsing.
+ /// Split up the constraint string from the inline assembly value into the
+ /// specific constraints and their prefixes, and also tie in the associated
+ /// operand values. If this returns an empty vector, and if the constraint
+ /// string itself isn't empty, there was an error parsing.
virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const;
/// Examine constraint type and operand type and determine a weight value.
@@ -2204,41 +2162,37 @@ public:
virtual ConstraintWeight getSingleConstraintMatchWeight(
AsmOperandInfo &info, const char *constraint) const;
- /// ComputeConstraintToUse - Determines the constraint code and constraint
- /// type to use for the specific AsmOperandInfo, setting
- /// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand
- /// being passed in is available, it can be passed in as Op, otherwise an
- /// empty SDValue can be passed.
+ /// Determines the constraint code and constraint type to use for the specific
+ /// AsmOperandInfo, setting OpInfo.ConstraintCode and OpInfo.ConstraintType.
+ /// If the actual operand being passed in is available, it can be passed in as
+ /// Op, otherwise an empty SDValue can be passed.
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
SDValue Op,
SelectionDAG *DAG = 0) const;
- /// getConstraintType - Given a constraint, return the type of constraint it
- /// is for this target.
+ /// Given a constraint, return the type of constraint it is for this target.
virtual ConstraintType getConstraintType(const std::string &Constraint) const;
- /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g.
- /// {edx}), return the register number and the register class for the
- /// register.
+ /// Given a physical register constraint (e.g. {edx}), return the register
+ /// number and the register class for the register.
///
/// Given a register class constraint, like 'r', if this corresponds directly
/// to an LLVM register class, return a register of 0 and the register class
/// pointer.
///
- /// This should only be used for C_Register constraints. On error,
- /// this returns a register number of 0 and a null register class pointer..
+ /// This should only be used for C_Register constraints. On error, this
+ /// returns a register number of 0 and a null register class pointer..
virtual std::pair<unsigned, const TargetRegisterClass*>
getRegForInlineAsmConstraint(const std::string &Constraint,
- EVT VT) const;
+ MVT VT) const;
- /// LowerXConstraint - try to replace an X constraint, which matches anything,
- /// with another that has more specific requirements based on the type of the
- /// corresponding operand. This returns null if there is no replacement to
- /// make.
+ /// Try to replace an X constraint, which matches anything, with another that
+ /// has more specific requirements based on the type of the corresponding
+ /// operand. This returns null if there is no replacement to make.
virtual const char *LowerXConstraint(EVT ConstraintVT) const;
- /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
- /// vector. If it is invalid, don't add anything to Ops.
+ /// Lower the specified operand into the Ops vector. If it is invalid, don't
+ /// add anything to Ops.
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const;
@@ -2257,26 +2211,26 @@ public:
// Instruction Emitting Hooks
//
- // EmitInstrWithCustomInserter - This method should be implemented by targets
- // that mark instructions with the 'usesCustomInserter' flag. These
- // instructions are special in various ways, which require special support to
- // insert. The specified MachineInstr is created but not inserted into any
- // basic blocks, and this method is called to expand it into a sequence of
- // instructions, potentially also creating new basic blocks and control flow.
+ // This method should be implemented by targets that mark instructions with
+ // the 'usesCustomInserter' flag. These instructions are special in various
+ // ways, which require special support to insert. The specified MachineInstr
+ // is created but not inserted into any basic blocks, and this method is
+ // called to expand it into a sequence of instructions, potentially also
+ // creating new basic blocks and control flow.
virtual MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;
- /// AdjustInstrPostInstrSelection - This method should be implemented by
- /// targets that mark instructions with the 'hasPostISelHook' flag. These
- /// instructions must be adjusted after instruction selection by target hooks.
- /// e.g. To fill in optional defs for ARM 's' setting instructions.
+ /// This method should be implemented by targets that mark instructions with
+ /// the 'hasPostISelHook' flag. These instructions must be adjusted after
+ /// instruction selection by target hooks. e.g. To fill in optional defs for
+ /// ARM 's' setting instructions.
virtual void
AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const;
};
-/// GetReturnInfo - Given an LLVM IR type and return type attributes,
-/// compute the return value EVTs and flags, and optionally also
-/// the offsets, if the return value is being lowered to memory.
+/// Given an LLVM IR type and return type attributes, compute the return value
+/// EVTs and flags, and optionally also the offsets, if the return value is
+/// being lowered to memory.
void GetReturnInfo(Type* ReturnType, AttributeSet attr,
SmallVectorImpl<ISD::OutputArg> &Outs,
const TargetLowering &TLI);
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 9958755..7f15b74 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -138,6 +138,10 @@ public:
return StaticDtorSection;
}
+ /// \brief Create a symbol reference to describe the given TLS variable when
+ /// emitting the address in debug info.
+ virtual const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const;
+
protected:
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 7f04119..fd7228a 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -102,11 +102,14 @@ public:
void resetTargetOptions(const MachineFunction *MF) const;
// Interfaces to the major aspects of target machine information:
+ //
// -- Instruction opcode and operand information
// -- Pipelines and scheduling information
// -- Stack frame information
// -- Selection DAG lowering information
//
+ // N.B. These objects may change during compilation. It's not safe to cache
+ // them between functions.
virtual const TargetInstrInfo *getInstrInfo() const { return 0; }
virtual const TargetFrameLowering *getFrameLowering() const { return 0; }
virtual const TargetLowering *getTargetLowering() const { return 0; }
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index 31c4c75..d9c8651 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -42,13 +42,13 @@ namespace llvm {
public:
TargetOptions()
: PrintMachineCode(false), NoFramePointerElim(false),
- NoFramePointerElimNonLeaf(false), LessPreciseFPMADOption(false),
+ LessPreciseFPMADOption(false),
UnsafeFPMath(false), NoInfsFPMath(false),
NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false),
UseSoftFloat(false), NoZerosInBSS(false),
JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false),
GuaranteedTailCallOpt(false), DisableTailCalls(false),
- StackAlignmentOverride(0), RealignStack(true), SSPBufferSize(0),
+ StackAlignmentOverride(0),
EnableFastISel(false), PositionIndependentExecutable(false),
EnableSegmentedStacks(false), UseInitArray(false), TrapFuncName(""),
FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard)
@@ -64,12 +64,6 @@ namespace llvm {
/// elimination optimization, this option should disable it.
unsigned NoFramePointerElim : 1;
- /// NoFramePointerElimNonLeaf - This flag is enabled when the
- /// -disable-non-leaf-fp-elim is specified on the command line. If the
- /// target supports the frame pointer elimination optimization, this option
- /// should disable it for non-leaf functions.
- unsigned NoFramePointerElimNonLeaf : 1;
-
/// DisableFramePointerElim - This returns true if frame pointer elimination
/// optimization should be disabled for the given machine function.
bool DisableFramePointerElim(const MachineFunction &MF) const;
@@ -147,14 +141,6 @@ namespace llvm {
/// StackAlignmentOverride - Override default stack alignment for target.
unsigned StackAlignmentOverride;
- /// RealignStack - This flag indicates whether the stack should be
- /// automatically realigned, if needed.
- unsigned RealignStack : 1;
-
- /// SSPBufferSize - The minimum size of buffers that will receive stack
- /// smashing protection when -fstack-protection is used.
- unsigned SSPBufferSize;
-
/// EnableFastISel - This flag enables fast-path instruction selection
/// which trades away generated code quality in favor of reducing
/// compile time.
@@ -203,9 +189,41 @@ namespace llvm {
/// via the llvm.fma.* intrinsic) will always be honored, regardless of
/// the value of this option.
FPOpFusion::FPOpFusionMode AllowFPOpFusion;
-
- bool operator==(const TargetOptions &);
};
+
+// Comparison operators:
+
+
+inline bool operator==(const TargetOptions &LHS,
+ const TargetOptions &RHS) {
+#define ARE_EQUAL(X) LHS.X == RHS.X
+ return
+ ARE_EQUAL(UnsafeFPMath) &&
+ ARE_EQUAL(NoInfsFPMath) &&
+ ARE_EQUAL(NoNaNsFPMath) &&
+ ARE_EQUAL(HonorSignDependentRoundingFPMathOption) &&
+ ARE_EQUAL(UseSoftFloat) &&
+ ARE_EQUAL(NoZerosInBSS) &&
+ ARE_EQUAL(JITEmitDebugInfo) &&
+ ARE_EQUAL(JITEmitDebugInfoToDisk) &&
+ ARE_EQUAL(GuaranteedTailCallOpt) &&
+ ARE_EQUAL(DisableTailCalls) &&
+ ARE_EQUAL(StackAlignmentOverride) &&
+ ARE_EQUAL(EnableFastISel) &&
+ ARE_EQUAL(PositionIndependentExecutable) &&
+ ARE_EQUAL(EnableSegmentedStacks) &&
+ ARE_EQUAL(UseInitArray) &&
+ ARE_EQUAL(TrapFuncName) &&
+ ARE_EQUAL(FloatABIType) &&
+ ARE_EQUAL(AllowFPOpFusion);
+#undef ARE_EQUAL
+}
+
+inline bool operator!=(const TargetOptions &LHS,
+ const TargetOptions &RHS) {
+ return !(LHS == RHS);
+}
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
index 660d2c4..575cb83 100644
--- a/include/llvm/Target/TargetSchedule.td
+++ b/include/llvm/Target/TargetSchedule.td
@@ -72,11 +72,13 @@ def instregex;
//
// Target hooks allow subtargets to associate LoadLatency and
// HighLatency with groups of opcodes.
+//
+// See MCSchedule.h for detailed comments.
class SchedMachineModel {
int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle.
int MinLatency = -1; // Determines which instrucions are allowed in a group.
// (-1) inorder (0) ooo, (1): inorder +var latencies.
- int ILPWindow = -1; // Cycles of latency likely hidden by hardware buffers.
+ int MicroOpBufferSize = -1; // Max micro-ops that can be buffered.
int LoadLatency = -1; // Cycles for loads to access the cache.
int HighLatency = -1; // Approximation of cycles for "high latency" ops.
int MispredictPenalty = -1; // Extra cycles for a mispredicted branch.
@@ -106,7 +108,7 @@ class ProcResourceKind;
// out-of-order engine that the compiler attempts to conserve.
// Buffered resources may be held for multiple clock cycles, but the
// scheduler does not pin them to a particular clock cycle relative to
-// instruction dispatch. Setting Buffered=0 changes this to an
+// instruction dispatch. Setting BufferSize=0 changes this to an
// in-order resource. In this case, the scheduler counts down from the
// cycle that the instruction issues in-order, forcing an interlock
// with subsequent instructions that require the same resource until
@@ -119,7 +121,7 @@ class ProcResourceUnits<ProcResourceKind kind, int num> {
ProcResourceKind Kind = kind;
int NumUnits = num;
ProcResourceKind Super = ?;
- bit Buffered = 1;
+ int BufferSize = -1;
SchedMachineModel SchedModel = ?;
}
@@ -136,6 +138,7 @@ class ProcResource<int num> : ProcResourceKind,
class ProcResGroup<list<ProcResource> resources> : ProcResourceKind {
list<ProcResource> Resources = resources;
SchedMachineModel SchedModel = ?;
+ int BufferSize = -1;
}
// A target architecture may define SchedReadWrite types and associate
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 563721e..75631b3 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -100,12 +100,12 @@ public:
/// added to the per-module passes.
Pass *Inliner;
- bool DisableSimplifyLibCalls;
bool DisableUnitAtATime;
bool DisableUnrollLoops;
bool BBVectorize;
bool SLPVectorize;
bool LoopVectorize;
+ bool LateVectorize;
private:
/// ExtensionList - This is list of all of the extensions that are registered.
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index f2027ce..d1b6fe1 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -78,11 +78,36 @@ FunctionPass *createThreadSanitizerPass(StringRef BlacklistFile = StringRef());
// checking on loads, stores, and other memory intrinsics.
FunctionPass *createBoundsCheckingPass();
-/// createDebugIRPass - Create and return a pass that modifies a module's
-/// debug metadata to point back to IR instead of the original source file
-ModulePass *createDebugIRPass(StringRef FilenamePostfix,
- bool hideDebugIntrinsics = true,
- bool hideDebugMetadata = true);
+/// createDebugIRPass - Enable interactive stepping through LLVM IR in LLDB (or
+/// GDB) and generate a file with the LLVM IR to be
+/// displayed in the debugger.
+///
+/// Existing debug metadata is preserved (but may be modified) in order to allow
+/// accessing variables in the original source. The line table and file
+/// information is modified to correspond to the lines in the LLVM IR. If
+/// Filename and Directory are empty, a file name is generated based on existing
+/// debug information. If no debug information is available, a temporary file
+/// name is generated.
+///
+/// @param HideDebugIntrinsics Omit debug intrinsics in emitted IR source file.
+/// @param HideDebugMetadata Omit debug metadata in emitted IR source file.
+/// @param Directory Embed this directory in the debug information.
+/// @param Filename Embed this file name in the debug information.
+ModulePass *createDebugIRPass(bool HideDebugIntrinsics,
+ bool HideDebugMetadata,
+ StringRef Directory = StringRef(),
+ StringRef Filename = StringRef());
+
+/// createDebugIRPass - Enable interactive stepping through LLVM IR in LLDB
+/// (or GDB) with an existing IR file on disk. When creating
+/// a DebugIR pass with this function, no source file is
+/// output to disk and the existing one is unmodified. Debug
+/// metadata in the Module is created/updated to point to
+/// the existing textual IR file on disk.
+/// NOTE: If the IR file to be debugged is not on disk, use the version of this
+/// function with parameters in order to generate the file that will be
+/// seen by the debugger.
+ModulePass *createDebugIRPass();
} // End llvm namespace
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index e833aaa..037ab6b 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -23,6 +23,7 @@ class GetElementPtrInst;
class PassInfo;
class TerminatorInst;
class TargetLowering;
+class TargetMachine;
//===----------------------------------------------------------------------===//
//
@@ -119,7 +120,7 @@ Pass *createLICMPass();
//
Pass *createLoopStrengthReducePass();
-Pass *createGlobalMergePass(const TargetLowering *TLI = 0);
+Pass *createGlobalMergePass(const TargetMachine *TM = 0);
//===----------------------------------------------------------------------===//
//
@@ -199,6 +200,19 @@ FunctionPass *createCFGSimplificationPass();
//===----------------------------------------------------------------------===//
//
+// FlattenCFG - flatten CFG, reduce number of conditional branches by using
+// parallel-and and parallel-or mode, etc...
+//
+FunctionPass *createFlattenCFGPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CFG Structurization - Remove irreducible control flow
+//
+Pass *createStructurizeCFGPass();
+
+//===----------------------------------------------------------------------===//
+//
// BreakCriticalEdges - Break all of the critical edges in the CFG by inserting
// a dummy basic block. This pass may be "required" by passes that cannot deal
// with critical edges. For this usage, a pass must call:
@@ -247,9 +261,8 @@ extern char &LowerSwitchID;
// purpose "my LLVM-to-LLVM pass doesn't support the invoke instruction yet"
// lowering pass.
//
-FunctionPass *createLowerInvokePass(const TargetLowering *TLI = 0);
-FunctionPass *createLowerInvokePass(const TargetLowering *TLI,
- bool useExpensiveEHSupport);
+FunctionPass *createLowerInvokePass(const TargetMachine *TM = 0,
+ bool useExpensiveEHSupport = false);
extern char &LowerInvokePassID;
//===----------------------------------------------------------------------===//
@@ -297,15 +310,9 @@ Pass *createLoopDeletionPass();
//===----------------------------------------------------------------------===//
//
-/// createSimplifyLibCallsPass - This pass optimizes specific calls to
-/// specific well-known (library) functions.
-FunctionPass *createSimplifyLibCallsPass();
-
-//===----------------------------------------------------------------------===//
-//
// CodeGenPrepare - This pass prepares a function for instruction selection.
//
-FunctionPass *createCodeGenPreparePass(const TargetLowering *TLI = 0);
+FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = 0);
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 8f1a6e2..65cafe2 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -70,28 +70,6 @@ void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
//
void ReplaceInstWithInst(Instruction *From, Instruction *To);
-/// FindFunctionBackedges - Analyze the specified function to find all of the
-/// loop backedges in the function and return them. This is a relatively cheap
-/// (compared to computing dominators and loop info) analysis.
-///
-/// The output is added to Result, as pairs of <from,to> edge info.
-void FindFunctionBackedges(const Function &F,
- SmallVectorImpl<std::pair<const BasicBlock*,const BasicBlock*> > &Result);
-
-
-/// GetSuccessorNumber - Search for the specified successor of basic block BB
-/// and return its position in the terminator instruction's list of
-/// successors. It is an error to call this with a block that is not a
-/// successor.
-unsigned GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ);
-
-/// isCriticalEdge - Return true if the specified edge is a critical edge.
-/// Critical edges are edges from a block with multiple successors to a block
-/// with multiple predecessors.
-///
-bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,
- bool AllowIdenticalEdges = false);
-
/// SplitCriticalEdge - If this edge is a critical edge, insert a new node to
/// split the critical edge. This will update DominatorTree and
/// DominatorFrontier information if it is available, thus calling this pass
@@ -227,6 +205,15 @@ ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp,
bool Unreachable, MDNode *BranchWeights = 0);
+///
+/// GetIfCondition - Check whether BB is the merge point of a if-region.
+/// If so, return the boolean condition that determines which entry into
+/// BB will be taken. Also, return by references the block that will be
+/// entered from if the condition is true, and the block that will be
+/// entered if the condition is false.
+
+Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
+ BasicBlock *&IfFalse);
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/BlackList.h b/include/llvm/Transforms/Utils/BlackList.h
deleted file mode 100644
index 316b364..0000000
--- a/include/llvm/Transforms/Utils/BlackList.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- BlackList.h - blacklist for sanitizers ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===//
-//
-// This is a utility class for instrumentation passes (like AddressSanitizer
-// or ThreadSanitizer) to avoid instrumenting some functions or global
-// variables based on a user-supplied blacklist.
-//
-// The blacklist disables instrumentation of various functions and global
-// variables. Each line contains a prefix, followed by a wild card expression.
-// Empty lines and lines starting with "#" are ignored.
-// ---
-// # Blacklisted items:
-// fun:*_ZN4base6subtle*
-// global:*global_with_bad_access_or_initialization*
-// global-init:*global_with_initialization_issues*
-// global-init-type:*Namespace::ClassName*
-// src:file_with_tricky_code.cc
-// global-init-src:ignore-global-initializers-issues.cc
-// ---
-// Note that the wild card is in fact an llvm::Regex, but * is automatically
-// replaced with .*
-// This is similar to the "ignore" feature of ThreadSanitizer.
-// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
-//
-//===----------------------------------------------------------------------===//
-//
-
-#include "llvm/ADT/StringMap.h"
-
-namespace llvm {
-class Function;
-class GlobalVariable;
-class Module;
-class Regex;
-class StringRef;
-
-class BlackList {
- public:
- BlackList(const StringRef Path);
- // Returns whether either this function or it's source file are blacklisted.
- bool isIn(const Function &F) const;
- // Returns whether either this global or it's source file are blacklisted.
- bool isIn(const GlobalVariable &G) const;
- // Returns whether this module is blacklisted by filename.
- bool isIn(const Module &M) const;
- // Returns whether a global should be excluded from initialization checking.
- bool isInInit(const GlobalVariable &G) const;
- private:
- StringMap<Regex*> Entries;
-
- bool inSection(const StringRef Section, const StringRef Query) const;
-};
-
-} // namespace llvm
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 2678250..65755d0 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -39,9 +39,10 @@ class DataLayout;
class TargetLibraryInfo;
class TargetTransformInfo;
class DIBuilder;
+class AliasAnalysis;
template<typename T> class SmallVectorImpl;
-
+
//===----------------------------------------------------------------------===//
// Local constant propagation.
//
@@ -79,7 +80,7 @@ bool RecursivelyDeleteTriviallyDeadInstructions(Value *V,
/// too, recursively. Return true if a change was made.
bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=0);
-
+
/// SimplifyInstructionsInBlock - Scan the specified basic block and try to
/// simplify any instructions in it and recursively delete dead instructions.
///
@@ -87,7 +88,7 @@ bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=0);
/// instructions in other blocks as well in this block.
bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
-
+
//===----------------------------------------------------------------------===//
// Control Flow Graph Restructuring.
//
@@ -105,15 +106,15 @@ bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = 0,
/// recursively fold the 'and' to 0.
void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
DataLayout *TD = 0);
-
-
+
+
/// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its
/// predecessor is known to have one successor (BB!). Eliminate the edge
/// between them, moving the instructions in the predecessor into BB. This
/// deletes the predecessor block.
///
void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, Pass *P = 0);
-
+
/// TryToSimplifyUncondBranchFromEmptyBlock - BB is known to contain an
/// unconditional branch, and contains no instructions other than PHI nodes,
@@ -138,6 +139,12 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
const DataLayout *TD = 0);
+/// FlatternCFG - This function is used to flatten a CFG. For
+/// example, it uses parallel-and and parallel-or mode to collapse
+// if-conditions and merge if-regions with identical statements.
+///
+bool FlattenCFG(BasicBlock *BB, AliasAnalysis *AA = 0);
+
/// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a branch,
/// and if a predecessor branches to us and one of our successors, fold the
/// setcc into the predecessor and use logical operations to pick the right
@@ -156,7 +163,7 @@ AllocaInst *DemoteRegToStack(Instruction &X,
/// DemotePHIToStack - This function takes a virtual register computed by a phi
/// node and replaces it with a slot in the stack frame, allocated via alloca.
-/// The phi node is deleted and it returns the pointer to the alloca inserted.
+/// The phi node is deleted and it returns the pointer to the alloca inserted.
AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0);
/// getOrEnforceKnownAlignment - If the specified pointer has an alignment that
@@ -179,18 +186,19 @@ static inline unsigned getKnownAlignment(Value *V, const DataLayout *TD = 0) {
template<typename IRBuilderTy>
Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
bool NoAssumptions = false) {
- gep_type_iterator GTI = gep_type_begin(GEP);
- Type *IntPtrTy = TD.getIntPtrType(GEP->getContext());
+ GEPOperator *GEPOp = cast<GEPOperator>(GEP);
+ Type *IntPtrTy = TD.getIntPtrType(GEP->getType());
Value *Result = Constant::getNullValue(IntPtrTy);
// If the GEP is inbounds, we know that none of the addressing operations will
// overflow in an unsigned sense.
- bool isInBounds = cast<GEPOperator>(GEP)->isInBounds() && !NoAssumptions;
+ bool isInBounds = GEPOp->isInBounds() && !NoAssumptions;
// Build a mask for high order bits.
- unsigned IntPtrWidth = TD.getPointerSizeInBits();
- uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth);
+ unsigned IntPtrWidth = IntPtrTy->getScalarType()->getIntegerBitWidth();
+ uint64_t PtrSizeMask = ~0ULL >> (64 - IntPtrWidth);
+ gep_type_iterator GTI = gep_type_begin(GEP);
for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
++i, ++GTI) {
Value *Op = *i;
diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h
index bb7fc06..98a19ed 100644
--- a/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -18,6 +18,9 @@ namespace llvm {
class Module;
class Function;
+class GlobalValue;
+class GlobalVariable;
+template <class PtrType, unsigned SmallSize> class SmallPtrSet;
/// Append F to the list of global ctors of module M with the given Priority.
/// This wraps the function in the appropriate structure and stores it along
@@ -28,6 +31,11 @@ void appendToGlobalCtors(Module &M, Function *F, int Priority);
/// Same as appendToGlobalCtors(), but for global dtors.
void appendToGlobalDtors(Module &M, Function *F, int Priority);
+/// \brief Given "llvm.used" or "llvm.compiler.used" as a global name, collect
+/// the initializer elements of that global in Set and return the global itself.
+GlobalVariable *collectUsedGlobalVariables(Module &M,
+ SmallPtrSet<GlobalValue *, 8> &Set,
+ bool CompilerUsed);
} // End llvm namespace
#endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h
index 52a6157..2f28f33 100644
--- a/include/llvm/Transforms/Utils/PromoteMemToReg.h
+++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -15,29 +15,34 @@
#ifndef LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
#define LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
-#include <vector>
+#include "llvm/ADT/ArrayRef.h"
namespace llvm {
class AllocaInst;
+class DataLayout;
class DominatorTree;
class AliasSetTracker;
-/// isAllocaPromotable - Return true if this alloca is legal for promotion.
-/// This is true if there are only loads and stores to the alloca...
+/// \brief Return true if this alloca is legal for promotion.
///
-bool isAllocaPromotable(const AllocaInst *AI);
-
-/// PromoteMemToReg - Promote the specified list of alloca instructions into
-/// scalar registers, inserting PHI nodes as appropriate. This function makes
-/// use of DominanceFrontier information. This function does not modify the CFG
-/// of the function at all. All allocas must be from the same function.
+/// This is true if there are only loads, stores, and lifetime markers
+/// (transitively) using this alloca. This also enforces that there is only
+/// ever one layer of bitcasts or GEPs between the alloca and the lifetime
+/// markers.
+bool isAllocaPromotable(const AllocaInst *AI, const DataLayout *DL);
+
+/// \brief Promote the specified list of alloca instructions into scalar
+/// registers, inserting PHI nodes as appropriate.
+///
+/// This function makes use of DominanceFrontier information. This function
+/// does not modify the CFG of the function at all. All allocas must be from
+/// the same function.
///
/// If AST is specified, the specified tracker is updated to reflect changes
/// made to the IR.
-///
-void PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
- DominatorTree &DT, AliasSetTracker *AST = 0);
+void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
+ const DataLayout *DL, AliasSetTracker *AST = 0);
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h
index cd04893..0c0e5de 100644
--- a/include/llvm/Transforms/Utils/SSAUpdater.h
+++ b/include/llvm/Transforms/Utils/SSAUpdater.h
@@ -28,82 +28,90 @@ namespace llvm {
class Use;
class Value;
-/// SSAUpdater - This class updates SSA form for a set of values defined in
-/// multiple blocks. This is used when code duplication or another unstructured
+/// \brief Helper class for SSA formation on a set of values defined in
+/// multiple blocks.
+///
+/// This is used when code duplication or another unstructured
/// transformation wants to rewrite a set of uses of one value with uses of a
/// set of values.
class SSAUpdater {
friend class SSAUpdaterTraits<SSAUpdater>;
private:
- /// AvailableVals - This keeps track of which value to use on a per-block
- /// basis. When we insert PHI nodes, we keep track of them here.
+ /// This keeps track of which value to use on a per-block basis. When we
+ /// insert PHI nodes, we keep track of them here.
//typedef DenseMap<BasicBlock*, Value*> AvailableValsTy;
void *AV;
/// ProtoType holds the type of the values being rewritten.
Type *ProtoType;
- // PHI nodes are given a name based on ProtoName.
+ /// PHI nodes are given a name based on ProtoName.
std::string ProtoName;
- /// InsertedPHIs - If this is non-null, the SSAUpdater adds all PHI nodes that
- /// it creates to the vector.
+ /// If this is non-null, the SSAUpdater adds all PHI nodes that it creates to
+ /// the vector.
SmallVectorImpl<PHINode*> *InsertedPHIs;
public:
- /// SSAUpdater constructor. If InsertedPHIs is specified, it will be filled
+ /// If InsertedPHIs is specified, it will be filled
/// in with all PHI Nodes created by rewriting.
explicit SSAUpdater(SmallVectorImpl<PHINode*> *InsertedPHIs = 0);
~SSAUpdater();
- /// Initialize - Reset this object to get ready for a new set of SSA
- /// updates with type 'Ty'. PHI nodes get a name based on 'Name'.
+ /// \brief Reset this object to get ready for a new set of SSA updates with
+ /// type 'Ty'.
+ ///
+ /// PHI nodes get a name based on 'Name'.
void Initialize(Type *Ty, StringRef Name);
- /// AddAvailableValue - Indicate that a rewritten value is available at the
- /// end of the specified block with the specified value.
+ /// \brief Indicate that a rewritten value is available in the specified block
+ /// with the specified value.
void AddAvailableValue(BasicBlock *BB, Value *V);
- /// HasValueForBlock - Return true if the SSAUpdater already has a value for
- /// the specified block.
+ /// \brief Return true if the SSAUpdater already has a value for the specified
+ /// block.
bool HasValueForBlock(BasicBlock *BB) const;
- /// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
- /// live at the end of the specified block.
+ /// \brief Construct SSA form, materializing a value that is live at the end
+ /// of the specified block.
Value *GetValueAtEndOfBlock(BasicBlock *BB);
- /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
- /// is live in the middle of the specified block.
+ /// \brief Construct SSA form, materializing a value that is live in the
+ /// middle of the specified block.
///
- /// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one
- /// important case: if there is a definition of the rewritten value after the
- /// 'use' in BB. Consider code like this:
+ /// \c GetValueInMiddleOfBlock is the same as \c GetValueAtEndOfBlock except
+ /// in one important case: if there is a definition of the rewritten value
+ /// after the 'use' in BB. Consider code like this:
///
+ /// \code
/// X1 = ...
/// SomeBB:
/// use(X)
/// X2 = ...
/// br Cond, SomeBB, OutBB
+ /// \endcode
///
/// In this case, there are two values (X1 and X2) added to the AvailableVals
/// set by the client of the rewriter, and those values are both live out of
/// their respective blocks. However, the use of X happens in the *middle* of
/// a block. Because of this, we need to insert a new PHI node in SomeBB to
/// merge the appropriate values, and this value isn't live out of the block.
- ///
Value *GetValueInMiddleOfBlock(BasicBlock *BB);
- /// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes,
- /// which use their value in the corresponding predecessor. Note that this
- /// will not work if the use is supposed to be rewritten to a value defined in
- /// the same block as the use, but above it. Any 'AddAvailableValue's added
- /// for the use's block will be considered to be below it.
+ /// \brief Rewrite a use of the symbolic value.
+ ///
+ /// This handles PHI nodes, which use their value in the corresponding
+ /// predecessor. Note that this will not work if the use is supposed to be
+ /// rewritten to a value defined in the same block as the use, but above it.
+ /// Any 'AddAvailableValue's added for the use's block will be considered to
+ /// be below it.
void RewriteUse(Use &U);
- /// RewriteUseAfterInsertions - Rewrite a use, just like RewriteUse. However,
- /// this version of the method can rewrite uses in the same block as a
- /// definition, because it assumes that all uses of a value are below any
+ /// \brief Rewrite a use like \c RewriteUse but handling in-block definitions.
+ ///
+ /// This version of the method can rewrite uses in the same block as
+ /// a definition, because it assumes that all uses of a value are below any
/// inserted values.
void RewriteUseAfterInsertions(Use &U);
@@ -113,15 +121,15 @@ private:
void operator=(const SSAUpdater&) LLVM_DELETED_FUNCTION;
SSAUpdater(const SSAUpdater&) LLVM_DELETED_FUNCTION;
};
-
-/// LoadAndStorePromoter - This little helper class provides a convenient way to
-/// promote a collection of loads and stores into SSA Form using the SSAUpdater.
+
+/// \brief Helper class for promoting a collection of loads and stores into SSA
+/// Form using the SSAUpdater.
+///
/// This handles complexities that SSAUpdater doesn't, such as multiple loads
/// and stores in one block.
///
/// Clients of this class are expected to subclass this and implement the
/// virtual methods.
-///
class LoadAndStorePromoter {
protected:
SSAUpdater &SSA;
@@ -130,34 +138,36 @@ public:
SSAUpdater &S, StringRef Name = StringRef());
virtual ~LoadAndStorePromoter() {}
- /// run - This does the promotion. Insts is a list of loads and stores to
- /// promote, and Name is the basename for the PHIs to insert. After this is
- /// complete, the loads and stores are removed from the code.
+ /// \brief This does the promotion.
+ ///
+ /// Insts is a list of loads and stores to promote, and Name is the basename
+ /// for the PHIs to insert. After this is complete, the loads and stores are
+ /// removed from the code.
void run(const SmallVectorImpl<Instruction*> &Insts) const;
- /// Return true if the specified instruction is in the Inst list (which was
- /// passed into the run method). Clients should implement this with a more
- /// efficient version if possible.
+ /// \brief Return true if the specified instruction is in the Inst list.
+ ///
+ /// The Insts list is the one passed into the constructor. Clients should
+ /// implement this with a more efficient version if possible.
virtual bool isInstInList(Instruction *I,
const SmallVectorImpl<Instruction*> &Insts) const;
- /// doExtraRewritesBeforeFinalDeletion - This hook is invoked after all the
- /// stores are found and inserted as available values, but
+ /// \brief This hook is invoked after all the stores are found and inserted as
+ /// available values.
virtual void doExtraRewritesBeforeFinalDeletion() const {
}
- /// replaceLoadWithValue - Clients can choose to implement this to get
- /// notified right before a load is RAUW'd another value.
+ /// \brief Clients can choose to implement this to get notified right before
+ /// a load is RAUW'd another value.
virtual void replaceLoadWithValue(LoadInst *LI, Value *V) const {
}
- /// This is called before each instruction is deleted.
+ /// \brief Called before each instruction is deleted.
virtual void instructionDeleted(Instruction *I) const {
}
- /// updateDebugInfo - This is called to update debug info associated with the
- /// instruction.
+ /// \brief Called to update debug info associated with the instruction.
virtual void updateDebugInfo(Instruction *I) const {
}
};
diff --git a/include/llvm/Transforms/Utils/SpecialCaseList.h b/include/llvm/Transforms/Utils/SpecialCaseList.h
new file mode 100644
index 0000000..787ddb0
--- /dev/null
+++ b/include/llvm/Transforms/Utils/SpecialCaseList.h
@@ -0,0 +1,102 @@
+//===-- SpecialCaseList.h - special case list for sanitizers ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+//
+// This is a utility class for instrumentation passes (like AddressSanitizer
+// or ThreadSanitizer) to avoid instrumenting some functions or global
+// variables based on a user-supplied list.
+//
+// The list can also specify categories for specific globals, which can be used
+// to instruct an instrumentation pass to treat certain functions or global
+// variables in a specific way, such as by omitting certain aspects of
+// instrumentation while keeping others, or informing the instrumentation pass
+// that a specific uninstrumentable function has certain semantics, thus
+// allowing the pass to instrument callers according to those semantics.
+//
+// For example, AddressSanitizer uses the "init" category for globals whose
+// initializers should not be instrumented, but which in all other respects
+// should be instrumented.
+//
+// Each line contains a prefix, followed by a colon and a wild card expression,
+// followed optionally by an equals sign and an instrumentation-specific
+// category. Empty lines and lines starting with "#" are ignored.
+// ---
+// # Blacklisted items:
+// fun:*_ZN4base6subtle*
+// global:*global_with_bad_access_or_initialization*
+// global:*global_with_initialization_issues*=init
+// type:*Namespace::ClassName*=init
+// src:file_with_tricky_code.cc
+// src:ignore-global-initializers-issues.cc=init
+//
+// # Functions with pure functional semantics:
+// fun:cos=functional
+// fun:sin=functional
+// ---
+// Note that the wild card is in fact an llvm::Regex, but * is automatically
+// replaced with .*
+// This is similar to the "ignore" feature of ThreadSanitizer.
+// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
+//
+//===----------------------------------------------------------------------===//
+//
+
+#include "llvm/ADT/StringMap.h"
+
+namespace llvm {
+class Function;
+class GlobalVariable;
+class MemoryBuffer;
+class Module;
+class Regex;
+class StringRef;
+
+class SpecialCaseList {
+ public:
+ SpecialCaseList(const StringRef Path);
+ SpecialCaseList(const MemoryBuffer *MB);
+ ~SpecialCaseList();
+
+ /// Returns whether either this function or its source file are listed in the
+ /// given category, which may be omitted to search the empty category.
+ bool isIn(const Function &F, const StringRef Category = StringRef()) const;
+
+ /// Returns whether this global, its type or its source file are listed in the
+ /// given category, which may be omitted to search the empty category.
+ bool isIn(const GlobalVariable &G,
+ const StringRef Category = StringRef()) const;
+
+ /// Returns whether this module is listed in the given category, which may be
+ /// omitted to search the empty category.
+ bool isIn(const Module &M, const StringRef Category = StringRef()) const;
+
+ /// Returns whether either this function or its source file are listed in any
+ /// category. Category will contain the name of an arbitrary category in
+ /// which this function is listed.
+ bool findCategory(const Function &F, StringRef &Category) const;
+
+ /// Returns whether this global, its type or its source file are listed in any
+ /// category. Category will contain the name of an arbitrary category in
+ /// which this global is listed.
+ bool findCategory(const GlobalVariable &G, StringRef &Category) const;
+
+ /// Returns whether this module is listed in any category. Category will
+ /// contain the name of an arbitrary category in which this module is listed.
+ bool findCategory(const Module &M, StringRef &Category) const;
+
+ private:
+ struct Entry;
+ StringMap<StringMap<Entry> > Entries;
+
+ void init(const MemoryBuffer *MB);
+ bool findCategory(const StringRef Section, const StringRef Query,
+ StringRef &Category) const;
+ bool inSectionCategory(const StringRef Section, const StringRef Query,
+ const StringRef Category) const;
+};
+
+} // namespace llvm