APFloat.h | APFloat.h | |||
---|---|---|---|---|
skipping to change at line 100 | skipping to change at line 100 | |||
Optional ability to detect underflow tininess before rounding. | Optional ability to detect underflow tininess before rounding. | |||
New formats: x87 in single and double precision mode (IEEE apart | New formats: x87 in single and double precision mode (IEEE apart | |||
from extended exponent range) (hard). | from extended exponent range) (hard). | |||
New operations: sqrt, IEEE remainder, C90 fmod, nextafter, | New operations: sqrt, IEEE remainder, C90 fmod, nextafter, | |||
nexttoward. | nexttoward. | |||
*/ | */ | |||
#ifndef LLVM_FLOAT_H | #ifndef LLVM_ADT_APFLOAT_H | |||
#define LLVM_FLOAT_H | #define LLVM_ADT_APFLOAT_H | |||
// APInt contains static functions implementing bignum arithmetic. | // APInt contains static functions implementing bignum arithmetic. | |||
#include "llvm/ADT/APInt.h" | #include "llvm/ADT/APInt.h" | |||
namespace llvm { | namespace llvm { | |||
/* Exponents are stored as signed numbers. */ | /* Exponents are stored as signed numbers. */ | |||
typedef signed short exponent_t; | typedef signed short exponent_t; | |||
struct fltSemantics; | struct fltSemantics; | |||
skipping to change at line 187 | skipping to change at line 187 | |||
enum uninitializedTag { | enum uninitializedTag { | |||
uninitialized | uninitialized | |||
}; | }; | |||
// Constructors. | // Constructors. | |||
APFloat(const fltSemantics &); // Default construct to 0.0 | APFloat(const fltSemantics &); // Default construct to 0.0 | |||
APFloat(const fltSemantics &, StringRef); | APFloat(const fltSemantics &, StringRef); | |||
APFloat(const fltSemantics &, integerPart); | APFloat(const fltSemantics &, integerPart); | |||
APFloat(const fltSemantics &, fltCategory, bool negative); | APFloat(const fltSemantics &, fltCategory, bool negative); | |||
APFloat(const fltSemantics &, uninitializedTag); | APFloat(const fltSemantics &, uninitializedTag); | |||
APFloat(const fltSemantics &, const APInt &); | ||||
explicit APFloat(double d); | explicit APFloat(double d); | |||
explicit APFloat(float f); | explicit APFloat(float f); | |||
explicit APFloat(const APInt &, bool isIEEE = false); | ||||
APFloat(const APFloat &); | APFloat(const APFloat &); | |||
~APFloat(); | ~APFloat(); | |||
// Convenience "constructors" | // Convenience "constructors" | |||
static APFloat getZero(const fltSemantics &Sem, bool Negative = false) { | static APFloat getZero(const fltSemantics &Sem, bool Negative = false) { | |||
return APFloat(Sem, fcZero, Negative); | return APFloat(Sem, fcZero, Negative); | |||
} | } | |||
static APFloat getInf(const fltSemantics &Sem, bool Negative = false) { | static APFloat getInf(const fltSemantics &Sem, bool Negative = false) { | |||
return APFloat(Sem, fcInfinity, Negative); | return APFloat(Sem, fcInfinity, Negative); | |||
} | } | |||
skipping to change at line 303 | skipping to change at line 303 | |||
opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned i nt, | opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned i nt, | |||
bool, roundingMode); | bool, roundingMode); | |||
opStatus convertFromString(StringRef, roundingMode); | opStatus convertFromString(StringRef, roundingMode); | |||
APInt bitcastToAPInt() const; | APInt bitcastToAPInt() const; | |||
double convertToDouble() const; | double convertToDouble() const; | |||
float convertToFloat() const; | float convertToFloat() const; | |||
/* The definition of equality is not straightforward for floating point , | /* The definition of equality is not straightforward for floating point , | |||
so we won't use operator==. Use one of the following, or write | so we won't use operator==. Use one of the following, or write | |||
whatever it is you really mean. */ | whatever it is you really mean. */ | |||
// bool operator==(const APFloat &) const; // DO NOT IMPLEMENT | bool operator==(const APFloat &) const LLVM_DELETED_FUNCTION; | |||
/* IEEE comparison with another floating point number (NaNs | /* IEEE comparison with another floating point number (NaNs | |||
compare unordered, 0==-0). */ | compare unordered, 0==-0). */ | |||
cmpResult compare(const APFloat &) const; | cmpResult compare(const APFloat &) const; | |||
/* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */ | /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */ | |||
bool bitwiseIsEqual(const APFloat &) const; | bool bitwiseIsEqual(const APFloat &) const; | |||
/* Write out a hexadecimal representation of the floating point | /* Write out a hexadecimal representation of the floating point | |||
value to DST, which must be of sufficient size, in the C99 form | value to DST, which must be of sufficient size, in the C99 form | |||
skipping to change at line 330 | skipping to change at line 330 | |||
fltCategory getCategory() const { return category; } | fltCategory getCategory() const { return category; } | |||
const fltSemantics &getSemantics() const { return *semantics; } | const fltSemantics &getSemantics() const { return *semantics; } | |||
bool isZero() const { return category == fcZero; } | bool isZero() const { return category == fcZero; } | |||
bool isNonZero() const { return category != fcZero; } | bool isNonZero() const { return category != fcZero; } | |||
bool isNormal() const { return category == fcNormal; } | bool isNormal() const { return category == fcNormal; } | |||
bool isNaN() const { return category == fcNaN; } | bool isNaN() const { return category == fcNaN; } | |||
bool isInfinity() const { return category == fcInfinity; } | bool isInfinity() const { return category == fcInfinity; } | |||
bool isNegative() const { return sign; } | bool isNegative() const { return sign; } | |||
bool isPosZero() const { return isZero() && !isNegative(); } | bool isPosZero() const { return isZero() && !isNegative(); } | |||
bool isNegZero() const { return isZero() && isNegative(); } | bool isNegZero() const { return isZero() && isNegative(); } | |||
bool isDenormal() const; | ||||
APFloat& operator=(const APFloat &); | APFloat& operator=(const APFloat &); | |||
/// \brief Overload to compute a hash code for an APFloat value. | /// \brief Overload to compute a hash code for an APFloat value. | |||
/// | /// | |||
/// Note that the use of hash codes for floating point values is in gen eral | /// Note that the use of hash codes for floating point values is in gen eral | |||
/// frought with peril. Equality is hard to define for these values. Fo r | /// frought with peril. Equality is hard to define for these values. Fo r | |||
/// example, should negative and positive zero hash to different codes? Are | /// example, should negative and positive zero hash to different codes? Are | |||
/// they equal or not? This hash value implementation specifically | /// they equal or not? This hash value implementation specifically | |||
/// emphasizes producing different codes for different inputs in order to | /// emphasizes producing different codes for different inputs in order to | |||
skipping to change at line 425 | skipping to change at line 426 | |||
roundingMode) const; | roundingMode) const; | |||
opStatus roundSignificandWithExponent(const integerPart *, unsigned int , | opStatus roundSignificandWithExponent(const integerPart *, unsigned int , | |||
int, roundingMode); | int, roundingMode); | |||
APInt convertHalfAPFloatToAPInt() const; | APInt convertHalfAPFloatToAPInt() const; | |||
APInt convertFloatAPFloatToAPInt() const; | APInt convertFloatAPFloatToAPInt() const; | |||
APInt convertDoubleAPFloatToAPInt() const; | APInt convertDoubleAPFloatToAPInt() const; | |||
APInt convertQuadrupleAPFloatToAPInt() const; | APInt convertQuadrupleAPFloatToAPInt() const; | |||
APInt convertF80LongDoubleAPFloatToAPInt() const; | APInt convertF80LongDoubleAPFloatToAPInt() const; | |||
APInt convertPPCDoubleDoubleAPFloatToAPInt() const; | APInt convertPPCDoubleDoubleAPFloatToAPInt() const; | |||
void initFromAPInt(const APInt& api, bool isIEEE = false); | void initFromAPInt(const fltSemantics *Sem, const APInt& api); | |||
void initFromHalfAPInt(const APInt& api); | void initFromHalfAPInt(const APInt& api); | |||
void initFromFloatAPInt(const APInt& api); | void initFromFloatAPInt(const APInt& api); | |||
void initFromDoubleAPInt(const APInt& api); | void initFromDoubleAPInt(const APInt& api); | |||
void initFromQuadrupleAPInt(const APInt &api); | void initFromQuadrupleAPInt(const APInt &api); | |||
void initFromF80LongDoubleAPInt(const APInt& api); | void initFromF80LongDoubleAPInt(const APInt& api); | |||
void initFromPPCDoubleDoubleAPInt(const APInt& api); | void initFromPPCDoubleDoubleAPInt(const APInt& api); | |||
void assign(const APFloat &); | void assign(const APFloat &); | |||
void copySignificand(const APFloat &); | void copySignificand(const APFloat &); | |||
void freeSignificand(); | void freeSignificand(); | |||
skipping to change at line 465 | skipping to change at line 466 | |||
/* The sign bit of this number. */ | /* The sign bit of this number. */ | |||
unsigned int sign: 1; | unsigned int sign: 1; | |||
}; | }; | |||
// See friend declaration above. This additional declaration is required in | // See friend declaration above. This additional declaration is required in | |||
// order to compile LLVM with IBM xlC compiler. | // order to compile LLVM with IBM xlC compiler. | |||
hash_code hash_value(const APFloat &Arg); | hash_code hash_value(const APFloat &Arg); | |||
} /* namespace llvm */ | } /* namespace llvm */ | |||
#endif /* LLVM_FLOAT_H */ | #endif /* LLVM_ADT_APFLOAT_H */ | |||
End of changes. 7 change blocks. | ||||
5 lines changed or deleted | 6 lines changed or added | |||
APInt.h | APInt.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements a class to represent arbitrary precision integral | // This file implements a class to represent arbitrary precision integral | |||
// constant values and operations on them. | // constant values and operations on them. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_APINT_H | #ifndef LLVM_ADT_APINT_H | |||
#define LLVM_APINT_H | #define LLVM_ADT_APINT_H | |||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/MathExtras.h" | #include "llvm/Support/MathExtras.h" | |||
#include <cassert> | #include <cassert> | |||
#include <climits> | #include <climits> | |||
#include <cstring> | #include <cstring> | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
skipping to change at line 277 | skipping to change at line 277 | |||
/// @brief Copy Constructor. | /// @brief Copy Constructor. | |||
APInt(const APInt& that) | APInt(const APInt& that) | |||
: BitWidth(that.BitWidth), VAL(0) { | : BitWidth(that.BitWidth), VAL(0) { | |||
assert(BitWidth && "bitwidth too small"); | assert(BitWidth && "bitwidth too small"); | |||
if (isSingleWord()) | if (isSingleWord()) | |||
VAL = that.VAL; | VAL = that.VAL; | |||
else | else | |||
initSlowCase(that); | initSlowCase(that); | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
/// @brief Move Constructor. | /// @brief Move Constructor. | |||
APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) { | APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) { | |||
that.BitWidth = 0; | that.BitWidth = 0; | |||
} | } | |||
#endif | #endif | |||
/// @brief Destructor. | /// @brief Destructor. | |||
~APInt() { | ~APInt() { | |||
if (!isSingleWord()) | if (!isSingleWord()) | |||
delete [] pVal; | delete [] pVal; | |||
skipping to change at line 430 | skipping to change at line 430 | |||
/// getSignBit - This is just a wrapper function of getSignedMinValue(), and | /// getSignBit - This is just a wrapper function of getSignedMinValue(), and | |||
/// it helps code readability when we want to get a SignBit. | /// it helps code readability when we want to get a SignBit. | |||
/// @brief Get the SignBit for a specific bit width. | /// @brief Get the SignBit for a specific bit width. | |||
static APInt getSignBit(unsigned BitWidth) { | static APInt getSignBit(unsigned BitWidth) { | |||
return getSignedMinValue(BitWidth); | return getSignedMinValue(BitWidth); | |||
} | } | |||
/// @returns the all-ones value for an APInt of the specified bit-width. | /// @returns the all-ones value for an APInt of the specified bit-width. | |||
/// @brief Get the all-ones value. | /// @brief Get the all-ones value. | |||
static APInt getAllOnesValue(unsigned numBits) { | static APInt getAllOnesValue(unsigned numBits) { | |||
return APInt(numBits, -1ULL, true); | return APInt(numBits, UINT64_MAX, true); | |||
} | } | |||
/// @returns the '0' value for an APInt of the specified bit-width. | /// @returns the '0' value for an APInt of the specified bit-width. | |||
/// @brief Get the '0' value. | /// @brief Get the '0' value. | |||
static APInt getNullValue(unsigned numBits) { | static APInt getNullValue(unsigned numBits) { | |||
return APInt(numBits, 0); | return APInt(numBits, 0); | |||
} | } | |||
/// Get an APInt with the same BitWidth as this APInt, just zero mask | /// Get an APInt with the same BitWidth as this APInt, just zero mask | |||
/// the low bits and right shift to the least significant bit. | /// the low bits and right shift to the least significant bit. | |||
skipping to change at line 501 | skipping to change at line 501 | |||
/// Constructs an APInt value that has the bottom loBitsSet bits set. | /// Constructs an APInt value that has the bottom loBitsSet bits set. | |||
/// @param numBits the bitwidth of the result | /// @param numBits the bitwidth of the result | |||
/// @param loBitsSet the number of low-order bits set in the result. | /// @param loBitsSet the number of low-order bits set in the result. | |||
/// @brief Get a value with low bits set | /// @brief Get a value with low bits set | |||
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) { | static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) { | |||
assert(loBitsSet <= numBits && "Too many bits to set!"); | assert(loBitsSet <= numBits && "Too many bits to set!"); | |||
// Handle a degenerate case, to avoid shifting by word size | // Handle a degenerate case, to avoid shifting by word size | |||
if (loBitsSet == 0) | if (loBitsSet == 0) | |||
return APInt(numBits, 0); | return APInt(numBits, 0); | |||
if (loBitsSet == APINT_BITS_PER_WORD) | if (loBitsSet == APINT_BITS_PER_WORD) | |||
return APInt(numBits, -1ULL); | return APInt(numBits, UINT64_MAX); | |||
// For small values, return quickly. | // For small values, return quickly. | |||
if (loBitsSet <= APINT_BITS_PER_WORD) | if (loBitsSet <= APINT_BITS_PER_WORD) | |||
return APInt(numBits, -1ULL >> (APINT_BITS_PER_WORD - loBitsSet)); | return APInt(numBits, UINT64_MAX >> (APINT_BITS_PER_WORD - loBitsSet) ); | |||
return getAllOnesValue(numBits).lshr(numBits - loBitsSet); | return getAllOnesValue(numBits).lshr(numBits - loBitsSet); | |||
} | } | |||
/// \brief Return a value containing V broadcasted over NewLen bits. | ||||
static APInt getSplat(unsigned NewLen, const APInt &V) { | ||||
assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!" | ||||
); | ||||
APInt Val = V.zextOrSelf(NewLen); | ||||
for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1) | ||||
Val |= Val << I; | ||||
return Val; | ||||
} | ||||
/// \brief Determine if two APInts have the same value, after zero-extend ing | /// \brief Determine if two APInts have the same value, after zero-extend ing | |||
/// one of them (if needed!) to ensure that the bit-widths match. | /// one of them (if needed!) to ensure that the bit-widths match. | |||
static bool isSameValue(const APInt &I1, const APInt &I2) { | static bool isSameValue(const APInt &I1, const APInt &I2) { | |||
if (I1.getBitWidth() == I2.getBitWidth()) | if (I1.getBitWidth() == I2.getBitWidth()) | |||
return I1 == I2; | return I1 == I2; | |||
if (I1.getBitWidth() > I2.getBitWidth()) | if (I1.getBitWidth() > I2.getBitWidth()) | |||
return I1 == I2.zext(I1.getBitWidth()); | return I1 == I2.zext(I1.getBitWidth()); | |||
return I1.zext(I2.getBitWidth()) == I2; | return I1.zext(I2.getBitWidth()) == I2; | |||
skipping to change at line 604 | skipping to change at line 615 | |||
// If the bitwidths are the same, we can avoid mucking with memory | // If the bitwidths are the same, we can avoid mucking with memory | |||
if (isSingleWord() && RHS.isSingleWord()) { | if (isSingleWord() && RHS.isSingleWord()) { | |||
VAL = RHS.VAL; | VAL = RHS.VAL; | |||
BitWidth = RHS.BitWidth; | BitWidth = RHS.BitWidth; | |||
return clearUnusedBits(); | return clearUnusedBits(); | |||
} | } | |||
return AssignSlowCase(RHS); | return AssignSlowCase(RHS); | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
/// @brief Move assignment operator. | /// @brief Move assignment operator. | |||
APInt& operator=(APInt&& that) { | APInt& operator=(APInt&& that) { | |||
if (!isSingleWord()) | if (!isSingleWord()) | |||
delete [] pVal; | delete [] pVal; | |||
BitWidth = that.BitWidth; | BitWidth = that.BitWidth; | |||
VAL = that.VAL; | VAL = that.VAL; | |||
that.BitWidth = 0; | that.BitWidth = 0; | |||
skipping to change at line 802 | skipping to change at line 813 | |||
APInt rotr(const APInt &rotateAmt) const; | APInt rotr(const APInt &rotateAmt) const; | |||
/// Perform an unsigned divide operation on this APInt by RHS. Both this and | /// Perform an unsigned divide operation on this APInt by RHS. Both this and | |||
/// RHS are treated as unsigned quantities for purposes of this division. | /// RHS are treated as unsigned quantities for purposes of this division. | |||
/// @returns a new APInt value containing the division result | /// @returns a new APInt value containing the division result | |||
/// @brief Unsigned division operation. | /// @brief Unsigned division operation. | |||
APInt udiv(const APInt &RHS) const; | APInt udiv(const APInt &RHS) const; | |||
/// Signed divide this APInt by APInt RHS. | /// Signed divide this APInt by APInt RHS. | |||
/// @brief Signed division function for APInt. | /// @brief Signed division function for APInt. | |||
APInt sdiv(const APInt &RHS) const { | APInt sdiv(const APInt &RHS) const; | |||
if (isNegative()) | ||||
if (RHS.isNegative()) | ||||
return (-(*this)).udiv(-RHS); | ||||
else | ||||
return -((-(*this)).udiv(RHS)); | ||||
else if (RHS.isNegative()) | ||||
return -(this->udiv(-RHS)); | ||||
return this->udiv(RHS); | ||||
} | ||||
/// Perform an unsigned remainder operation on this APInt with RHS being the | /// Perform an unsigned remainder operation on this APInt with RHS being the | |||
/// divisor. Both this and RHS are treated as unsigned quantities for pur poses | /// divisor. Both this and RHS are treated as unsigned quantities for pur poses | |||
/// of this operation. Note that this is a true remainder operation and n ot | /// of this operation. Note that this is a true remainder operation and n ot | |||
/// a modulo operation because the sign follows the sign of the dividend | /// a modulo operation because the sign follows the sign of the dividend | |||
/// which is *this. | /// which is *this. | |||
/// @returns a new APInt value containing the remainder result | /// @returns a new APInt value containing the remainder result | |||
/// @brief Unsigned remainder operation. | /// @brief Unsigned remainder operation. | |||
APInt urem(const APInt &RHS) const; | APInt urem(const APInt &RHS) const; | |||
/// Signed remainder operation on APInt. | /// Signed remainder operation on APInt. | |||
/// @brief Function for signed remainder operation. | /// @brief Function for signed remainder operation. | |||
APInt srem(const APInt &RHS) const { | APInt srem(const APInt &RHS) const; | |||
if (isNegative()) | ||||
if (RHS.isNegative()) | ||||
return -((-(*this)).urem(-RHS)); | ||||
else | ||||
return -((-(*this)).urem(RHS)); | ||||
else if (RHS.isNegative()) | ||||
return this->urem(-RHS); | ||||
return this->urem(RHS); | ||||
} | ||||
/// Sometimes it is convenient to divide two APInt values and obtain both the | /// Sometimes it is convenient to divide two APInt values and obtain both the | |||
/// quotient and remainder. This function does both operations in the sam e | /// quotient and remainder. This function does both operations in the sam e | |||
/// computation making it a little more efficient. The pair of input argu ments | /// computation making it a little more efficient. The pair of input argu ments | |||
/// may overlap with the pair of output arguments. It is safe to call | /// may overlap with the pair of output arguments. It is safe to call | |||
/// udivrem(X, Y, X, Y), for example. | /// udivrem(X, Y, X, Y), for example. | |||
/// @brief Dual division/remainder interface. | /// @brief Dual division/remainder interface. | |||
static void udivrem(const APInt &LHS, const APInt &RHS, | static void udivrem(const APInt &LHS, const APInt &RHS, | |||
APInt &Quotient, APInt &Remainder); | APInt &Quotient, APInt &Remainder); | |||
static void sdivrem(const APInt &LHS, const APInt &RHS, | static void sdivrem(const APInt &LHS, const APInt &RHS, | |||
APInt &Quotient, APInt &Remainder) { | APInt &Quotient, APInt &Remainder); | |||
if (LHS.isNegative()) { | ||||
if (RHS.isNegative()) | ||||
APInt::udivrem(-LHS, -RHS, Quotient, Remainder); | ||||
else { | ||||
APInt::udivrem(-LHS, RHS, Quotient, Remainder); | ||||
Quotient = -Quotient; | ||||
} | ||||
Remainder = -Remainder; | ||||
} else if (RHS.isNegative()) { | ||||
APInt::udivrem(LHS, -RHS, Quotient, Remainder); | ||||
Quotient = -Quotient; | ||||
} else { | ||||
APInt::udivrem(LHS, RHS, Quotient, Remainder); | ||||
} | ||||
} | ||||
// Operations that return overflow indicators. | // Operations that return overflow indicators. | |||
APInt sadd_ov(const APInt &RHS, bool &Overflow) const; | APInt sadd_ov(const APInt &RHS, bool &Overflow) const; | |||
APInt uadd_ov(const APInt &RHS, bool &Overflow) const; | APInt uadd_ov(const APInt &RHS, bool &Overflow) const; | |||
APInt ssub_ov(const APInt &RHS, bool &Overflow) const; | APInt ssub_ov(const APInt &RHS, bool &Overflow) const; | |||
APInt usub_ov(const APInt &RHS, bool &Overflow) const; | APInt usub_ov(const APInt &RHS, bool &Overflow) const; | |||
APInt sdiv_ov(const APInt &RHS, bool &Overflow) const; | APInt sdiv_ov(const APInt &RHS, bool &Overflow) const; | |||
APInt smul_ov(const APInt &RHS, bool &Overflow) const; | APInt smul_ov(const APInt &RHS, bool &Overflow) const; | |||
APInt umul_ov(const APInt &RHS, bool &Overflow) const; | APInt umul_ov(const APInt &RHS, bool &Overflow) const; | |||
APInt sshl_ov(unsigned Amt, bool &Overflow) const; | APInt sshl_ov(unsigned Amt, bool &Overflow) const; | |||
skipping to change at line 1112 | skipping to change at line 1090 | |||
/// extended, or left alone to make it that width. | /// extended, or left alone to make it that width. | |||
/// @brief Zero extend or truncate to width | /// @brief Zero extend or truncate to width | |||
APInt zextOrSelf(unsigned width) const; | APInt zextOrSelf(unsigned width) const; | |||
/// @} | /// @} | |||
/// @name Bit Manipulation Operators | /// @name Bit Manipulation Operators | |||
/// @{ | /// @{ | |||
/// @brief Set every bit to 1. | /// @brief Set every bit to 1. | |||
void setAllBits() { | void setAllBits() { | |||
if (isSingleWord()) | if (isSingleWord()) | |||
VAL = -1ULL; | VAL = UINT64_MAX; | |||
else { | else { | |||
// Set all the bits in all the words. | // Set all the bits in all the words. | |||
for (unsigned i = 0; i < getNumWords(); ++i) | for (unsigned i = 0; i < getNumWords(); ++i) | |||
pVal[i] = -1ULL; | pVal[i] = UINT64_MAX; | |||
} | } | |||
// Clear the unused ones | // Clear the unused ones | |||
clearUnusedBits(); | clearUnusedBits(); | |||
} | } | |||
/// Set the given bit to 1 whose position is given as "bitPosition". | /// Set the given bit to 1 whose position is given as "bitPosition". | |||
/// @brief Set a given bit to 1. | /// @brief Set a given bit to 1. | |||
void setBit(unsigned bitPosition); | void setBit(unsigned bitPosition); | |||
/// @brief Set every bit to 0. | /// @brief Set every bit to 0. | |||
skipping to change at line 1141 | skipping to change at line 1119 | |||
memset(pVal, 0, getNumWords() * APINT_WORD_SIZE); | memset(pVal, 0, getNumWords() * APINT_WORD_SIZE); | |||
} | } | |||
/// Set the given bit to 0 whose position is given as "bitPosition". | /// Set the given bit to 0 whose position is given as "bitPosition". | |||
/// @brief Set a given bit to 0. | /// @brief Set a given bit to 0. | |||
void clearBit(unsigned bitPosition); | void clearBit(unsigned bitPosition); | |||
/// @brief Toggle every bit to its opposite value. | /// @brief Toggle every bit to its opposite value. | |||
void flipAllBits() { | void flipAllBits() { | |||
if (isSingleWord()) | if (isSingleWord()) | |||
VAL ^= -1ULL; | VAL ^= UINT64_MAX; | |||
else { | else { | |||
for (unsigned i = 0; i < getNumWords(); ++i) | for (unsigned i = 0; i < getNumWords(); ++i) | |||
pVal[i] ^= -1ULL; | pVal[i] ^= UINT64_MAX; | |||
} | } | |||
clearUnusedBits(); | clearUnusedBits(); | |||
} | } | |||
/// Toggle a given bit to its opposite value whose position is given | /// Toggle a given bit to its opposite value whose position is given | |||
/// as "bitPosition". | /// as "bitPosition". | |||
/// @brief Toggles a given bit to its opposite value. | /// @brief Toggles a given bit to its opposite value. | |||
void flipBit(unsigned bitPosition); | void flipBit(unsigned bitPosition); | |||
/// @} | /// @} | |||
skipping to change at line 1190 | skipping to change at line 1168 | |||
/// computations to see how "wide" the value is. | /// computations to see how "wide" the value is. | |||
/// @brief Compute the number of active bits in the value | /// @brief Compute the number of active bits in the value | |||
unsigned getActiveBits() const { | unsigned getActiveBits() const { | |||
return BitWidth - countLeadingZeros(); | return BitWidth - countLeadingZeros(); | |||
} | } | |||
/// This function returns the number of active words in the value of this | /// This function returns the number of active words in the value of this | |||
/// APInt. This is used in conjunction with getActiveData to extract the raw | /// APInt. This is used in conjunction with getActiveData to extract the raw | |||
/// value of the APInt. | /// value of the APInt. | |||
unsigned getActiveWords() const { | unsigned getActiveWords() const { | |||
return whichWord(getActiveBits()-1) + 1; | unsigned numActiveBits = getActiveBits(); | |||
return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1; | ||||
} | } | |||
/// Computes the minimum bit width for this APInt while considering it to be | /// Computes the minimum bit width for this APInt while considering it to be | |||
/// a signed (and probably negative) value. If the value is not negative, | /// a signed (and probably negative) value. If the value is not negative, | |||
/// this function returns the same value as getActiveBits()+1. Otherwise, it | /// this function returns the same value as getActiveBits()+1. Otherwise, it | |||
/// returns the smallest bit width that will retain the negative value. F or | /// returns the smallest bit width that will retain the negative value. F or | |||
/// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so | /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so | |||
/// for -1, this function will always return 1. | /// for -1, this function will always return 1. | |||
/// @brief Get the minimum bit size for this signed APInt | /// @brief Get the minimum bit size for this signed APInt | |||
unsigned getMinSignedBits() const { | unsigned getMinSignedBits() const { | |||
End of changes. 15 change blocks. | ||||
48 lines changed or deleted | 28 lines changed or added | |||
APSInt.h | APSInt.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements the APSInt class, which is a simple class that | // This file implements the APSInt class, which is a simple class that | |||
// represents an arbitrary sized integer that knows its signedness. | // represents an arbitrary sized integer that knows its signedness. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_APSINT_H | #ifndef LLVM_ADT_APSINT_H | |||
#define LLVM_APSINT_H | #define LLVM_ADT_APSINT_H | |||
#include "llvm/ADT/APInt.h" | #include "llvm/ADT/APInt.h" | |||
namespace llvm { | namespace llvm { | |||
class APSInt : public APInt { | class APSInt : public APInt { | |||
bool IsUnsigned; | bool IsUnsigned; | |||
public: | public: | |||
/// Default constructor that creates an uninitialized APInt. | /// Default constructor that creates an uninitialized APInt. | |||
explicit APSInt() {} | explicit APSInt() : IsUnsigned(false) {} | |||
/// APSInt ctor - Create an APSInt with the specified width, default to | /// APSInt ctor - Create an APSInt with the specified width, default to | |||
/// unsigned. | /// unsigned. | |||
explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) | explicit APSInt(uint32_t BitWidth, bool isUnsigned = true) | |||
: APInt(BitWidth, 0), IsUnsigned(isUnsigned) {} | : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {} | |||
explicit APSInt(const APInt &I, bool isUnsigned = true) | explicit APSInt(const APInt &I, bool isUnsigned = true) | |||
: APInt(I), IsUnsigned(isUnsigned) {} | : APInt(I), IsUnsigned(isUnsigned) {} | |||
APSInt &operator=(const APSInt &RHS) { | APSInt &operator=(const APSInt &RHS) { | |||
skipping to change at line 164 | skipping to change at line 164 | |||
APSInt operator<<(unsigned Bits) const { | APSInt operator<<(unsigned Bits) const { | |||
return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned); | return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned); | |||
} | } | |||
APSInt& operator<<=(unsigned Amt) { | APSInt& operator<<=(unsigned Amt) { | |||
*this = *this << Amt; | *this = *this << Amt; | |||
return *this; | return *this; | |||
} | } | |||
APSInt& operator++() { | APSInt& operator++() { | |||
static_cast<APInt&>(*this)++; | ++(static_cast<APInt&>(*this)); | |||
return *this; | return *this; | |||
} | } | |||
APSInt& operator--() { | APSInt& operator--() { | |||
static_cast<APInt&>(*this)--; | --(static_cast<APInt&>(*this)); | |||
return *this; | return *this; | |||
} | } | |||
APSInt operator++(int) { | APSInt operator++(int) { | |||
return APSInt(++static_cast<APInt&>(*this), IsUnsigned); | return APSInt(++static_cast<APInt&>(*this), IsUnsigned); | |||
} | } | |||
APSInt operator--(int) { | APSInt operator--(int) { | |||
return APSInt(--static_cast<APInt&>(*this), IsUnsigned); | return APSInt(--static_cast<APInt&>(*this), IsUnsigned); | |||
} | } | |||
APSInt operator-() const { | APSInt operator-() const { | |||
return APSInt(-static_cast<const APInt&>(*this), IsUnsigned); | return APSInt(-static_cast<const APInt&>(*this), IsUnsigned); | |||
End of changes. 4 change blocks. | ||||
5 lines changed or deleted | 5 lines changed or added | |||
AliasAnalysis.h | AliasAnalysis.h | |||
---|---|---|---|---|
skipping to change at line 37 | skipping to change at line 37 | |||
// alias, regardless of the value of the Size component. | // alias, regardless of the value of the Size component. | |||
// - NoAlias doesn't imply inequal pointers. The most obvious example of t his | // - NoAlias doesn't imply inequal pointers. The most obvious example of t his | |||
// is two pointers to constant memory. Even if they are equal, constant | // is two pointers to constant memory. Even if they are equal, constant | |||
// memory is never stored to, so there will never be any dependencies. | // memory is never stored to, so there will never be any dependencies. | |||
// In this and other situations, the pointers may be both NoAlias and | // In this and other situations, the pointers may be both NoAlias and | |||
// MustAlias at the same time. The current API can only return one resul t, | // MustAlias at the same time. The current API can only return one resul t, | |||
// though this is rarely a problem in practice. | // though this is rarely a problem in practice. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_ALIAS_ANALYSIS_H | #ifndef LLVM_ANALYSIS_ALIASANALYSIS_H | |||
#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H | #define LLVM_ANALYSIS_ALIASANALYSIS_H | |||
#include "llvm/Support/CallSite.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/Support/CallSite.h" | ||||
namespace llvm { | namespace llvm { | |||
class LoadInst; | class LoadInst; | |||
class StoreInst; | class StoreInst; | |||
class VAArgInst; | class VAArgInst; | |||
class DataLayout; | class DataLayout; | |||
class TargetLibraryInfo; | class TargetLibraryInfo; | |||
class Pass; | class Pass; | |||
class AnalysisUsage; | class AnalysisUsage; | |||
skipping to change at line 376 | skipping to change at line 376 | |||
default: return NoModRef; | default: return NoModRef; | |||
} | } | |||
} | } | |||
/// getModRefInfo - A convenience wrapper. | /// getModRefInfo - A convenience wrapper. | |||
ModRefResult getModRefInfo(const Instruction *I, | ModRefResult getModRefInfo(const Instruction *I, | |||
const Value *P, uint64_t Size) { | const Value *P, uint64_t Size) { | |||
return getModRefInfo(I, Location(P, Size)); | return getModRefInfo(I, Location(P, Size)); | |||
} | } | |||
/// getModRefInfo (for call sites) - Return whether information about whe ther | /// getModRefInfo (for call sites) - Return information about whether | |||
/// a particular call site modifies or reads the specified memory locatio n. | /// a particular call site modifies or reads the specified memory locatio n. | |||
virtual ModRefResult getModRefInfo(ImmutableCallSite CS, | virtual ModRefResult getModRefInfo(ImmutableCallSite CS, | |||
const Location &Loc); | const Location &Loc); | |||
/// getModRefInfo (for call sites) - A convenience wrapper. | /// getModRefInfo (for call sites) - A convenience wrapper. | |||
ModRefResult getModRefInfo(ImmutableCallSite CS, | ModRefResult getModRefInfo(ImmutableCallSite CS, | |||
const Value *P, uint64_t Size) { | const Value *P, uint64_t Size) { | |||
return getModRefInfo(CS, Location(P, Size)); | return getModRefInfo(CS, Location(P, Size)); | |||
} | } | |||
/// getModRefInfo (for calls) - Return whether information about whether | /// getModRefInfo (for calls) - Return information about whether | |||
/// a particular call modifies or reads the specified memory location. | /// a particular call modifies or reads the specified memory location. | |||
ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) { | ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) { | |||
return getModRefInfo(ImmutableCallSite(C), Loc); | return getModRefInfo(ImmutableCallSite(C), Loc); | |||
} | } | |||
/// getModRefInfo (for calls) - A convenience wrapper. | /// getModRefInfo (for calls) - A convenience wrapper. | |||
ModRefResult getModRefInfo(const CallInst *C, const Value *P, uint64_t Si ze) { | ModRefResult getModRefInfo(const CallInst *C, const Value *P, uint64_t Si ze) { | |||
return getModRefInfo(C, Location(P, Size)); | return getModRefInfo(C, Location(P, Size)); | |||
} | } | |||
/// getModRefInfo (for invokes) - Return whether information about whethe r | /// getModRefInfo (for invokes) - Return information about whether | |||
/// a particular invoke modifies or reads the specified memory location. | /// a particular invoke modifies or reads the specified memory location. | |||
ModRefResult getModRefInfo(const InvokeInst *I, | ModRefResult getModRefInfo(const InvokeInst *I, | |||
const Location &Loc) { | const Location &Loc) { | |||
return getModRefInfo(ImmutableCallSite(I), Loc); | return getModRefInfo(ImmutableCallSite(I), Loc); | |||
} | } | |||
/// getModRefInfo (for invokes) - A convenience wrapper. | /// getModRefInfo (for invokes) - A convenience wrapper. | |||
ModRefResult getModRefInfo(const InvokeInst *I, | ModRefResult getModRefInfo(const InvokeInst *I, | |||
const Value *P, uint64_t Size) { | const Value *P, uint64_t Size) { | |||
return getModRefInfo(I, Location(P, Size)); | return getModRefInfo(I, Location(P, Size)); | |||
} | } | |||
/// getModRefInfo (for loads) - Return whether information about whether | /// getModRefInfo (for loads) - Return information about whether | |||
/// a particular load modifies or reads the specified memory location. | /// a particular load modifies or reads the specified memory location. | |||
ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc); | ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc); | |||
/// getModRefInfo (for loads) - A convenience wrapper. | /// getModRefInfo (for loads) - A convenience wrapper. | |||
ModRefResult getModRefInfo(const LoadInst *L, const Value *P, uint64_t Si ze) { | ModRefResult getModRefInfo(const LoadInst *L, const Value *P, uint64_t Si ze) { | |||
return getModRefInfo(L, Location(P, Size)); | return getModRefInfo(L, Location(P, Size)); | |||
} | } | |||
/// getModRefInfo (for stores) - Return whether information about whether | /// getModRefInfo (for stores) - Return information about whether | |||
/// a particular store modifies or reads the specified memory location. | /// a particular store modifies or reads the specified memory location. | |||
ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc); | ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc); | |||
/// getModRefInfo (for stores) - A convenience wrapper. | /// getModRefInfo (for stores) - A convenience wrapper. | |||
ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t S ize){ | ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t S ize){ | |||
return getModRefInfo(S, Location(P, Size)); | return getModRefInfo(S, Location(P, Size)); | |||
} | } | |||
/// getModRefInfo (for fences) - Return whether information about whether | /// getModRefInfo (for fences) - Return information about whether | |||
/// a particular store modifies or reads the specified memory location. | /// a particular store modifies or reads the specified memory location. | |||
ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) { | ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) { | |||
// Conservatively correct. (We could possibly be a bit smarter if | // Conservatively correct. (We could possibly be a bit smarter if | |||
// Loc is a alloca that doesn't escape.) | // Loc is a alloca that doesn't escape.) | |||
return ModRef; | return ModRef; | |||
} | } | |||
/// getModRefInfo (for fences) - A convenience wrapper. | /// getModRefInfo (for fences) - A convenience wrapper. | |||
ModRefResult getModRefInfo(const FenceInst *S, const Value *P, uint64_t S ize){ | ModRefResult getModRefInfo(const FenceInst *S, const Value *P, uint64_t S ize){ | |||
return getModRefInfo(S, Location(P, Size)); | return getModRefInfo(S, Location(P, Size)); | |||
} | } | |||
/// getModRefInfo (for cmpxchges) - Return whether information about whet her | /// getModRefInfo (for cmpxchges) - Return information about whether | |||
/// a particular cmpxchg modifies or reads the specified memory location. | /// a particular cmpxchg modifies or reads the specified memory location. | |||
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &L oc); | ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &L oc); | |||
/// getModRefInfo (for cmpxchges) - A convenience wrapper. | /// getModRefInfo (for cmpxchges) - A convenience wrapper. | |||
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, | ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, | |||
const Value *P, unsigned Size) { | const Value *P, unsigned Size) { | |||
return getModRefInfo(CX, Location(P, Size)); | return getModRefInfo(CX, Location(P, Size)); | |||
} | } | |||
/// getModRefInfo (for atomicrmws) - Return whether information about whe ther | /// getModRefInfo (for atomicrmws) - Return information about whether | |||
/// a particular atomicrmw modifies or reads the specified memory locatio n. | /// a particular atomicrmw modifies or reads the specified memory locatio n. | |||
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc) ; | ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc) ; | |||
/// getModRefInfo (for atomicrmws) - A convenience wrapper. | /// getModRefInfo (for atomicrmws) - A convenience wrapper. | |||
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, | ModRefResult getModRefInfo(const AtomicRMWInst *RMW, | |||
const Value *P, unsigned Size) { | const Value *P, unsigned Size) { | |||
return getModRefInfo(RMW, Location(P, Size)); | return getModRefInfo(RMW, Location(P, Size)); | |||
} | } | |||
/// getModRefInfo (for va_args) - Return whether information about whethe r | /// getModRefInfo (for va_args) - Return information about whether | |||
/// a particular va_arg modifies or reads the specified memory location. | /// a particular va_arg modifies or reads the specified memory location. | |||
ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc); | ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc); | |||
/// getModRefInfo (for va_args) - A convenience wrapper. | /// getModRefInfo (for va_args) - A convenience wrapper. | |||
ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t S ize){ | ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t S ize){ | |||
return getModRefInfo(I, Location(P, Size)); | return getModRefInfo(I, Location(P, Size)); | |||
} | } | |||
/// getModRefInfo - Return information about whether two call sites may r efer | /// getModRefInfo - Return information about whether two call sites may r efer | |||
/// to the same set of memory locations. See | /// to the same set of memory locations. See | |||
skipping to change at line 590 | skipping to change at line 590 | |||
} | } | |||
}; | }; | |||
/// isNoAliasCall - Return true if this pointer is returned by a noalias | /// isNoAliasCall - Return true if this pointer is returned by a noalias | |||
/// function. | /// function. | |||
bool isNoAliasCall(const Value *V); | bool isNoAliasCall(const Value *V); | |||
/// isIdentifiedObject - Return true if this pointer refers to a distinct a nd | /// isIdentifiedObject - Return true if this pointer refers to a distinct a nd | |||
/// identifiable object. This returns true for: | /// identifiable object. This returns true for: | |||
/// Global Variables and Functions (but not Global Aliases) | /// Global Variables and Functions (but not Global Aliases) | |||
/// Allocas and Mallocs | /// Allocas | |||
/// ByVal and NoAlias Arguments | /// ByVal and NoAlias Arguments | |||
/// NoAlias returns | /// NoAlias returns (e.g. calls to malloc) | |||
/// | /// | |||
bool isIdentifiedObject(const Value *V); | bool isIdentifiedObject(const Value *V); | |||
/// isKnownNonNull - Return true if this pointer couldn't possibly be null | ||||
by | ||||
/// its definition. This returns true for allocas, non-extern-weak globals | ||||
and | ||||
/// byval arguments. | ||||
bool isKnownNonNull(const Value *V); | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 15 change blocks. | ||||
21 lines changed or deleted | 14 lines changed or added | |||
AliasSetTracker.h | AliasSetTracker.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file defines two classes: AliasSetTracker and AliasSet. These inte rface | // This file defines two classes: AliasSetTracker and AliasSet. These inte rface | |||
// are used to classify a collection of pointer references into a maximal n umber | // are used to classify a collection of pointer references into a maximal n umber | |||
// of disjoint sets. Each AliasSet object constructed by the AliasSetTrack er | // of disjoint sets. Each AliasSet object constructed by the AliasSetTrack er | |||
// object refers to memory disjoint from the other sets. | // object refers to memory disjoint from the other sets. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H | #ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H | |||
#define LLVM_ANALYSIS_ALIASSETTRACKER_H | #define LLVM_ANALYSIS_ALIASSETTRACKER_H | |||
#include "llvm/Support/CallSite.h" | ||||
#include "llvm/Support/ValueHandle.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/ilist.h" | #include "llvm/ADT/ilist.h" | |||
#include "llvm/ADT/ilist_node.h" | #include "llvm/ADT/ilist_node.h" | |||
#include "llvm/Support/ValueHandle.h" | ||||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class AliasAnalysis; | class AliasAnalysis; | |||
class LoadInst; | class LoadInst; | |||
class StoreInst; | class StoreInst; | |||
class VAArgInst; | class VAArgInst; | |||
class AliasSetTracker; | class AliasSetTracker; | |||
class AliasSet; | class AliasSet; | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 1 lines changed or added | |||
AlignOf.h | AlignOf.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_ALIGNOF_H | #ifndef LLVM_SUPPORT_ALIGNOF_H | |||
#define LLVM_SUPPORT_ALIGNOF_H | #define LLVM_SUPPORT_ALIGNOF_H | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include <cstddef> | #include <cstddef> | |||
namespace llvm { | namespace llvm { | |||
template <typename T> | template <typename T> | |||
struct AlignmentCalcImpl { | struct AlignmentCalcImpl { | |||
char x; | char x; | |||
T t; | T t; | |||
private: | private: | |||
AlignmentCalcImpl() {} // Never instantiate. | AlignmentCalcImpl() {} // Never instantiate. | |||
}; | }; | |||
/// AlignOf - A templated class that contains an enum value representing | /// AlignOf - A templated class that contains an enum value representing | |||
/// the alignment of the template argument. For example, | /// the alignment of the template argument. For example, | |||
skipping to change at line 52 | skipping to change at line 51 | |||
enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 }; | enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 }; | |||
enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 }; | enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 }; | |||
enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 }; | enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 }; | |||
enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 }; | enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 }; | |||
enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 }; | enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 }; | |||
enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 }; | enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 }; | |||
enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 }; | enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 }; | |||
enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 }; | enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 }; | |||
}; | }; | |||
/// alignOf - A templated function that returns the minimum alignment of | /// alignOf - A templated function that returns the minimum alignment of | |||
/// of a type. This provides no extra functionality beyond the AlignOf | /// of a type. This provides no extra functionality beyond the AlignOf | |||
/// class besides some cosmetic cleanliness. Example usage: | /// class besides some cosmetic cleanliness. Example usage: | |||
/// alignOf<int>() returns the alignment of an int. | /// alignOf<int>() returns the alignment of an int. | |||
template <typename T> | template <typename T> | |||
inline unsigned alignOf() { return AlignOf<T>::Alignment; } | inline unsigned alignOf() { return AlignOf<T>::Alignment; } | |||
/// \struct AlignedCharArray | ||||
/// \brief Helper for building an aligned character array type. | /// \brief Helper for building an aligned character array type. | |||
/// | /// | |||
/// This template is used to explicitly build up a collection of aligned | /// This template is used to explicitly build up a collection of aligned | |||
/// character types. We have to build these up using a macro and explicit | /// character array types. We have to build these up using a macro and expl icit | |||
/// specialization to cope with old versions of MSVC and GCC where only an | /// specialization to cope with old versions of MSVC and GCC where only an | |||
/// integer literal can be used to specify an alignment constraint. Once bu ilt | /// integer literal can be used to specify an alignment constraint. Once bu ilt | |||
/// up here, we can then begin to indirect between these using normal C++ | /// up here, we can then begin to indirect between these using normal C++ | |||
/// template parameters. | /// template parameters. | |||
template <size_t Alignment> struct AlignedCharArrayImpl; | ||||
// MSVC requires special handling here. | // MSVC requires special handling here. | |||
#ifndef _MSC_VER | #ifndef _MSC_VER | |||
#if __has_feature(cxx_alignas) | #if __has_feature(cxx_alignas) | |||
#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ | template<std::size_t Alignment, std::size_t Size> | |||
template <> struct AlignedCharArrayImpl<x> { \ | struct AlignedCharArray { | |||
char alignas(x) aligned; \ | alignas(Alignment) char buffer[Size]; | |||
} | }; | |||
#elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES) | #elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES) | |||
/// \brief Create a type with an aligned char buffer. | ||||
template<std::size_t Alignment, std::size_t Size> | ||||
struct AlignedCharArray; | ||||
#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ | #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ | |||
template <> struct AlignedCharArrayImpl<x> { \ | template<std::size_t Size> \ | |||
char aligned __attribute__((aligned(x))); \ | struct AlignedCharArray<x, Size> { \ | |||
} | __attribute__((aligned(x))) char buffer[Size]; \ | |||
#else | }; | |||
# error No supported align as directive. | ||||
#endif | ||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512); | ||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024); | ||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048); | ||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096); | ||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); | ||||
#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT | #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT | |||
#else | ||||
# error No supported align as directive. | ||||
#endif | ||||
#else // _MSC_VER | #else // _MSC_VER | |||
/// \brief Create a type with an aligned char buffer. | ||||
template<std::size_t Alignment, std::size_t Size> | ||||
struct AlignedCharArray; | ||||
// We provide special variations of this template for the most common | // We provide special variations of this template for the most common | |||
// alignments because __declspec(align(...)) doesn't actually work when it is | // alignments because __declspec(align(...)) doesn't actually work when it is | |||
// a member of a by-value function argument in MSVC, even if the alignment | // a member of a by-value function argument in MSVC, even if the alignment | |||
// request is something reasonably like 8-byte or 16-byte. | // request is something reasonably like 8-byte or 16-byte. Note that we can | |||
template <> struct AlignedCharArrayImpl<1> { char aligned; }; | 't | |||
template <> struct AlignedCharArrayImpl<2> { short aligned; }; | // even include the declspec with the union that forces the alignment becau | |||
template <> struct AlignedCharArrayImpl<4> { int aligned; }; | se | |||
template <> struct AlignedCharArrayImpl<8> { double aligned; }; | // MSVC warns on the existence of the declspec despite the union member for | |||
cing | ||||
// proper alignment. | ||||
template<std::size_t Size> | ||||
struct AlignedCharArray<1, Size> { | ||||
union { | ||||
char aligned; | ||||
char buffer[Size]; | ||||
}; | ||||
}; | ||||
template<std::size_t Size> | ||||
struct AlignedCharArray<2, Size> { | ||||
union { | ||||
short aligned; | ||||
char buffer[Size]; | ||||
}; | ||||
}; | ||||
template<std::size_t Size> | ||||
struct AlignedCharArray<4, Size> { | ||||
union { | ||||
int aligned; | ||||
char buffer[Size]; | ||||
}; | ||||
}; | ||||
template<std::size_t Size> | ||||
struct AlignedCharArray<8, Size> { | ||||
union { | ||||
double aligned; | ||||
char buffer[Size]; | ||||
}; | ||||
}; | ||||
// The rest of these are provided with a __declspec(align(...)) and we simp | ||||
ly | ||||
// can't pass them by-value as function arguments on MSVC. | ||||
#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ | #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ | |||
template <> struct AlignedCharArrayImpl<x> { \ | template<std::size_t Size> \ | |||
__declspec(align(x)) char aligned; \ | struct AlignedCharArray<x, Size> { \ | |||
} | __declspec(align(x)) char buffer[Size]; \ | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16); | }; | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32); | ||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024); | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128) | |||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048); | ||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096); | ||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); | ||||
// Any larger and MSVC complains. | ||||
#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT | #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT | |||
#endif // _MSC_VER | #endif // _MSC_VER | |||
namespace detail { | ||||
template <typename T1, | ||||
typename T2 = char, typename T3 = char, typename T4 = char, | ||||
typename T5 = char, typename T6 = char, typename T7 = char> | ||||
class AlignerImpl { | ||||
T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; | ||||
AlignerImpl(); // Never defined or instantiated. | ||||
}; | ||||
template <typename T1, | ||||
typename T2 = char, typename T3 = char, typename T4 = char, | ||||
typename T5 = char, typename T6 = char, typename T7 = char> | ||||
union SizerImpl { | ||||
char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4 | ||||
)], | ||||
arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)]; | ||||
}; | ||||
} // end namespace detail | ||||
/// \brief This union template exposes a suitably aligned and sized charact er | /// \brief This union template exposes a suitably aligned and sized charact er | |||
/// array member which can hold elements of any of up to four types. | /// array member which can hold elements of any of up to four types. | |||
/// | /// | |||
/// These types may be arrays, structs, or any other types. The goal is to | /// These types may be arrays, structs, or any other types. The goal is to | |||
/// produce a union type containing a character array which, when used, for | /// expose a char array buffer member which can be used as suitable storage | |||
ms | for | |||
/// storage suitable to placement new any of these types over. Support for | /// a placement new of any of these types. Support for more than seven type | |||
more | s can | |||
/// than four types can be added at the cost of more boiler plate. | /// be added at the cost of more boiler plate. | |||
template <typename T1, | template <typename T1, | |||
typename T2 = char, typename T3 = char, typename T4 = char> | typename T2 = char, typename T3 = char, typename T4 = char, | |||
union AlignedCharArrayUnion { | typename T5 = char, typename T6 = char, typename T7 = char> | |||
private: | struct AlignedCharArrayUnion : llvm::AlignedCharArray< | |||
class AlignerImpl { | AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5, T6, T7> >::Alignment, | |||
T1 t1; T2 t2; T3 t3; T4 t4; | sizeof(detail::SizerImpl<T1, T2, T3, T4, T5, T6, T7>)> { | |||
AlignerImpl(); // Never defined or instantiated. | ||||
}; | ||||
union SizerImpl { | ||||
char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof( | ||||
T4)]; | ||||
}; | ||||
public: | ||||
/// \brief The character array buffer for use by clients. | ||||
/// | ||||
/// No other member of this union should be referenced. The exist purely | ||||
to | ||||
/// constrain the layout of this character array. | ||||
char buffer[sizeof(SizerImpl)]; | ||||
private: | ||||
// Tests seem to indicate that both Clang and GCC will properly register | ||||
the | ||||
// alignment of a struct containing an aligned member, and this alignment | ||||
// should carry over to the character array in the union. | ||||
llvm::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment> nonce_member; | ||||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 17 change blocks. | ||||
78 lines changed or deleted | 114 lines changed or added | |||
Allocator.h | Allocator.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the MallocAllocator and BumpPtrAllocator interfaces. | // This file defines the MallocAllocator and BumpPtrAllocator interfaces. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_ALLOCATOR_H | #ifndef LLVM_SUPPORT_ALLOCATOR_H | |||
#define LLVM_SUPPORT_ALLOCATOR_H | #define LLVM_SUPPORT_ALLOCATOR_H | |||
#include "llvm/Support/AlignOf.h" | #include "llvm/Support/AlignOf.h" | |||
#include "llvm/Support/MathExtras.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/MathExtras.h" | ||||
#include <algorithm> | #include <algorithm> | |||
#include <cassert> | #include <cassert> | |||
#include <cstdlib> | ||||
#include <cstddef> | #include <cstddef> | |||
#include <cstdlib> | ||||
namespace llvm { | namespace llvm { | |||
template <typename T> struct ReferenceAdder { typedef T& result; }; | template <typename T> struct ReferenceAdder { typedef T& result; }; | |||
template <typename T> struct ReferenceAdder<T&> { typedef T result; }; | template <typename T> struct ReferenceAdder<T&> { typedef T result; }; | |||
class MallocAllocator { | class MallocAllocator { | |||
public: | public: | |||
MallocAllocator() {} | MallocAllocator() {} | |||
~MallocAllocator() {} | ~MallocAllocator() {} | |||
End of changes. 4 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Archive.h | Archive.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the ar archive file format class. | // This file declares the ar archive file format class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_OBJECT_ARCHIVE_H | #ifndef LLVM_OBJECT_ARCHIVE_H | |||
#define LLVM_OBJECT_ARCHIVE_H | #define LLVM_OBJECT_ARCHIVE_H | |||
#include "llvm/Object/Binary.h" | #include "llvm/ADT/SmallString.h" | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/ADT/Twine.h" | ||||
#include "llvm/Object/Binary.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/ErrorHandling.h" | ||||
#include "llvm/Support/MemoryBuffer.h" | ||||
namespace llvm { | namespace llvm { | |||
namespace object { | namespace object { | |||
struct ArchiveMemberHeader { | ||||
char Name[16]; | ||||
char LastModified[12]; | ||||
char UID[6]; | ||||
char GID[6]; | ||||
char AccessMode[8]; | ||||
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); | ||||
} | ||||
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; | ||||
} | ||||
}; | ||||
static const ArchiveMemberHeader *ToHeader(const char *base) { | ||||
return reinterpret_cast<const ArchiveMemberHeader *>(base); | ||||
} | ||||
class Archive : public Binary { | class Archive : public Binary { | |||
virtual void anchor(); | virtual void anchor(); | |||
public: | public: | |||
class Child { | class Child { | |||
const Archive *Parent; | const Archive *Parent; | |||
/// \brief Includes header but not padding byte. | ||||
StringRef Data; | StringRef Data; | |||
/// \brief Offset from Data to the start of the file. | ||||
uint16_t StartOfFile; | ||||
public: | public: | |||
Child(const Archive *p, StringRef d) : Parent(p), Data(d) {} | 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; | ||||
} | ||||
} | ||||
bool operator ==(const Child &other) const { | bool operator ==(const Child &other) const { | |||
return (Parent == other.Parent) && (Data.begin() == other.Data.begin( )); | return (Parent == other.Parent) && (Data.begin() == other.Data.begin( )); | |||
} | } | |||
bool operator <(const Child &other) const { | bool operator <(const Child &other) const { | |||
return Data.begin() < other.Data.begin(); | return Data.begin() < other.Data.begin(); | |||
} | } | |||
Child getNext() const; | 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)); | ||||
} | ||||
error_code getName(StringRef &Result) const; | error_code getName(StringRef &Result) const; | |||
int getLastModified() const; | int getLastModified() const; | |||
int getUID() const; | int getUID() const; | |||
int getGID() const; | int getGID() const; | |||
int getAccessMode() const; | int getAccessMode() const; | |||
///! Return the size of the archive member without the header or paddin | /// \return the size of the archive member without the header or paddin | |||
g. | g. | |||
uint64_t getSize() const; | uint64_t getSize() const { return Data.size() - StartOfFile; } | |||
StringRef getBuffer() const { | ||||
return StringRef(Data.data() + StartOfFile, getSize()); | ||||
} | ||||
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()) + "(" + Nam | ||||
e + | ||||
")").toStringRef(Path) : Name, false)); | ||||
return error_code::success(); | ||||
} | ||||
MemoryBuffer *getBuffer() const; | ||||
error_code getAsBinary(OwningPtr<Binary> &Result) const; | error_code getAsBinary(OwningPtr<Binary> &Result) const; | |||
}; | }; | |||
class child_iterator { | class child_iterator { | |||
Child child; | Child child; | |||
public: | public: | |||
child_iterator() : child(Child(0, StringRef())) {} | child_iterator() : child(Child(0, StringRef())) {} | |||
child_iterator(const Child &c) : child(c) {} | child_iterator(const Child &c) : child(c) {} | |||
const Child* operator->() const { | const Child* operator->() const { | |||
return &child; | return &child; | |||
skipping to change at line 125 | skipping to change at line 213 | |||
} | } | |||
symbol_iterator& operator++() { // Preincrement | symbol_iterator& operator++() { // Preincrement | |||
symbol = symbol.getNext(); | symbol = symbol.getNext(); | |||
return *this; | return *this; | |||
} | } | |||
}; | }; | |||
Archive(MemoryBuffer *source, error_code &ec); | Archive(MemoryBuffer *source, error_code &ec); | |||
enum Kind { | ||||
K_GNU, | ||||
K_BSD, | ||||
K_COFF | ||||
}; | ||||
Kind kind() const { | ||||
return Format; | ||||
} | ||||
child_iterator begin_children(bool skip_internal = true) const; | child_iterator begin_children(bool skip_internal = true) const; | |||
child_iterator end_children() const; | child_iterator end_children() const; | |||
symbol_iterator begin_symbols() const; | symbol_iterator begin_symbols() const; | |||
symbol_iterator end_symbols() const; | symbol_iterator end_symbols() const; | |||
// Cast methods. | // Cast methods. | |||
static inline bool classof(Binary const *v) { | static inline bool classof(Binary const *v) { | |||
return v->isArchive(); | return v->isArchive(); | |||
} | } | |||
// check if a symbol is in the archive | ||||
child_iterator findSym(StringRef name) const; | ||||
private: | private: | |||
child_iterator SymbolTable; | child_iterator SymbolTable; | |||
child_iterator StringTable; | child_iterator StringTable; | |||
Kind Format; | ||||
}; | }; | |||
} | } | |||
} | } | |||
#endif | #endif | |||
End of changes. 13 change blocks. | ||||
7 lines changed or deleted | 111 lines changed or added | |||
Argument.h | Argument.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the Argument class. | // This file declares the Argument class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ARGUMENT_H | #ifndef LLVM_IR_ARGUMENT_H | |||
#define LLVM_ARGUMENT_H | #define LLVM_IR_ARGUMENT_H | |||
#include "llvm/Value.h" | ||||
#include "llvm/Attributes.h" | ||||
#include "llvm/ADT/ilist_node.h" | ||||
#include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | |||
#include "llvm/ADT/ilist_node.h" | ||||
#include "llvm/IR/Attributes.h" | ||||
#include "llvm/IR/Value.h" | ||||
namespace llvm { | namespace llvm { | |||
template<typename ValueSubClass, typename ItemParentClass> | template<typename ValueSubClass, typename ItemParentClass> | |||
class SymbolTableListTraits; | class SymbolTableListTraits; | |||
/// A class to represent an incoming formal argument to a Function. An argu | /// \brief LLVM Argument representation | |||
ment | /// | |||
/// is a very simple Value. It is essentially a named (optional) type. When | /// This class represents an incoming formal argument to a Function. A form | |||
used | al | |||
/// in the body of a function, it represents the value of the actual argume | /// argument, since it is ``formal'', does not contain an actual value but | |||
nt | /// instead represents the type, argument number, and attributes of an argu | |||
/// the function was called with. | ment | |||
/// @brief LLVM Argument representation | /// for a specific function. When used in the body of said function, the | |||
/// argument of course represents the value of the actual argument that the | ||||
/// function was called with. | ||||
class Argument : public Value, public ilist_node<Argument> { | class Argument : public Value, public ilist_node<Argument> { | |||
virtual void anchor(); | virtual void anchor(); | |||
Function *Parent; | Function *Parent; | |||
friend class SymbolTableListTraits<Argument, Function>; | friend class SymbolTableListTraits<Argument, Function>; | |||
void setParent(Function *parent); | void setParent(Function *parent); | |||
public: | public: | |||
/// Argument ctor - If Function argument is specified, this argument is | /// \brief Constructor. | |||
/// inserted at the end of the argument list for the function. | ||||
/// | /// | |||
/// If \p F is specified, the argument is inserted at the end of the argu | ||||
ment | ||||
/// list for \p F. | ||||
explicit Argument(Type *Ty, const Twine &Name = "", Function *F = 0); | explicit Argument(Type *Ty, const Twine &Name = "", Function *F = 0); | |||
inline const Function *getParent() const { return Parent; } | inline const Function *getParent() const { return Parent; } | |||
inline Function *getParent() { return Parent; } | inline Function *getParent() { return Parent; } | |||
/// getArgNo - Return the index of this formal argument in its containing | /// \brief Return the index of this formal argument in its containing | |||
/// function. For example in "void foo(int a, float b)" a is 0 and b is | /// function. | |||
1. | /// | |||
/// For example in "void foo(int a, float b)" a is 0 and b is 1. | ||||
unsigned getArgNo() const; | unsigned getArgNo() const; | |||
/// hasByValAttr - Return true if this argument has the byval attribute o | /// \brief Return true if this argument has the byval attribute on it in | |||
n it | its | |||
/// in its containing function. | /// containing function. | |||
bool hasByValAttr() const; | bool hasByValAttr() const; | |||
/// getParamAlignment - If this is a byval argument, return its alignment . | /// \brief If this is a byval argument, return its alignment. | |||
unsigned getParamAlignment() const; | unsigned getParamAlignment() const; | |||
/// hasNestAttr - Return true if this argument has the nest attribute on | /// \brief Return true if this argument has the nest attribute on it in i | |||
/// it in its containing function. | ts | |||
/// containing function. | ||||
bool hasNestAttr() const; | bool hasNestAttr() const; | |||
/// hasNoAliasAttr - Return true if this argument has the noalias attribu | /// \brief Return true if this argument has the noalias attribute on it i | |||
te on | n its | |||
/// it in its containing function. | /// containing function. | |||
bool hasNoAliasAttr() const; | bool hasNoAliasAttr() const; | |||
/// hasNoCaptureAttr - Return true if this argument has the nocapture | /// \brief Return true if this argument has the nocapture attribute on it | |||
/// attribute on it in its containing function. | in | |||
/// its containing function. | ||||
bool hasNoCaptureAttr() const; | bool hasNoCaptureAttr() const; | |||
/// hasStructRetAttr - Return true if this argument has the sret attribut | /// \brief Return true if this argument has the sret attribute on it in i | |||
e on | ts | |||
/// it in its containing function. | /// containing function. | |||
bool hasStructRetAttr() const; | bool hasStructRetAttr() const; | |||
/// addAttr - Add a Attribute to an argument | /// \brief Return true if this argument has the returned attribute on it | |||
void addAttr(Attributes); | in | |||
/// its containing function. | ||||
bool hasReturnedAttr() const; | ||||
/// removeAttr - Remove a Attribute from an argument | /// \brief Add a Attribute to an argument. | |||
void removeAttr(Attributes); | void addAttr(AttributeSet AS); | |||
/// classof - Methods for support type inquiry through isa, cast, and | /// \brief Remove a Attribute from an argument. | |||
/// dyn_cast: | void removeAttr(AttributeSet AS); | |||
/// | ||||
/// \brief Method for support type inquiry through isa, cast, and | ||||
/// dyn_cast. | ||||
static inline bool classof(const Value *V) { | static inline bool classof(const Value *V) { | |||
return V->getValueID() == ArgumentVal; | return V->getValueID() == ArgumentVal; | |||
} | } | |||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 16 change blocks. | ||||
39 lines changed or deleted | 50 lines changed or added | |||
ArrayRef.h | ArrayRef.h | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_ARRAYREF_H | #ifndef LLVM_ADT_ARRAYREF_H | |||
#define LLVM_ADT_ARRAYREF_H | #define LLVM_ADT_ARRAYREF_H | |||
#include "llvm/ADT/None.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
/// ArrayRef - Represent a constant reference to an array (0 or more elem ents | /// ArrayRef - Represent a constant reference to an array (0 or more elem ents | |||
/// consecutively in memory), i.e. a start pointer and a length. It allo ws | /// consecutively in memory), i.e. a start pointer and a length. It allo ws | |||
/// various APIs to take consecutive elements easily and conveniently. | /// various APIs to take consecutive elements easily and conveniently. | |||
/// | /// | |||
/// This class does not own the underlying data, it is expected to be use d in | /// This class does not own the underlying data, it is expected to be use d in | |||
skipping to change at line 36 | skipping to change at line 37 | |||
/// | /// | |||
/// This is intended to be trivially copyable, so it should be passed by | /// This is intended to be trivially copyable, so it should be passed by | |||
/// value. | /// value. | |||
template<typename T> | template<typename T> | |||
class ArrayRef { | class ArrayRef { | |||
public: | public: | |||
typedef const T *iterator; | typedef const T *iterator; | |||
typedef const T *const_iterator; | typedef const T *const_iterator; | |||
typedef size_t size_type; | typedef size_t size_type; | |||
typedef std::reverse_iterator<iterator> reverse_iterator; | ||||
private: | private: | |||
/// The start of the array, in an external buffer. | /// The start of the array, in an external buffer. | |||
const T *Data; | const T *Data; | |||
/// The number of elements. | /// The number of elements. | |||
size_type Length; | size_type Length; | |||
public: | public: | |||
/// @name Constructors | /// @name Constructors | |||
/// @{ | /// @{ | |||
/// Construct an empty ArrayRef. | /// Construct an empty ArrayRef. | |||
/*implicit*/ ArrayRef() : Data(0), Length(0) {} | /*implicit*/ ArrayRef() : Data(0), Length(0) {} | |||
/// Construct an empty ArrayRef from None. | ||||
/*implicit*/ ArrayRef(NoneType) : Data(0), Length(0) {} | ||||
/// Construct an ArrayRef from a single element. | /// Construct an ArrayRef from a single element. | |||
/*implicit*/ ArrayRef(const T &OneElt) | /*implicit*/ ArrayRef(const T &OneElt) | |||
: Data(&OneElt), Length(1) {} | : Data(&OneElt), Length(1) {} | |||
/// Construct an ArrayRef from a pointer and length. | /// Construct an ArrayRef from a pointer and length. | |||
/*implicit*/ ArrayRef(const T *data, size_t length) | /*implicit*/ ArrayRef(const T *data, size_t length) | |||
: Data(data), Length(length) {} | : Data(data), Length(length) {} | |||
/// Construct an ArrayRef from a range. | /// Construct an ArrayRef from a range. | |||
ArrayRef(const T *begin, const T *end) | ArrayRef(const T *begin, const T *end) | |||
skipping to change at line 87 | skipping to change at line 93 | |||
/*implicit*/ ArrayRef(const T (&Arr)[N]) | /*implicit*/ ArrayRef(const T (&Arr)[N]) | |||
: Data(Arr), Length(N) {} | : Data(Arr), Length(N) {} | |||
/// @} | /// @} | |||
/// @name Simple Operations | /// @name Simple Operations | |||
/// @{ | /// @{ | |||
iterator begin() const { return Data; } | iterator begin() const { return Data; } | |||
iterator end() const { return Data + Length; } | iterator end() const { return Data + Length; } | |||
reverse_iterator rbegin() const { return reverse_iterator(end()); } | ||||
reverse_iterator rend() const { return reverse_iterator(begin()); } | ||||
/// empty - Check if the array is empty. | /// empty - Check if the array is empty. | |||
bool empty() const { return Length == 0; } | bool empty() const { return Length == 0; } | |||
const T *data() const { return Data; } | const T *data() const { return Data; } | |||
/// size - Get the array size. | /// size - Get the array size. | |||
size_t size() const { return Length; } | size_t size() const { return Length; } | |||
/// front - Get the first element. | /// front - Get the first element. | |||
const T &front() const { | const T &front() const { | |||
skipping to change at line 172 | skipping to change at line 181 | |||
/// extends past that of the MutableArrayRef. For this reason, it is not in | /// extends past that of the MutableArrayRef. For this reason, it is not in | |||
/// general safe to store a MutableArrayRef. | /// general safe to store a MutableArrayRef. | |||
/// | /// | |||
/// This is intended to be trivially copyable, so it should be passed by | /// This is intended to be trivially copyable, so it should be passed by | |||
/// value. | /// value. | |||
template<typename T> | template<typename T> | |||
class MutableArrayRef : public ArrayRef<T> { | class MutableArrayRef : public ArrayRef<T> { | |||
public: | public: | |||
typedef T *iterator; | typedef T *iterator; | |||
/// Construct an empty ArrayRef. | /// Construct an empty MutableArrayRef. | |||
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {} | /*implicit*/ MutableArrayRef() : ArrayRef<T>() {} | |||
/// Construct an empty MutableArrayRef from None. | ||||
/*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {} | ||||
/// Construct an MutableArrayRef from a single element. | /// Construct an MutableArrayRef from a single element. | |||
/*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {} | /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {} | |||
/// Construct an MutableArrayRef from a pointer and length. | /// Construct an MutableArrayRef from a pointer and length. | |||
/*implicit*/ MutableArrayRef(T *data, size_t length) | /*implicit*/ MutableArrayRef(T *data, size_t length) | |||
: ArrayRef<T>(data, length) {} | : ArrayRef<T>(data, length) {} | |||
/// Construct an MutableArrayRef from a range. | /// Construct an MutableArrayRef from a range. | |||
MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {} | MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {} | |||
End of changes. 6 change blocks. | ||||
1 lines changed or deleted | 13 lines changed or added | |||
AsmCond.h | AsmCond.h | |||
---|---|---|---|---|
//===- AsmCond.h - Assembly file conditional assembly ----------*- C++ -*- ===// | //===- AsmCond.h - Assembly file conditional assembly ----------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef ASMCOND_H | #ifndef LLVM_MC_MCPARSER_ASMCOND_H | |||
#define ASMCOND_H | #define LLVM_MC_MCPARSER_ASMCOND_H | |||
namespace llvm { | namespace llvm { | |||
/// AsmCond - Class to support conditional assembly | /// AsmCond - Class to support conditional assembly | |||
/// | /// | |||
/// The conditional assembly feature (.if, .else, .elseif and .endif) is | /// The conditional assembly feature (.if, .else, .elseif and .endif) is | |||
/// implemented with AsmCond that tells us what we are in the middle of | /// implemented with AsmCond that tells us what we are in the middle of | |||
/// processing. Ignore can be either true or false. When true we are igno ring | /// processing. Ignore can be either true or false. When true we are igno ring | |||
/// the block of code in the middle of a conditional. | /// the block of code in the middle of a conditional. | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
AsmLexer.h | AsmLexer.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This class declares the lexer for assembly files. | // This class declares the lexer for assembly files. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef ASMLEXER_H | #ifndef LLVM_MC_MCPARSER_ASMLEXER_H | |||
#define ASMLEXER_H | #define LLVM_MC_MCPARSER_ASMLEXER_H | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/MC/MCParser/MCAsmLexer.h" | #include "llvm/MC/MCParser/MCAsmLexer.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class MemoryBuffer; | class MemoryBuffer; | |||
class MCAsmInfo; | class MCAsmInfo; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
AsmParsers.def | AsmParsers.def | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
|* The set of targets supported by LLVM is generated at configuration *| | |* The set of targets supported by LLVM is generated at configuration *| | |||
|* time, at which point this header is generated. Do not modify this *| | |* time, at which point this header is generated. Do not modify this *| | |||
|* header directly. *| | |* header directly. *| | |||
|* *| | |* *| | |||
\*===---------------------------------------------------------------------- ===*/ | \*===---------------------------------------------------------------------- ===*/ | |||
#ifndef LLVM_ASM_PARSER | #ifndef LLVM_ASM_PARSER | |||
# error Please define the macro LLVM_ASM_PARSER(TargetName) | # error Please define the macro LLVM_ASM_PARSER(TargetName) | |||
#endif | #endif | |||
LLVM_ASM_PARSER(MBlaze) LLVM_ASM_PARSER(Mips) LLVM_ASM_PARSER(ARM) LLVM_ASM _PARSER(X86) | LLVM_ASM_PARSER(SystemZ) LLVM_ASM_PARSER(MBlaze) LLVM_ASM_PARSER(Mips) LLVM _ASM_PARSER(ARM) LLVM_ASM_PARSER(AArch64) LLVM_ASM_PARSER(PowerPC) LLVM_ASM _PARSER(X86) | |||
#undef LLVM_ASM_PARSER | #undef LLVM_ASM_PARSER | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
AsmPrinter.h | AsmPrinter.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file contains a class to be used as the base class for target speci fic | // This file contains a class to be used as the base class for target speci fic | |||
// asm writers. This class primarily handles common functionality used by | // asm writers. This class primarily handles common functionality used by | |||
// all asm writers. | // all asm writers. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_ASMPRINTER_H | #ifndef LLVM_CODEGEN_ASMPRINTER_H | |||
#define LLVM_CODEGEN_ASMPRINTER_H | #define LLVM_CODEGEN_ASMPRINTER_H | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | #include "llvm/CodeGen/MachineFunctionPass.h" | |||
#include "llvm/InlineAsm.h" | #include "llvm/IR/InlineAsm.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
namespace llvm { | namespace llvm { | |||
class BlockAddress; | class BlockAddress; | |||
class GCStrategy; | class GCStrategy; | |||
class Constant; | class Constant; | |||
class ConstantArray; | ||||
class GCMetadataPrinter; | class GCMetadataPrinter; | |||
class GlobalValue; | class GlobalValue; | |||
class GlobalVariable; | class GlobalVariable; | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
class MachineFunction; | class MachineFunction; | |||
class MachineInstr; | class MachineInstr; | |||
class MachineLocation; | class MachineLocation; | |||
class MachineLoopInfo; | class MachineLoopInfo; | |||
class MachineLoop; | class MachineLoop; | |||
class MachineConstantPoolValue; | class MachineConstantPoolValue; | |||
skipping to change at line 137 | skipping to change at line 138 | |||
/// getFunctionNumber - Return a unique ID for the current function. | /// getFunctionNumber - Return a unique ID for the current function. | |||
/// | /// | |||
unsigned getFunctionNumber() const; | unsigned getFunctionNumber() const; | |||
/// getObjFileLowering - Return information about object file lowering. | /// getObjFileLowering - Return information about object file lowering. | |||
const TargetLoweringObjectFile &getObjFileLowering() const; | const TargetLoweringObjectFile &getObjFileLowering() const; | |||
/// getDataLayout - Return information about data layout. | /// getDataLayout - Return information about data layout. | |||
const DataLayout &getDataLayout() const; | const DataLayout &getDataLayout() const; | |||
/// getTargetTriple - Return the target triple string. | ||||
StringRef getTargetTriple() const; | ||||
/// getCurrentSection() - Return the current section we are emitting to . | /// getCurrentSection() - Return the current section we are emitting to . | |||
const MCSection *getCurrentSection() const; | const MCSection *getCurrentSection() const; | |||
//===------------------------------------------------------------------ ===// | //===------------------------------------------------------------------ ===// | |||
// MachineFunctionPass Implementation. | // MachineFunctionPass Implementation. | |||
//===------------------------------------------------------------------ ===// | //===------------------------------------------------------------------ ===// | |||
/// getAnalysisUsage - Record analysis usage. | /// getAnalysisUsage - Record analysis usage. | |||
/// | /// | |||
void getAnalysisUsage(AnalysisUsage &AU) const; | void getAnalysisUsage(AnalysisUsage &AU) const; | |||
skipping to change at line 385 | skipping to change at line 389 | |||
/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an | /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an | |||
/// encoding. If verbose assembly output is enabled, we output comment s | /// encoding. If verbose assembly output is enabled, we output comment s | |||
/// describing the encoding. Desc is a string saying what the encoding is | /// describing the encoding. Desc is a string saying what the encoding is | |||
/// specifying (e.g. "LSDA"). | /// specifying (e.g. "LSDA"). | |||
void EmitEncodingByte(unsigned Val, const char *Desc = 0) const; | void EmitEncodingByte(unsigned Val, const char *Desc = 0) const; | |||
/// GetSizeOfEncodedValue - Return the size of the encoding in bytes. | /// GetSizeOfEncodedValue - Return the size of the encoding in bytes. | |||
unsigned GetSizeOfEncodedValue(unsigned Encoding) const; | unsigned GetSizeOfEncodedValue(unsigned Encoding) const; | |||
/// EmitReference - Emit a reference to a label with a specified encodi | /// EmitReference - Emit reference to a ttype global with a specified e | |||
ng. | ncoding. | |||
/// | void EmitTTypeReference(const GlobalValue *GV, unsigned Encoding) const | |||
void EmitReference(const MCSymbol *Sym, unsigned Encoding) const; | ; | |||
void EmitReference(const GlobalValue *GV, unsigned Encoding) const; | ||||
/// EmitSectionOffset - Emit the 4-byte offset of Label from the start of | /// EmitSectionOffset - Emit the 4-byte offset of Label from the start of | |||
/// its section. This can be done with a special directive if the targ et | /// its section. This can be done with a special directive if the targ et | |||
/// supports it (e.g. cygwin) or by emitting it as an offset from a lab el at | /// supports it (e.g. cygwin) or by emitting it as an offset from a lab el at | |||
/// the start of the section. | /// the start of the section. | |||
/// | /// | |||
/// SectionLabel is a temporary label emitted at the start of the secti on | /// SectionLabel is a temporary label emitted at the start of the secti on | |||
/// that Label lives in. | /// that Label lives in. | |||
void EmitSectionOffset(const MCSymbol *Label, | void EmitSectionOffset(const MCSymbol *Label, | |||
const MCSymbol *SectionLabel) const; | const MCSymbol *SectionLabel) const; | |||
skipping to change at line 482 | skipping to change at line 484 | |||
/// EmitVisibility - This emits visibility information about symbol, if | /// EmitVisibility - This emits visibility information about symbol, if | |||
/// this is suported by the target. | /// this is suported by the target. | |||
void EmitVisibility(MCSymbol *Sym, unsigned Visibility, | void EmitVisibility(MCSymbol *Sym, unsigned Visibility, | |||
bool IsDefinition = true) const; | bool IsDefinition = true) const; | |||
void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const; | void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const; | |||
void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, | void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, | |||
const MachineBasicBlock *MBB, | const MachineBasicBlock *MBB, | |||
unsigned uid) const; | unsigned uid) const; | |||
void EmitLLVMUsedList(const Constant *List); | void EmitLLVMUsedList(const ConstantArray *InitList); | |||
void EmitXXStructorList(const Constant *List, bool isCtor); | void EmitXXStructorList(const Constant *List, bool isCtor); | |||
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); | GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 5 change blocks. | ||||
7 lines changed or deleted | 10 lines changed or added | |||
AsmPrinters.def | AsmPrinters.def | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
|* The set of targets supported by LLVM is generated at configuration *| | |* The set of targets supported by LLVM is generated at configuration *| | |||
|* time, at which point this header is generated. Do not modify this *| | |* time, at which point this header is generated. Do not modify this *| | |||
|* header directly. *| | |* header directly. *| | |||
|* *| | |* *| | |||
\*===---------------------------------------------------------------------- ===*/ | \*===---------------------------------------------------------------------- ===*/ | |||
#ifndef LLVM_ASM_PRINTER | #ifndef LLVM_ASM_PRINTER | |||
# error Please define the macro LLVM_ASM_PRINTER(TargetName) | # error Please define the macro LLVM_ASM_PRINTER(TargetName) | |||
#endif | #endif | |||
LLVM_ASM_PRINTER(Hexagon) LLVM_ASM_PRINTER(NVPTX) LLVM_ASM_PRINTER(MBlaze) LLVM_ASM_PRINTER(MSP430) LLVM_ASM_PRINTER(XCore) LLVM_ASM_PRINTER(CellSPU) LLVM_ASM_PRINTER(Mips) LLVM_ASM_PRINTER(ARM) LLVM_ASM_PRINTER(PowerPC) LLVM _ASM_PRINTER(Sparc) LLVM_ASM_PRINTER(X86) | LLVM_ASM_PRINTER(SystemZ) LLVM_ASM_PRINTER(Hexagon) LLVM_ASM_PRINTER(NVPTX) LLVM_ASM_PRINTER(MBlaze) LLVM_ASM_PRINTER(MSP430) LLVM_ASM_PRINTER(XCore) LLVM_ASM_PRINTER(Mips) LLVM_ASM_PRINTER(ARM) LLVM_ASM_PRINTER(AArch64) LLVM _ASM_PRINTER(PowerPC) LLVM_ASM_PRINTER(Sparc) LLVM_ASM_PRINTER(X86) | |||
#undef LLVM_ASM_PRINTER | #undef LLVM_ASM_PRINTER | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Atomic.h | Atomic.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the llvm::sys atomic operations. | // This file declares the llvm::sys atomic operations. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_ATOMIC_H | #ifndef LLVM_SUPPORT_ATOMIC_H | |||
#define LLVM_SYSTEM_ATOMIC_H | #define LLVM_SUPPORT_ATOMIC_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
void MemoryFence(); | void MemoryFence(); | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
typedef long cas_flag; | typedef long cas_flag; | |||
#else | #else | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Attributes.h | Attributes.h | |||
---|---|---|---|---|
//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*- ===// | //===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | /// | |||
// This file contains the simple types necessary to represent the | /// \file | |||
// attributes associated with functions and their calls. | /// \brief This file contains the simple types necessary to represent the | |||
// | /// attributes associated with functions and their calls. | |||
/// | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ATTRIBUTES_H | #ifndef LLVM_IR_ATTRIBUTES_H | |||
#define LLVM_ATTRIBUTES_H | #define LLVM_IR_ATTRIBUTES_H | |||
#include "llvm/Support/MathExtras.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/FoldingSet.h" | ||||
#include "llvm/Support/PointerLikeTypeTraits.h" | ||||
#include <bitset> | ||||
#include <cassert> | #include <cassert> | |||
#include <map> | ||||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class AttrBuilder; | class AttrBuilder; | |||
class AttributesImpl; | class AttributeImpl; | |||
class AttributeSetImpl; | ||||
class AttributeSetNode; | ||||
class Constant; | ||||
template<typename T> struct DenseMapInfo; | ||||
class LLVMContext; | class LLVMContext; | |||
class Type; | class Type; | |||
/// Attributes - A bitset of attributes. | //===---------------------------------------------------------------------- | |||
class Attributes { | ===// | |||
/// \class | ||||
/// \brief Functions, function parameters, and return types can have attrib | ||||
utes | ||||
/// to indicate how they should be treated by optimizations and code | ||||
/// generation. This class represents one of those attributes. It's light-w | ||||
eight | ||||
/// and should be passed around by-value. | ||||
class Attribute { | ||||
public: | public: | |||
/// Function parameters and results can have attributes to indicate how t | /// This enumeration lists the attributes that can be associated with | |||
hey | /// parameters, function results, or the function itself. | |||
/// should be treated by optimizations and code generation. This enumerat | ||||
ion | ||||
/// lists the attributes that can be associated with parameters, function | ||||
/// results or the function itself. | ||||
/// | /// | |||
/// Note that uwtable is about the ABI or the user mandating an entry in | /// Note: The `uwtable' attribute is about the ABI or the user mandating | |||
the | an | |||
/// unwind table. The nounwind attribute is about an exception passing by | /// entry in the unwind table. The `nounwind' attribute is about an excep | |||
the | tion | |||
/// function. | /// passing by the function. | |||
/// | /// | |||
/// In a theoretical system that uses tables for profiling and sjlj for | /// In a theoretical system that uses tables for profiling and SjLj for | |||
/// exceptions, they would be fully independent. In a normal system that uses | /// exceptions, they would be fully independent. In a normal system that uses | |||
/// tables for both, the semantics are: | /// tables for both, the semantics are: | |||
/// | /// | |||
/// nil = Needs an entry because an exception might pass b y. | /// nil = Needs an entry because an exception might pass b y. | |||
/// nounwind = No need for an entry | /// nounwind = No need for an entry | |||
/// uwtable = Needs an entry because the ABI says so and becau se | /// uwtable = Needs an entry because the ABI says so and becau se | |||
/// an exception might pass by. | /// an exception might pass by. | |||
/// uwtable + nounwind = Needs an entry because the ABI says so. | /// uwtable + nounwind = Needs an entry because the ABI says so. | |||
enum AttrVal { | enum AttrKind { | |||
// IR-Level Attributes | // IR-Level Attributes | |||
None, ///< No attributes have been set | None, ///< No attributes have been set | |||
AddressSafety, ///< Address safety checking is on. | ||||
Alignment, ///< Alignment of parameter (5 bits) | Alignment, ///< Alignment of parameter (5 bits) | |||
///< stored as log2 of alignment with +1 bias | ///< stored as log2 of alignment with +1 bias | |||
///< 0 means unaligned different from align 1 | ///< 0 means unaligned (different from align(1)) | |||
AlwaysInline, ///< inline=always | AlwaysInline, ///< inline=always | |||
ByVal, ///< Pass structure by value | ByVal, ///< Pass structure by value | |||
InlineHint, ///< Source said inlining was desirable | InlineHint, ///< Source said inlining was desirable | |||
InReg, ///< Force argument to be passed in register | InReg, ///< Force argument to be passed in register | |||
MinSize, ///< Function must be optimized for size first | MinSize, ///< Function must be optimized for size first | |||
Naked, ///< Naked function | Naked, ///< Naked function | |||
Nest, ///< Nested function static chain | Nest, ///< Nested function static chain | |||
NoAlias, ///< Considered to not alias after call | NoAlias, ///< Considered to not alias after call | |||
NoBuiltin, ///< Callee isn't recognized as a builtin | ||||
NoCapture, ///< Function creates no aliases of pointer | NoCapture, ///< Function creates no aliases of pointer | |||
NoDuplicate, ///< Call cannot be duplicated | ||||
NoImplicitFloat, ///< Disable implicit floating point insts | NoImplicitFloat, ///< Disable implicit floating point insts | |||
NoInline, ///< inline=never | NoInline, ///< inline=never | |||
NonLazyBind, ///< Function is called early and/or | NonLazyBind, ///< Function is called early and/or | |||
///< often, so lazy binding isn't worthwhile | ///< often, so lazy binding isn't worthwhile | |||
NoRedZone, ///< Disable redzone | NoRedZone, ///< Disable redzone | |||
NoReturn, ///< Mark the function as not returning | NoReturn, ///< Mark the function as not returning | |||
NoUnwind, ///< Function doesn't unwind stack | NoUnwind, ///< Function doesn't unwind stack | |||
OptimizeForSize, ///< opt_size | OptimizeForSize, ///< opt_size | |||
ReadNone, ///< Function does not access memory | ReadNone, ///< Function does not access memory | |||
ReadOnly, ///< Function only reads from memory | ReadOnly, ///< Function only reads from memory | |||
Returned, ///< Return value is always equal to this argume nt | ||||
ReturnsTwice, ///< Function can return twice | ReturnsTwice, ///< Function can return twice | |||
SExt, ///< Sign extended before/after call | SExt, ///< Sign extended before/after call | |||
StackAlignment, ///< Alignment of stack for function (3 bits) | StackAlignment, ///< Alignment of stack for function (3 bits) | |||
///< stored as log2 of alignment with +1 bias 0 | ///< stored as log2 of alignment with +1 bias 0 | |||
///< means unaligned (different from | ///< means unaligned (different from | |||
///< alignstack={1)) | ///< alignstack=(1)) | |||
StackProtect, ///< Stack protection. | StackProtect, ///< Stack protection. | |||
StackProtectReq, ///< Stack protection required. | StackProtectReq, ///< Stack protection required. | |||
StackProtectStrong, ///< Strong Stack protection. | ||||
StructRet, ///< Hidden pointer to structure to return | StructRet, ///< Hidden pointer to structure to return | |||
SanitizeAddress, ///< AddressSanitizer is on. | ||||
SanitizeThread, ///< ThreadSanitizer is on. | ||||
SanitizeMemory, ///< MemorySanitizer is on. | ||||
UWTable, ///< Function must be in a unwind table | UWTable, ///< Function must be in a unwind table | |||
ZExt ///< Zero extended before/after call | ZExt, ///< Zero extended before/after call | |||
EndAttrKinds ///< Sentinal value useful for loops | ||||
}; | }; | |||
private: | private: | |||
AttributesImpl *Attrs; | AttributeImpl *pImpl; | |||
Attributes(AttributesImpl *A) : Attrs(A) {} | Attribute(AttributeImpl *A) : pImpl(A) {} | |||
public: | public: | |||
Attributes() : Attrs(0) {} | Attribute() : pImpl(0) {} | |||
Attributes(const Attributes &A) : Attrs(A.Attrs) {} | ||||
Attributes &operator=(const Attributes &A) { | ||||
Attrs = A.Attrs; | ||||
return *this; | ||||
} | ||||
/// get - Return a uniquified Attributes object. This takes the uniquifie | ||||
d | ||||
/// value from the Builder and wraps it in the Attributes class. | ||||
static Attributes get(LLVMContext &Context, ArrayRef<AttrVal> Vals); | ||||
static Attributes get(LLVMContext &Context, AttrBuilder &B); | ||||
/// @brief Return true if the attribute is present. | //===-------------------------------------------------------------------- | |||
bool hasAttribute(AttrVal Val) const; | ===// | |||
// Attribute Construction | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
/// @brief Return true if attributes exist | /// \brief Return a uniquified Attribute object. | |||
bool hasAttributes() const; | static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = | |||
0); | ||||
static Attribute get(LLVMContext &Context, StringRef Kind, | ||||
StringRef Val = StringRef()); | ||||
/// \brief Return a uniquified Attribute object that has the specific | ||||
/// alignment set. | ||||
static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align); | ||||
static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Ali | ||||
gn); | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
// Attribute Accessors | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
/// \brief Return true if the attribute is an Attribute::AttrKind type. | ||||
bool isEnumAttribute() const; | ||||
/// \brief Return true if the attribute is an alignment attribute. | ||||
bool isAlignAttribute() const; | ||||
/// \brief Return true if the attribute is a string (target-dependent) | ||||
/// attribute. | ||||
bool isStringAttribute() const; | ||||
/// \brief Return true if the attribute is present. | ||||
bool hasAttribute(AttrKind Val) const; | ||||
/// @brief Return true if the attributes are a non-null intersection. | /// \brief Return true if the target-dependent attribute is present. | |||
bool hasAttributes(const Attributes &A) const; | bool hasAttribute(StringRef Val) const; | |||
/// @brief Returns the alignment field of an attribute as a byte alignmen | /// \brief Return the attribute's kind as an enum (Attribute::AttrKind). | |||
t | This | |||
/// requires the attribute to be an enum or alignment attribute. | ||||
Attribute::AttrKind getKindAsEnum() const; | ||||
/// \brief Return the attribute's value as an integer. This requires that | ||||
the | ||||
/// attribute be an alignment attribute. | ||||
uint64_t getValueAsInt() const; | ||||
/// \brief Return the attribute's kind as a string. This requires the | ||||
/// attribute to be a string attribute. | ||||
StringRef getKindAsString() const; | ||||
/// \brief Return the attribute's value as a string. This requires the | ||||
/// attribute to be a string attribute. | ||||
StringRef getValueAsString() const; | ||||
/// \brief Returns the alignment field of an attribute as a byte alignmen | ||||
t | ||||
/// value. | /// value. | |||
unsigned getAlignment() const; | unsigned getAlignment() const; | |||
/// @brief Returns the stack alignment field of an attribute as a byte | /// \brief Returns the stack alignment field of an attribute as a byte | |||
/// alignment value. | /// alignment value. | |||
unsigned getStackAlignment() const; | unsigned getStackAlignment() const; | |||
/// @brief Parameter attributes that do not apply to vararg call argument | /// \brief The Attribute is converted to a string of equivalent mnemonic. | |||
s. | This | |||
bool hasIncompatibleWithVarArgsAttrs() const { | /// is, presumably, for writing out the mnemonics for the assembly writer | |||
return hasAttribute(Attributes::StructRet); | . | |||
} | std::string getAsString(bool InAttrGrp = false) const; | |||
/// @brief Attributes that only apply to function parameters. | /// \brief Equality and non-equality operators. | |||
bool hasParameterOnlyAttrs() const { | bool operator==(Attribute A) const { return pImpl == A.pImpl; } | |||
return hasAttribute(Attributes::ByVal) || | bool operator!=(Attribute A) const { return pImpl != A.pImpl; } | |||
hasAttribute(Attributes::Nest) || | ||||
hasAttribute(Attributes::StructRet) || | /// \brief Less-than operator. Useful for sorting the attributes list. | |||
hasAttribute(Attributes::NoCapture); | bool operator<(Attribute A) const; | |||
} | ||||
void Profile(FoldingSetNodeID &ID) const { | ||||
/// @brief Attributes that may be applied to the function itself. These | ID.AddPointer(pImpl); | |||
cannot | } | |||
/// be used on return values or function parameters. | ||||
bool hasFunctionOnlyAttrs() const { | ||||
return hasAttribute(Attributes::NoReturn) || | ||||
hasAttribute(Attributes::NoUnwind) || | ||||
hasAttribute(Attributes::ReadNone) || | ||||
hasAttribute(Attributes::ReadOnly) || | ||||
hasAttribute(Attributes::NoInline) || | ||||
hasAttribute(Attributes::AlwaysInline) || | ||||
hasAttribute(Attributes::OptimizeForSize) || | ||||
hasAttribute(Attributes::StackProtect) || | ||||
hasAttribute(Attributes::StackProtectReq) || | ||||
hasAttribute(Attributes::NoRedZone) || | ||||
hasAttribute(Attributes::NoImplicitFloat) || | ||||
hasAttribute(Attributes::Naked) || | ||||
hasAttribute(Attributes::InlineHint) || | ||||
hasAttribute(Attributes::StackAlignment) || | ||||
hasAttribute(Attributes::UWTable) || | ||||
hasAttribute(Attributes::NonLazyBind) || | ||||
hasAttribute(Attributes::ReturnsTwice) || | ||||
hasAttribute(Attributes::AddressSafety) || | ||||
hasAttribute(Attributes::MinSize); | ||||
} | ||||
bool operator==(const Attributes &A) const { | ||||
return Attrs == A.Attrs; | ||||
} | ||||
bool operator!=(const Attributes &A) const { | ||||
return Attrs != A.Attrs; | ||||
} | ||||
uint64_t Raw() const; | ||||
/// @brief Which attributes cannot be applied to a type. | ||||
static Attributes typeIncompatible(Type *Ty); | ||||
/// encodeLLVMAttributesForBitcode - This returns an integer containing a | ||||
n | ||||
/// encoding of all the LLVM attributes found in the given attribute bits | ||||
et. | ||||
/// Any change to this encoding is a breaking change to bitcode compatibi | ||||
lity. | ||||
static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs); | ||||
/// decodeLLVMAttributesForBitcode - This returns an attribute bitset | ||||
/// containing the LLVM attributes that have been decoded from the given | ||||
/// integer. This function must stay in sync with | ||||
/// 'encodeLLVMAttributesForBitcode'. | ||||
static Attributes decodeLLVMAttributesForBitcode(LLVMContext &C, | ||||
uint64_t EncodedAttrs); | ||||
/// getAsString - The set of Attributes set in Attributes is converted to | ||||
a | ||||
/// string of equivalent mnemonics. This is, presumably, for writing out | ||||
the | ||||
/// mnemonics for the assembly writer. | ||||
/// @brief Convert attribute bits to text | ||||
std::string getAsString() const; | ||||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// AttrBuilder - This class is used in conjunction with the Attributes::ge | /// \class | |||
t | /// \brief This class holds the attributes for a function, its return value | |||
/// method to create an Attributes object. The object itself is uniquified. | , and | |||
The | /// its parameters. You access the attributes for each of them via an index | |||
/// Builder's value, however, is not. So this can be used as a quick way to | into | |||
test | /// the AttributeSet object. The function attributes are at index | |||
/// for equality, presence of attributes, etc. | /// `AttributeSet::FunctionIndex', the return value is at index | |||
class AttrBuilder { | /// `AttributeSet::ReturnIndex', and the attributes for the parameters star | |||
uint64_t Bits; | t at | |||
/// index `1'. | ||||
class AttributeSet { | ||||
public: | public: | |||
AttrBuilder() : Bits(0) {} | enum AttrIndex { | |||
explicit AttrBuilder(uint64_t B) : Bits(B) {} | ReturnIndex = 0U, | |||
AttrBuilder(const Attributes &A) : Bits(A.Raw()) {} | FunctionIndex = ~0U | |||
AttrBuilder(const AttrBuilder &B) : Bits(B.Bits) {} | }; | |||
private: | ||||
friend class AttrBuilder; | ||||
friend class AttributeSetImpl; | ||||
template <typename Ty> friend struct DenseMapInfo; | ||||
void clear() { Bits = 0; } | /// \brief The attributes that we are managing. This can be null to repre | |||
sent | ||||
/// the empty attributes list. | ||||
AttributeSetImpl *pImpl; | ||||
/// addAttribute - Add an attribute to the builder. | /// \brief The attributes for the specified index are returned. | |||
AttrBuilder &addAttribute(Attributes::AttrVal Val); | AttributeSetNode *getAttributes(unsigned Index) const; | |||
/// removeAttribute - Remove an attribute from the builder. | /// \brief Create an AttributeSet with the specified parameters in it. | |||
AttrBuilder &removeAttribute(Attributes::AttrVal Val); | static AttributeSet get(LLVMContext &C, | |||
ArrayRef<std::pair<unsigned, Attribute> > Attrs); | ||||
static AttributeSet get(LLVMContext &C, | ||||
ArrayRef<std::pair<unsigned, | ||||
AttributeSetNode*> > Attrs); | ||||
static AttributeSet getImpl(LLVMContext &C, | ||||
ArrayRef<std::pair<unsigned, | ||||
AttributeSetNode*> > Attrs | ||||
); | ||||
/// addAttribute - Add the attributes from A to the builder. | explicit AttributeSet(AttributeSetImpl *LI) : pImpl(LI) {} | |||
AttrBuilder &addAttributes(const Attributes &A); | public: | |||
AttributeSet() : pImpl(0) {} | ||||
/// removeAttribute - Remove the attributes from A from the builder. | //===-------------------------------------------------------------------- | |||
AttrBuilder &removeAttributes(const Attributes &A); | ===// | |||
// AttributeSet Construction and Mutation | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
/// hasAttribute - Return true if the builder has the specified attribute | /// \brief Return an AttributeSet with the specified parameters in it. | |||
. | static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs); | |||
bool hasAttribute(Attributes::AttrVal A) const; | static AttributeSet get(LLVMContext &C, unsigned Index, | |||
ArrayRef<Attribute::AttrKind> Kind); | ||||
static AttributeSet get(LLVMContext &C, unsigned Index, AttrBuilder &B); | ||||
/// \brief Add an attribute to the attribute set at the given index. Sinc | ||||
e | ||||
/// attribute sets are immutable, this returns a new set. | ||||
AttributeSet addAttribute(LLVMContext &C, unsigned Index, | ||||
Attribute::AttrKind Attr) const; | ||||
/// \brief Add an attribute to the attribute set at the given index. Sinc | ||||
e | ||||
/// attribute sets are immutable, this returns a new set. | ||||
AttributeSet addAttribute(LLVMContext &C, unsigned Index, | ||||
StringRef Kind) const; | ||||
/// \brief Add attributes to the attribute set at the given index. Since | ||||
/// attribute sets are immutable, this returns a new set. | ||||
AttributeSet addAttributes(LLVMContext &C, unsigned Index, | ||||
AttributeSet Attrs) const; | ||||
/// \brief Remove the specified attribute at the specified index from thi | ||||
s | ||||
/// attribute list. Since attribute lists are immutable, this returns the | ||||
new | ||||
/// list. | ||||
AttributeSet removeAttribute(LLVMContext &C, unsigned Index, | ||||
Attribute::AttrKind Attr) const; | ||||
/// \brief Remove the specified attributes at the specified index from th | ||||
is | ||||
/// attribute list. Since attribute lists are immutable, this returns the | ||||
new | ||||
/// list. | ||||
AttributeSet removeAttributes(LLVMContext &C, unsigned Index, | ||||
AttributeSet Attrs) const; | ||||
/// hasAttributes - Return true if the builder has IR-level attributes. | //===-------------------------------------------------------------------- | |||
bool hasAttributes() const; | ===// | |||
// AttributeSet Accessors | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
/// hasAttributes - Return true if the builder has any attribute that's i | /// \brief Retrieve the LLVM context. | |||
n the | LLVMContext &getContext() const; | |||
/// specified attribute. | ||||
bool hasAttributes(const Attributes &A) const; | ||||
/// hasAlignmentAttr - Return true if the builder has an alignment attrib | /// \brief The attributes for the specified index are returned. | |||
ute. | AttributeSet getParamAttributes(unsigned Index) const; | |||
bool hasAlignmentAttr() const; | ||||
/// getAlignment - Retrieve the alignment attribute, if it exists. | /// \brief The attributes for the ret value are returned. | |||
uint64_t getAlignment() const; | AttributeSet getRetAttributes() const; | |||
/// getStackAlignment - Retrieve the stack alignment attribute, if it exi | /// \brief The function attributes are returned. | |||
sts. | AttributeSet getFnAttributes() const; | |||
uint64_t getStackAlignment() const; | ||||
/// addAlignmentAttr - This turns an int alignment (which must be a power | /// \brief Return true if the attribute exists at the given index. | |||
of | bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const; | |||
/// 2) into the form used internally in Attributes. | ||||
AttrBuilder &addAlignmentAttr(unsigned Align); | ||||
/// addStackAlignmentAttr - This turns an int stack alignment (which must | /// \brief Return true if the attribute exists at the given index. | |||
be a | bool hasAttribute(unsigned Index, StringRef Kind) const; | |||
/// power of 2) into the form used internally in Attributes. | ||||
AttrBuilder &addStackAlignmentAttr(unsigned Align); | ||||
/// addRawValue - Add the raw value to the internal representation. | /// \brief Return true if attribute exists at the given index. | |||
/// N.B. This should be used ONLY for decoding LLVM bitcode! | bool hasAttributes(unsigned Index) const; | |||
AttrBuilder &addRawValue(uint64_t Val); | ||||
/// \brief Return true if the specified attribute is set for at least one | ||||
/// parameter or for the return value. | ||||
bool hasAttrSomewhere(Attribute::AttrKind Attr) const; | ||||
/// \brief Return the attribute object that exists at the given index. | ||||
Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const; | ||||
/// \brief Return the attribute object that exists at the given index. | ||||
Attribute getAttribute(unsigned Index, StringRef Kind) const; | ||||
/// @brief Remove attributes that are used on functions only. | /// \brief Return the alignment for the specified function parameter. | |||
void removeFunctionOnlyAttrs() { | unsigned getParamAlignment(unsigned Index) const; | |||
removeAttribute(Attributes::NoReturn) | ||||
.removeAttribute(Attributes::NoUnwind) | /// \brief Get the stack alignment. | |||
.removeAttribute(Attributes::ReadNone) | unsigned getStackAlignment(unsigned Index) const; | |||
.removeAttribute(Attributes::ReadOnly) | ||||
.removeAttribute(Attributes::NoInline) | /// \brief Return the attributes at the index as a string. | |||
.removeAttribute(Attributes::AlwaysInline) | std::string getAsString(unsigned Index, bool InAttrGrp = false) const; | |||
.removeAttribute(Attributes::OptimizeForSize) | ||||
.removeAttribute(Attributes::StackProtect) | typedef ArrayRef<Attribute>::iterator iterator; | |||
.removeAttribute(Attributes::StackProtectReq) | ||||
.removeAttribute(Attributes::NoRedZone) | iterator begin(unsigned Slot) const; | |||
.removeAttribute(Attributes::NoImplicitFloat) | iterator end(unsigned Slot) const; | |||
.removeAttribute(Attributes::Naked) | ||||
.removeAttribute(Attributes::InlineHint) | /// operator==/!= - Provide equality predicates. | |||
.removeAttribute(Attributes::StackAlignment) | bool operator==(const AttributeSet &RHS) const { | |||
.removeAttribute(Attributes::UWTable) | return pImpl == RHS.pImpl; | |||
.removeAttribute(Attributes::NonLazyBind) | } | |||
.removeAttribute(Attributes::ReturnsTwice) | bool operator!=(const AttributeSet &RHS) const { | |||
.removeAttribute(Attributes::AddressSafety) | return pImpl != RHS.pImpl; | |||
.removeAttribute(Attributes::MinSize); | ||||
} | } | |||
uint64_t Raw() const { return Bits; } | //===-------------------------------------------------------------------- | |||
===// | ||||
// AttributeSet Introspection | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
// FIXME: Remove this. | ||||
uint64_t Raw(unsigned Index) const; | ||||
bool operator==(const AttrBuilder &B) { | /// \brief Return a raw pointer that uniquely identifies this attribute l | |||
return Bits == B.Bits; | ist. | |||
void *getRawPointer() const { | ||||
return pImpl; | ||||
} | } | |||
bool operator!=(const AttrBuilder &B) { | ||||
return Bits != B.Bits; | /// \brief Return true if there are no attributes. | |||
bool isEmpty() const { | ||||
return getNumSlots() == 0; | ||||
} | } | |||
/// \brief Return the number of slots used in this attribute list. This | ||||
is | ||||
/// the number of arguments that have an attribute set on them (including | ||||
the | ||||
/// function itself). | ||||
unsigned getNumSlots() const; | ||||
/// \brief Return the index for the given slot. | ||||
unsigned getSlotIndex(unsigned Slot) const; | ||||
/// \brief Return the attributes at the given slot. | ||||
AttributeSet getSlotAttributes(unsigned Slot) const; | ||||
void dump() const; | ||||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// AttributeWithIndex | /// \class | |||
//===---------------------------------------------------------------------- | /// \brief Provide DenseMapInfo for AttributeSet. | |||
===// | template<> struct DenseMapInfo<AttributeSet> { | |||
static inline AttributeSet getEmptyKey() { | ||||
/// AttributeWithIndex - This is just a pair of values to associate a set o | uintptr_t Val = static_cast<uintptr_t>(-1); | |||
f | Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; | |||
/// attributes with an index. | return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val)); | |||
struct AttributeWithIndex { | } | |||
Attributes Attrs; ///< The attributes that are set, or'd together. | static inline AttributeSet getTombstoneKey() { | |||
unsigned Index; ///< Index of the parameter for which the attributes a | uintptr_t Val = static_cast<uintptr_t>(-2); | |||
pply. | Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; | |||
///< Index 0 is used for return value attributes. | return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val)); | |||
///< Index ~0U is used for function attributes. | } | |||
static unsigned getHashValue(AttributeSet AS) { | ||||
static AttributeWithIndex get(LLVMContext &C, unsigned Idx, | return (unsigned((uintptr_t)AS.pImpl) >> 4) ^ | |||
ArrayRef<Attributes::AttrVal> Attrs) { | (unsigned((uintptr_t)AS.pImpl) >> 9); | |||
return get(Idx, Attributes::get(C, Attrs)); | ||||
} | ||||
static AttributeWithIndex get(unsigned Idx, Attributes Attrs) { | ||||
AttributeWithIndex P; | ||||
P.Index = Idx; | ||||
P.Attrs = Attrs; | ||||
return P; | ||||
} | } | |||
static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == R HS; } | ||||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// AttrListPtr Smart Pointer | /// \class | |||
//===---------------------------------------------------------------------- | /// \brief This class is used in conjunction with the Attribute::get method | |||
===// | to | |||
/// create an Attribute object. The object itself is uniquified. The Builde | ||||
r's | ||||
/// value, however, is not. So this can be used as a quick way to test for | ||||
/// equality, presence of attributes, etc. | ||||
class AttrBuilder { | ||||
std::bitset<Attribute::EndAttrKinds> Attrs; | ||||
std::map<std::string, std::string> TargetDepAttrs; | ||||
uint64_t Alignment; | ||||
uint64_t StackAlignment; | ||||
public: | ||||
AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0) {} | ||||
explicit AttrBuilder(uint64_t Val) | ||||
: Attrs(0), Alignment(0), StackAlignment(0) { | ||||
addRawValue(Val); | ||||
} | ||||
AttrBuilder(const Attribute &A) : Attrs(0), Alignment(0), StackAlignment( | ||||
0) { | ||||
addAttribute(A); | ||||
} | ||||
AttrBuilder(AttributeSet AS, unsigned Idx); | ||||
AttrBuilder(const AttrBuilder &B) | ||||
: Attrs(B.Attrs), | ||||
TargetDepAttrs(B.TargetDepAttrs.begin(), B.TargetDepAttrs.end()), | ||||
Alignment(B.Alignment), StackAlignment(B.StackAlignment) {} | ||||
class AttributeListImpl; | void clear(); | |||
/// AttrListPtr - This class manages the ref count for the opaque | /// \brief Add an attribute to the builder. | |||
/// AttributeListImpl object and provides accessors for it. | AttrBuilder &addAttribute(Attribute::AttrKind Val); | |||
class AttrListPtr { | ||||
public: | ||||
enum AttrIndex { | ||||
ReturnIndex = 0U, | ||||
FunctionIndex = ~0U | ||||
}; | ||||
private: | ||||
/// @brief The attributes that we are managing. This can be null to repr | ||||
esent | ||||
/// the empty attributes list. | ||||
AttributeListImpl *AttrList; | ||||
/// @brief The attributes for the specified index are returned. Attribut | /// \brief Add the Attribute object to the builder. | |||
es | AttrBuilder &addAttribute(Attribute A); | |||
/// for the result are denoted with Idx = 0. | ||||
Attributes getAttributes(unsigned Idx) const; | ||||
explicit AttrListPtr(AttributeListImpl *LI) : AttrList(LI) {} | /// \brief Add the target-dependent attribute to the builder. | |||
public: | AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef()); | |||
AttrListPtr() : AttrList(0) {} | ||||
AttrListPtr(const AttrListPtr &P) : AttrList(P.AttrList) {} | ||||
const AttrListPtr &operator=(const AttrListPtr &RHS); | ||||
//===-------------------------------------------------------------------- | /// \brief Remove an attribute from the builder. | |||
===// | AttrBuilder &removeAttribute(Attribute::AttrKind Val); | |||
// Attribute List Construction and Mutation | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
/// get - Return a Attributes list with the specified parameters in it. | /// \brief Remove the attributes from the builder. | |||
static AttrListPtr get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs | AttrBuilder &removeAttributes(AttributeSet A, uint64_t Index); | |||
); | ||||
/// addAttr - Add the specified attribute at the specified index to this | /// \brief Remove the target-dependent attribute to the builder. | |||
/// attribute list. Since attribute lists are immutable, this | AttrBuilder &removeAttribute(StringRef A); | |||
/// returns the new list. | ||||
AttrListPtr addAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const | ||||
; | ||||
/// removeAttr - Remove the specified attribute at the specified index fr | ||||
om | ||||
/// this attribute list. Since attribute lists are immutable, this | ||||
/// returns the new list. | ||||
AttrListPtr removeAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) co | ||||
nst; | ||||
//===-------------------------------------------------------------------- | /// \brief Add the attributes from the builder. | |||
===// | AttrBuilder &merge(const AttrBuilder &B); | |||
// Attribute List Accessors | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
/// getParamAttributes - The attributes for the specified index are | ||||
/// returned. | ||||
Attributes getParamAttributes(unsigned Idx) const { | ||||
return getAttributes(Idx); | ||||
} | ||||
/// getRetAttributes - The attributes for the ret value are | /// \brief Return true if the builder has the specified attribute. | |||
/// returned. | bool contains(Attribute::AttrKind A) const { | |||
Attributes getRetAttributes() const { | assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range | |||
return getAttributes(ReturnIndex); | !"); | |||
return Attrs[A]; | ||||
} | } | |||
/// getFnAttributes - The function attributes are returned. | /// \brief Return true if the builder has the specified target-dependent | |||
Attributes getFnAttributes() const { | /// attribute. | |||
return getAttributes(FunctionIndex); | bool contains(StringRef A) const; | |||
} | ||||
/// paramHasAttr - Return true if the specified parameter index has the | /// \brief Return true if the builder has IR-level attributes. | |||
/// specified attribute set. | bool hasAttributes() const; | |||
bool paramHasAttr(unsigned Idx, Attributes Attr) const { | ||||
return getAttributes(Idx).hasAttributes(Attr); | ||||
} | ||||
/// getParamAlignment - Return the alignment for the specified function | /// \brief Return true if the builder has any attribute that's in the | |||
/// parameter. | /// specified attribute. | |||
unsigned getParamAlignment(unsigned Idx) const { | bool hasAttributes(AttributeSet A, uint64_t Index) const; | |||
return getAttributes(Idx).getAlignment(); | ||||
} | ||||
/// hasAttrSomewhere - Return true if the specified attribute is set for | /// \brief Return true if the builder has an alignment attribute. | |||
at | bool hasAlignmentAttr() const; | |||
/// least one parameter or for the return value. | ||||
bool hasAttrSomewhere(Attributes::AttrVal Attr) const; | ||||
unsigned getNumAttrs() const; | /// \brief Retrieve the alignment attribute, if it exists. | |||
Attributes &getAttributesAtIndex(unsigned i) const; | uint64_t getAlignment() const { return Alignment; } | |||
/// operator==/!= - Provide equality predicates. | /// \brief Retrieve the stack alignment attribute, if it exists. | |||
bool operator==(const AttrListPtr &RHS) const | uint64_t getStackAlignment() const { return StackAlignment; } | |||
{ return AttrList == RHS.AttrList; } | ||||
bool operator!=(const AttrListPtr &RHS) const | ||||
{ return AttrList != RHS.AttrList; } | ||||
//===-------------------------------------------------------------------- | /// \brief This turns an int alignment (which must be a power of 2) into | |||
===// | the | |||
// Attribute List Introspection | /// form used internally in Attribute. | |||
//===-------------------------------------------------------------------- | AttrBuilder &addAlignmentAttr(unsigned Align); | |||
===// | ||||
/// getRawPointer - Return a raw pointer that uniquely identifies this | /// \brief This turns an int stack alignment (which must be a power of 2) | |||
/// attribute list. | into | |||
void *getRawPointer() const { | /// the form used internally in Attribute. | |||
return AttrList; | AttrBuilder &addStackAlignmentAttr(unsigned Align); | |||
} | ||||
// Attributes are stored as a dense set of slots, where there is one | /// \brief Return true if the builder contains no target-independent | |||
// slot for each argument that has an attribute. This allows walking ove | /// attributes. | |||
r the | bool empty() const { return Attrs.none(); } | |||
// dense set instead of walking the sparse list of attributes. | ||||
/// isEmpty - Return true if there are no attributes. | // Iterators for target-dependent attributes. | |||
/// | typedef std::pair<std::string, std::string> td_type; | |||
bool isEmpty() const { | typedef std::map<std::string, std::string>::iterator td_iterator; | |||
return AttrList == 0; | typedef std::map<std::string, std::string>::const_iterator td_const_itera | |||
} | tor; | |||
/// getNumSlots - Return the number of slots used in this attribute list. | td_iterator td_begin() { return TargetDepAttrs.begin(); } | |||
/// This is the number of arguments that have an attribute set on them | td_iterator td_end() { return TargetDepAttrs.end(); } | |||
/// (including the function itself). | ||||
unsigned getNumSlots() const; | ||||
/// getSlot - Return the AttributeWithIndex at the specified slot. This | td_const_iterator td_begin() const { return TargetDepAttrs.begin(); } | |||
/// holds a index number plus a set of attributes. | td_const_iterator td_end() const { return TargetDepAttrs.end(); } | |||
const AttributeWithIndex &getSlot(unsigned Slot) const; | ||||
void dump() const; | bool td_empty() const { return TargetDepAttrs.empty(); } | |||
bool operator==(const AttrBuilder &B); | ||||
bool operator!=(const AttrBuilder &B) { | ||||
return !(*this == B); | ||||
} | ||||
// FIXME: Remove this in 4.0. | ||||
/// \brief Add the raw value to the internal representation. | ||||
AttrBuilder &addRawValue(uint64_t Val); | ||||
}; | }; | |||
} // End llvm namespace | namespace AttributeFuncs { | |||
/// \brief Which attributes cannot be applied to a type. | ||||
AttributeSet typeIncompatible(Type *Ty, uint64_t Index); | ||||
} // end AttributeFuncs namespace | ||||
} // end llvm namespace | ||||
#endif | #endif | |||
End of changes. 75 change blocks. | ||||
335 lines changed or deleted | 403 lines changed or added | |||
BasicBlock.h | BasicBlock.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the declaration of the BasicBlock class. | // This file contains the declaration of the BasicBlock class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_BASICBLOCK_H | #ifndef LLVM_IR_BASICBLOCK_H | |||
#define LLVM_BASICBLOCK_H | #define LLVM_IR_BASICBLOCK_H | |||
#include "llvm/Instruction.h" | ||||
#include "llvm/SymbolTableListTraits.h" | ||||
#include "llvm/ADT/ilist.h" | ||||
#include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | |||
#include "llvm/ADT/ilist.h" | ||||
#include "llvm/IR/Instruction.h" | ||||
#include "llvm/IR/SymbolTableListTraits.h" | ||||
#include "llvm/Support/CBindingWrapping.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
class LandingPadInst; | class LandingPadInst; | |||
class TerminatorInst; | class TerminatorInst; | |||
class LLVMContext; | class LLVMContext; | |||
class BlockAddress; | class BlockAddress; | |||
template<> struct ilist_traits<Instruction> | template<> struct ilist_traits<Instruction> | |||
: public SymbolTableListTraits<Instruction, BasicBlock> { | : public SymbolTableListTraits<Instruction, BasicBlock> { | |||
// createSentinel is used to get hold of a node that marks the end of | ||||
// the list... | /// \brief Return a node that marks the end of a list. | |||
// The sentinel is relative to this instance, so we use a non-static | /// | |||
// method. | /// The sentinel is relative to this instance, so we use a non-static | |||
/// method. | ||||
Instruction *createSentinel() const { | Instruction *createSentinel() const { | |||
// since i(p)lists always publicly derive from the corresponding | // Since i(p)lists always publicly derive from their corresponding trai | |||
// traits, placing a data member in this class will augment i(p)list. | ts, | |||
// But since the NodeTy is expected to publicly derive from | // placing a data member in this class will augment the i(p)list. But | |||
// ilist_node<NodeTy>, there is a legal viable downcast from it | since | |||
// to NodeTy. We use this trick to superpose i(p)list with a "ghostly" | // the NodeTy is expected to be publicly derive from ilist_node<NodeTy> | |||
// NodeTy, which becomes the sentinel. Dereferencing the sentinel is | , | |||
// forbidden (save the ilist_node<NodeTy>) so no one will ever notice | // there is a legal viable downcast from it to NodeTy. We use this tric | |||
// the superposition. | k to | |||
// superimpose an i(p)list with a "ghostly" NodeTy, which becomes the | ||||
// sentinel. Dereferencing the sentinel is forbidden (save the | ||||
// ilist_node<NodeTy>), so no one will ever notice the superposition. | ||||
return static_cast<Instruction*>(&Sentinel); | return static_cast<Instruction*>(&Sentinel); | |||
} | } | |||
static void destroySentinel(Instruction*) {} | static void destroySentinel(Instruction*) {} | |||
Instruction *provideInitialHead() const { return createSentinel(); } | Instruction *provideInitialHead() const { return createSentinel(); } | |||
Instruction *ensureHead(Instruction*) const { return createSentinel(); } | Instruction *ensureHead(Instruction*) const { return createSentinel(); } | |||
static void noteHead(Instruction*, Instruction*) {} | static void noteHead(Instruction*, Instruction*) {} | |||
private: | private: | |||
mutable ilist_half_node<Instruction> Sentinel; | mutable ilist_half_node<Instruction> Sentinel; | |||
}; | }; | |||
/// \brief LLVM Basic Block Representation | ||||
/// | ||||
/// This represents a single basic block in LLVM. A basic block is simply a | /// This represents a single basic block in LLVM. A basic block is simply a | |||
/// container of instructions that execute sequentially. Basic blocks are V alues | /// container of instructions that execute sequentially. Basic blocks are V alues | |||
/// because they are referenced by instructions such as branches and switch | /// because they are referenced by instructions such as branches and switch | |||
/// tables. The type of a BasicBlock is "Type::LabelTy" because the basic b lock | /// tables. The type of a BasicBlock is "Type::LabelTy" because the basic b lock | |||
/// represents a label to which a branch can jump. | /// represents a label to which a branch can jump. | |||
/// | /// | |||
/// A well formed basic block is formed of a list of non-terminating | /// A well formed basic block is formed of a list of non-terminating | |||
/// instructions followed by a single TerminatorInst instruction. | /// instructions followed by a single TerminatorInst instruction. | |||
/// TerminatorInst's may not occur in the middle of basic blocks, and must | /// TerminatorInst's may not occur in the middle of basic blocks, and must | |||
/// terminate the blocks. The BasicBlock class allows malformed basic block s to | /// terminate the blocks. The BasicBlock class allows malformed basic block s to | |||
/// occur because it may be useful in the intermediate stage of constructin g or | /// occur because it may be useful in the intermediate stage of constructin g or | |||
/// modifying a program. However, the verifier will ensure that basic block s | /// modifying a program. However, the verifier will ensure that basic block s | |||
/// are "well formed". | /// are "well formed". | |||
/// @brief LLVM Basic Block Representation | ||||
class BasicBlock : public Value, // Basic blocks are data objects also | class BasicBlock : public Value, // Basic blocks are data objects also | |||
public ilist_node<BasicBlock> { | public ilist_node<BasicBlock> { | |||
friend class BlockAddress; | friend class BlockAddress; | |||
public: | public: | |||
typedef iplist<Instruction> InstListType; | typedef iplist<Instruction> InstListType; | |||
private: | private: | |||
InstListType InstList; | InstListType InstList; | |||
Function *Parent; | Function *Parent; | |||
void setParent(Function *parent); | void setParent(Function *parent); | |||
friend class SymbolTableListTraits<BasicBlock, Function>; | friend class SymbolTableListTraits<BasicBlock, Function>; | |||
BasicBlock(const BasicBlock &) LLVM_DELETED_FUNCTION; | BasicBlock(const BasicBlock &) LLVM_DELETED_FUNCTION; | |||
void operator=(const BasicBlock &) LLVM_DELETED_FUNCTION; | void operator=(const BasicBlock &) LLVM_DELETED_FUNCTION; | |||
/// BasicBlock ctor - If the function parameter is specified, the basic b | /// \brief Constructor. | |||
lock | ||||
/// is automatically inserted at either the end of the function (if | ||||
/// InsertBefore is null), or before the specified basic block. | ||||
/// | /// | |||
/// If the function parameter is specified, the basic block is automatica | ||||
lly | ||||
/// inserted at either the end of the function (if InsertBefore is null), | ||||
or | ||||
/// before the specified basic block. | ||||
explicit BasicBlock(LLVMContext &C, const Twine &Name = "", | explicit BasicBlock(LLVMContext &C, const Twine &Name = "", | |||
Function *Parent = 0, BasicBlock *InsertBefore = 0); | Function *Parent = 0, BasicBlock *InsertBefore = 0); | |||
public: | public: | |||
/// getContext - Get the context in which this basic block lives. | /// \brief Get the context in which this basic block lives. | |||
LLVMContext &getContext() const; | LLVMContext &getContext() const; | |||
/// Instruction iterators... | /// Instruction iterators... | |||
typedef InstListType::iterator iterator; | typedef InstListType::iterator iterator; | |||
typedef InstListType::const_iterator const_iterator; | typedef InstListType::const_iterator const_iterator; | |||
typedef InstListType::reverse_iterator reverse_iterator; | ||||
/// Create - Creates a new BasicBlock. If the Parent parameter is specifi | typedef InstListType::const_reverse_iterator const_reverse_iterator; | |||
ed, | ||||
/// the basic block is automatically inserted at either the end of the | /// \brief Creates a new BasicBlock. | |||
/// function (if InsertBefore is 0), or before the specified basic block. | /// | |||
/// If the Parent parameter is specified, the basic block is automaticall | ||||
y | ||||
/// inserted at either the end of the function (if InsertBefore is 0), or | ||||
/// before the specified basic block. | ||||
static BasicBlock *Create(LLVMContext &Context, const Twine &Name = "", | static BasicBlock *Create(LLVMContext &Context, const Twine &Name = "", | |||
Function *Parent = 0,BasicBlock *InsertBefore = 0) { | Function *Parent = 0,BasicBlock *InsertBefore = 0) { | |||
return new BasicBlock(Context, Name, Parent, InsertBefore); | return new BasicBlock(Context, Name, Parent, InsertBefore); | |||
} | } | |||
~BasicBlock(); | ~BasicBlock(); | |||
/// getParent - Return the enclosing method, or null if none | /// \brief Return the enclosing method, or null if none. | |||
/// | ||||
const Function *getParent() const { return Parent; } | const Function *getParent() const { return Parent; } | |||
Function *getParent() { return Parent; } | Function *getParent() { return Parent; } | |||
/// getTerminator() - If this is a well formed basic block, then this ret | /// \brief Returns the terminator instruction if the block is well formed | |||
urns | or | |||
/// a pointer to the terminator instruction. If it is not, then you get | /// null if the block is not well formed. | |||
a | ||||
/// null pointer back. | ||||
/// | ||||
TerminatorInst *getTerminator(); | TerminatorInst *getTerminator(); | |||
const TerminatorInst *getTerminator() const; | const TerminatorInst *getTerminator() const; | |||
/// Returns a pointer to the first instructon in this block that is not a | /// \brief Returns a pointer to the first instruction in this block that | |||
/// PHINode instruction. When adding instruction to the beginning of the | is | |||
/// basic block, they should be added before the returned value, not befo | /// not a PHINode instruction. | |||
re | /// | |||
/// the first instruction, which might be PHI. | /// When adding instructions to the beginning of the basic block, they sh | |||
/// Returns 0 is there's no non-PHI instruction. | ould | |||
/// be added before the returned value, not before the first instruction, | ||||
/// which might be PHI. Returns 0 is there's no non-PHI instruction. | ||||
Instruction* getFirstNonPHI(); | Instruction* getFirstNonPHI(); | |||
const Instruction* getFirstNonPHI() const { | const Instruction* getFirstNonPHI() const { | |||
return const_cast<BasicBlock*>(this)->getFirstNonPHI(); | return const_cast<BasicBlock*>(this)->getFirstNonPHI(); | |||
} | } | |||
// Same as above, but also skip debug intrinsics. | /// \brief Returns a pointer to the first instruction in this block that | |||
is not | ||||
/// a PHINode or a debug intrinsic. | ||||
Instruction* getFirstNonPHIOrDbg(); | Instruction* getFirstNonPHIOrDbg(); | |||
const Instruction* getFirstNonPHIOrDbg() const { | const Instruction* getFirstNonPHIOrDbg() const { | |||
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg(); | return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg(); | |||
} | } | |||
// Same as above, but also skip lifetime intrinsics. | /// \brief Returns a pointer to the first instruction in this block that | |||
is not | ||||
/// a PHINode, a debug intrinsic, or a lifetime intrinsic. | ||||
Instruction* getFirstNonPHIOrDbgOrLifetime(); | Instruction* getFirstNonPHIOrDbgOrLifetime(); | |||
const Instruction* getFirstNonPHIOrDbgOrLifetime() const { | const Instruction* getFirstNonPHIOrDbgOrLifetime() const { | |||
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime(); | return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime(); | |||
} | } | |||
/// getFirstInsertionPt - Returns an iterator to the first instruction in | /// \brief Returns an iterator to the first instruction in this block tha | |||
this | t is | |||
/// block that is suitable for inserting a non-PHI instruction. In partic | /// suitable for inserting a non-PHI instruction. | |||
ular, | /// | |||
/// it skips all PHIs and LandingPad instructions. | /// In particular, it skips all PHIs and LandingPad instructions. | |||
iterator getFirstInsertionPt(); | iterator getFirstInsertionPt(); | |||
const_iterator getFirstInsertionPt() const { | const_iterator getFirstInsertionPt() const { | |||
return const_cast<BasicBlock*>(this)->getFirstInsertionPt(); | return const_cast<BasicBlock*>(this)->getFirstInsertionPt(); | |||
} | } | |||
/// removeFromParent - This method unlinks 'this' from the containing | /// \brief Unlink 'this' from the containing function, but do not delete | |||
/// function, but does not delete it. | it. | |||
/// | ||||
void removeFromParent(); | void removeFromParent(); | |||
/// eraseFromParent - This method unlinks 'this' from the containing func | /// \brief Unlink 'this' from the containing function and delete it. | |||
tion | ||||
/// and deletes it. | ||||
/// | ||||
void eraseFromParent(); | void eraseFromParent(); | |||
/// moveBefore - Unlink this basic block from its current function and | /// \brief Unlink this basic block from its current function and insert i | |||
/// insert it into the function that MovePos lives in, right before MoveP | t | |||
os. | /// into the function that \p MovePos lives in, right before \p MovePos. | |||
void moveBefore(BasicBlock *MovePos); | void moveBefore(BasicBlock *MovePos); | |||
/// moveAfter - Unlink this basic block from its current function and | /// \brief Unlink this basic block from its current function and insert i | |||
/// insert it into the function that MovePos lives in, right after MovePo | t | |||
s. | /// right after \p MovePos in the function \p MovePos lives in. | |||
void moveAfter(BasicBlock *MovePos); | void moveAfter(BasicBlock *MovePos); | |||
/// getSinglePredecessor - If this basic block has a single predecessor b | /// \brief Return this block if it has a single predecessor block. Otherw | |||
lock, | ise | |||
/// return the block, otherwise return a null pointer. | /// return a null pointer. | |||
BasicBlock *getSinglePredecessor(); | BasicBlock *getSinglePredecessor(); | |||
const BasicBlock *getSinglePredecessor() const { | const BasicBlock *getSinglePredecessor() const { | |||
return const_cast<BasicBlock*>(this)->getSinglePredecessor(); | return const_cast<BasicBlock*>(this)->getSinglePredecessor(); | |||
} | } | |||
/// getUniquePredecessor - If this basic block has a unique predecessor b | /// \brief Return this block if it has a unique predecessor block. Otherw | |||
lock, | ise return a null pointer. | |||
/// return the block, otherwise return a null pointer. | /// | |||
/// Note that unique predecessor doesn't mean single edge, there can be | /// Note that unique predecessor doesn't mean single edge, there can be | |||
/// multiple edges from the unique predecessor to this block (for example | /// multiple edges from the unique predecessor to this block (for example | |||
/// a switch statement with multiple cases having the same destination). | a | |||
/// switch statement with multiple cases having the same destination). | ||||
BasicBlock *getUniquePredecessor(); | BasicBlock *getUniquePredecessor(); | |||
const BasicBlock *getUniquePredecessor() const { | const BasicBlock *getUniquePredecessor() const { | |||
return const_cast<BasicBlock*>(this)->getUniquePredecessor(); | return const_cast<BasicBlock*>(this)->getUniquePredecessor(); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// Instruction iterator methods | /// Instruction iterator methods | |||
/// | /// | |||
inline iterator begin() { return InstList.begin(); } | inline iterator begin() { return InstList.begin(); } | |||
inline const_iterator begin() const { return InstList.begin(); } | inline const_iterator begin() const { return InstList.begin(); } | |||
inline iterator end () { return InstList.end(); } | inline iterator end () { return InstList.end(); } | |||
inline const_iterator end () const { return InstList.end(); } | inline const_iterator end () const { return InstList.end(); } | |||
inline reverse_iterator rbegin() { return InstList.rbegin(); | ||||
} | ||||
inline const_reverse_iterator rbegin() const { return InstList.rbegin(); | ||||
} | ||||
inline reverse_iterator rend () { return InstList.rend(); | ||||
} | ||||
inline const_reverse_iterator rend () const { return InstList.rend(); | ||||
} | ||||
inline size_t size() const { return InstList.size(); } | inline size_t size() const { return InstList.size(); } | |||
inline bool empty() const { return InstList.empty(); } | inline bool empty() const { return InstList.empty(); } | |||
inline const Instruction &front() const { return InstList.front(); } | inline const Instruction &front() const { return InstList.front(); } | |||
inline Instruction &front() { return InstList.front(); } | inline Instruction &front() { return InstList.front(); } | |||
inline const Instruction &back() const { return InstList.back(); } | inline const Instruction &back() const { return InstList.back(); } | |||
inline Instruction &back() { return InstList.back(); } | inline Instruction &back() { return InstList.back(); } | |||
/// getInstList() - Return the underlying instruction list container. Yo | /// \brief Return the underlying instruction list container. | |||
u | ||||
/// need to access it directly if you want to modify it currently. | ||||
/// | /// | |||
/// Currently you need to access the underlying instruction list containe | ||||
r | ||||
/// directly if you want to modify it. | ||||
const InstListType &getInstList() const { return InstList; } | const InstListType &getInstList() const { return InstList; } | |||
InstListType &getInstList() { return InstList; } | InstListType &getInstList() { return InstList; } | |||
/// getSublistAccess() - returns pointer to member of instruction list | /// \brief Returns a pointer to a member of the instruction list. | |||
static iplist<Instruction> BasicBlock::*getSublistAccess(Instruction*) { | static iplist<Instruction> BasicBlock::*getSublistAccess(Instruction*) { | |||
return &BasicBlock::InstList; | return &BasicBlock::InstList; | |||
} | } | |||
/// getValueSymbolTable() - returns pointer to symbol table (if any) | /// \brief Returns a pointer to the symbol table if one exists. | |||
ValueSymbolTable *getValueSymbolTable(); | ValueSymbolTable *getValueSymbolTable(); | |||
/// Methods for support type inquiry through isa, cast, and dyn_cast: | /// \brief Methods for support type inquiry through isa, cast, and dyn_ca st. | |||
static inline bool classof(const Value *V) { | static inline bool classof(const Value *V) { | |||
return V->getValueID() == Value::BasicBlockVal; | return V->getValueID() == Value::BasicBlockVal; | |||
} | } | |||
/// dropAllReferences() - This function causes all the subinstructions to | /// \brief Cause all subinstructions to "let go" of all the references th | |||
"let | at | |||
/// go" of all references that they are maintaining. This allows one to | /// said subinstructions are maintaining. | |||
/// 'delete' a whole class at a time, even though there may be circular | ||||
/// references... first all references are dropped, and all use counts go | ||||
to | ||||
/// zero. Then everything is delete'd for real. Note that no operations | ||||
are | ||||
/// valid on an object that has "dropped all references", except operator | ||||
/// delete. | ||||
/// | /// | |||
/// This allows one to 'delete' a whole class at a time, even though ther | ||||
e may | ||||
/// be circular references... first all references are dropped, and all u | ||||
se | ||||
/// counts go to zero. Then everything is delete'd for real. Note that | ||||
no | ||||
/// operations are valid on an object that has "dropped all references", | ||||
/// except operator delete. | ||||
void dropAllReferences(); | void dropAllReferences(); | |||
/// removePredecessor - This method is used to notify a BasicBlock that t | /// \brief Notify the BasicBlock that the predecessor \p Pred is no longe | |||
he | r | |||
/// specified Predecessor of the block is no longer able to reach it. Th | /// able to reach it. | |||
is is | ||||
/// actually not used to update the Predecessor list, but is actually use | ||||
d to | ||||
/// update the PHI nodes that reside in the block. Note that this should | ||||
be | ||||
/// called while the predecessor still refers to this block. | ||||
/// | /// | |||
/// This is actually not used to update the Predecessor list, but is actu | ||||
ally | ||||
/// used to update the PHI nodes that reside in the block. Note that thi | ||||
s | ||||
/// should be called while the predecessor still refers to this block. | ||||
void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs = fal se); | void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs = fal se); | |||
/// splitBasicBlock - This splits a basic block into two at the specified | /// \brief Split the basic block into two basic blocks at the specified | |||
/// instruction. Note that all instructions BEFORE the specified iterato | /// instruction. | |||
r | /// | |||
/// stay as part of the original basic block, an unconditional branch is | /// Note that all instructions BEFORE the specified iterator stay as part | |||
added | of | |||
/// to the original BB, and the rest of the instructions in the BB are mo | /// the original basic block, an unconditional branch is added to the ori | |||
ved | ginal | |||
/// to the new BB, including the old terminator. The newly formed BasicB | /// BB, and the rest of the instructions in the BB are moved to the new B | |||
lock | B, | |||
/// is returned. This function invalidates the specified iterator. | /// including the old terminator. The newly formed BasicBlock is returne | |||
d. | ||||
/// This function invalidates the specified iterator. | ||||
/// | /// | |||
/// Note that this only works on well formed basic blocks (must have a | /// Note that this only works on well formed basic blocks (must have a | |||
/// terminator), and 'I' must not be the end of instruction list (which w ould | /// terminator), and 'I' must not be the end of instruction list (which w ould | |||
/// cause a degenerate basic block to be formed, having a terminator insi de of | /// cause a degenerate basic block to be formed, having a terminator insi de of | |||
/// the basic block). | /// the basic block). | |||
/// | /// | |||
/// Also note that this doesn't preserve any passes. To split blocks whil e | /// Also note that this doesn't preserve any passes. To split blocks whil e | |||
/// keeping loop information consistent, use the SplitBlock utility funct ion. | /// keeping loop information consistent, use the SplitBlock utility funct ion. | |||
/// | ||||
BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = ""); | BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = ""); | |||
/// hasAddressTaken - returns true if there are any uses of this basic bl | /// \brief Returns true if there are any uses of this basic block other t | |||
ock | han | |||
/// other than direct branches, switches, etc. to it. | /// direct branches, switches, etc. to it. | |||
bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } | bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } | |||
/// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our succes | /// \brief Update all phi nodes in this basic block's successors to refer | |||
sors | to | |||
/// to refer to basic block New instead of to us. | /// basic block \p New instead of to it. | |||
void replaceSuccessorsPhiUsesWith(BasicBlock *New); | void replaceSuccessorsPhiUsesWith(BasicBlock *New); | |||
/// isLandingPad - Return true if this basic block is a landing pad. I.e. | /// \brief Return true if this basic block is a landing pad. | |||
, | /// | |||
/// it's the destination of the 'unwind' edge of an invoke instruction. | /// Being a ``landing pad'' means that the basic block is the destination | |||
of | ||||
/// the 'unwind' edge of an invoke instruction. | ||||
bool isLandingPad() const; | bool isLandingPad() const; | |||
/// getLandingPadInst() - Return the landingpad instruction associated wi | /// \brief Return the landingpad instruction associated with the landing | |||
th | pad. | |||
/// the landing pad. | ||||
LandingPadInst *getLandingPadInst(); | LandingPadInst *getLandingPadInst(); | |||
const LandingPadInst *getLandingPadInst() const; | const LandingPadInst *getLandingPadInst() const; | |||
private: | private: | |||
/// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAdd | /// \brief Increment the internal refcount of the number of BlockAddresse | |||
ress | s | |||
/// objects using it. This is almost always 0, sometimes one, possibly b | /// referencing this BasicBlock by \p Amt. | |||
ut | /// | |||
/// almost never 2, and inconceivably 3 or more. | /// This is almost always 0, sometimes one possibly, but almost never 2, | |||
and | ||||
/// inconceivably 3 or more. | ||||
void AdjustBlockAddressRefCount(int Amt) { | void AdjustBlockAddressRefCount(int Amt) { | |||
setValueSubclassData(getSubclassDataFromValue()+Amt); | setValueSubclassData(getSubclassDataFromValue()+Amt); | |||
assert((int)(signed char)getSubclassDataFromValue() >= 0 && | assert((int)(signed char)getSubclassDataFromValue() >= 0 && | |||
"Refcount wrap-around"); | "Refcount wrap-around"); | |||
} | } | |||
// Shadow Value::setValueSubclassData with a private forwarding method so | /// \brief Shadow Value::setValueSubclassData with a private forwarding m | |||
that | ethod | |||
// any future subclasses cannot accidentally use it. | /// so that any future subclasses cannot accidentally use it. | |||
void setValueSubclassData(unsigned short D) { | void setValueSubclassData(unsigned short D) { | |||
Value::setValueSubclassData(D); | Value::setValueSubclassData(D); | |||
} | } | |||
}; | }; | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef) | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 43 change blocks. | ||||
128 lines changed or deleted | 156 lines changed or added | |||
BasicBlockUtils.h | BasicBlockUtils.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This family of functions perform manipulations on basic blocks, and | // This family of functions perform manipulations on basic blocks, and | |||
// instructions contained within basic blocks. | // instructions contained within basic blocks. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_UTILS_BASICBLOCK_H | #ifndef LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H | |||
#define LLVM_TRANSFORMS_UTILS_BASICBLOCK_H | #define LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H | |||
// FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicB lock | // FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicB lock | |||
#include "llvm/BasicBlock.h" | #include "llvm/IR/BasicBlock.h" | |||
#include "llvm/Support/CFG.h" | #include "llvm/Support/CFG.h" | |||
#include "llvm/Support/DebugLoc.h" | ||||
namespace llvm { | namespace llvm { | |||
class AliasAnalysis; | class AliasAnalysis; | |||
class Instruction; | class Instruction; | |||
class MDNode; | class MDNode; | |||
class Pass; | class Pass; | |||
class ReturnInst; | class ReturnInst; | |||
class TargetLibraryInfo; | class TargetLibraryInfo; | |||
class TerminatorInst; | class TerminatorInst; | |||
End of changes. 3 change blocks. | ||||
4 lines changed or deleted | 3 lines changed or added | |||
Binary.h | Binary.h | |||
---|---|---|---|---|
skipping to change at line 44 | skipping to change at line 44 | |||
protected: | protected: | |||
MemoryBuffer *Data; | MemoryBuffer *Data; | |||
Binary(unsigned int Type, MemoryBuffer *Source); | Binary(unsigned int Type, MemoryBuffer *Source); | |||
enum { | enum { | |||
ID_Archive, | ID_Archive, | |||
// Object and children. | // Object and children. | |||
ID_StartObjects, | ID_StartObjects, | |||
ID_COFF, | ID_COFF, | |||
ID_ELF32L, // ELF 32-bit, little endian | ID_ELF32L, // ELF 32-bit, little endian | |||
ID_ELF32B, // ELF 32-bit, big endian | ID_ELF32B, // ELF 32-bit, big endian | |||
ID_ELF64L, // ELF 64-bit, little endian | ID_ELF64L, // ELF 64-bit, little endian | |||
ID_ELF64B, // ELF 64-bit, big endian | ID_ELF64B, // ELF 64-bit, big endian | |||
ID_MachO, | ||||
ID_MachO32L, // MachO 32-bit, little endian | ||||
ID_MachO32B, // MachO 32-bit, big endian | ||||
ID_MachO64L, // MachO 64-bit, little endian | ||||
ID_MachO64B, // MachO 64-bit, big endian | ||||
ID_EndObjects | ID_EndObjects | |||
}; | }; | |||
static inline unsigned int getELFType(bool isLittleEndian, bool is64Bits) | static inline unsigned int getELFType(bool isLE, bool is64Bits) { | |||
{ | if (isLE) | |||
if (isLittleEndian) | ||||
return is64Bits ? ID_ELF64L : ID_ELF32L; | return is64Bits ? ID_ELF64L : ID_ELF32L; | |||
else | else | |||
return is64Bits ? ID_ELF64B : ID_ELF32B; | return is64Bits ? ID_ELF64B : ID_ELF32B; | |||
} | } | |||
static unsigned int getMachOType(bool isLE, bool is64Bits) { | ||||
if (isLE) | ||||
return is64Bits ? ID_MachO64L : ID_MachO32L; | ||||
else | ||||
return is64Bits ? ID_MachO64B : ID_MachO32B; | ||||
} | ||||
public: | public: | |||
virtual ~Binary(); | virtual ~Binary(); | |||
StringRef getData() const; | StringRef getData() const; | |||
StringRef getFileName() const; | StringRef getFileName() const; | |||
// Cast methods. | // Cast methods. | |||
unsigned int getType() const { return TypeID; } | unsigned int getType() const { return TypeID; } | |||
// Convenience methods | // Convenience methods | |||
skipping to change at line 82 | skipping to change at line 95 | |||
bool isArchive() const { | bool isArchive() const { | |||
return TypeID == ID_Archive; | return TypeID == ID_Archive; | |||
} | } | |||
bool isELF() const { | bool isELF() const { | |||
return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B; | return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B; | |||
} | } | |||
bool isMachO() const { | bool isMachO() const { | |||
return TypeID == ID_MachO; | return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B; | |||
} | } | |||
bool isCOFF() const { | bool isCOFF() const { | |||
return TypeID == ID_COFF; | return TypeID == ID_COFF; | |||
} | } | |||
bool isLittleEndian() const { | ||||
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B || | ||||
TypeID == ID_MachO32B || TypeID == ID_MachO64B); | ||||
} | ||||
}; | }; | |||
/// @brief Create a Binary from Source, autodetecting the file type. | /// @brief Create a Binary from Source, autodetecting the file type. | |||
/// | /// | |||
/// @param Source The data to create the Binary from. Ownership is transfer red | /// @param Source The data to create the Binary from. Ownership is transfer red | |||
/// to Result if successful. If an error is returned, Source is dest royed | /// to Result if successful. If an error is returned, Source is dest royed | |||
/// by createBinary before returning. | /// by createBinary before returning. | |||
/// @param Result A pointer to the resulting Binary if no error occured. | /// @param Result A pointer to the resulting Binary if no error occured. | |||
error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result); | error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result); | |||
End of changes. 6 change blocks. | ||||
5 lines changed or deleted | 22 lines changed or added | |||
BitCodes.h | BitCodes.h | |||
---|---|---|---|---|
skipping to change at line 29 | skipping to change at line 29 | |||
#define LLVM_BITCODE_BITCODES_H | #define LLVM_BITCODE_BITCODES_H | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
namespace bitc { | namespace bitc { | |||
enum StandardWidths { | enum StandardWidths { | |||
BlockIDWidth = 8, // We use VBR-8 for block IDs. | BlockIDWidth = 8, // We use VBR-8 for block IDs. | |||
CodeLenWidth = 4, // Codelen are VBR-4. | CodeLenWidth = 4, // Codelen are VBR-4. | |||
BlockSizeWidth = 32 // BlockSize up to 2^32 32-bit words = 16GB per bl ock. | BlockSizeWidth = 32 // BlockSize up to 2^32 32-bit words = 16GB per bl ock. | |||
}; | }; | |||
// The standard abbrev namespace always has a way to exit a block, enter a | // The standard abbrev namespace always has a way to exit a block, enter a | |||
// nested block, define abbrevs, and define an unabbreviated record. | // nested block, define abbrevs, and define an unabbreviated record. | |||
enum FixedAbbrevIDs { | enum FixedAbbrevIDs { | |||
END_BLOCK = 0, // Must be zero to guarantee termination for broken bit code. | END_BLOCK = 0, // Must be zero to guarantee termination for broken bit code. | |||
ENTER_SUBBLOCK = 1, | ENTER_SUBBLOCK = 1, | |||
/// DEFINE_ABBREV - Defines an abbrev for the current block. It consis ts | /// DEFINE_ABBREV - Defines an abbrev for the current block. It consis ts | |||
skipping to change at line 73 | skipping to change at line 73 | |||
// Block IDs 1-7 are reserved for future expansion. | // Block IDs 1-7 are reserved for future expansion. | |||
FIRST_APPLICATION_BLOCKID = 8 | FIRST_APPLICATION_BLOCKID = 8 | |||
}; | }; | |||
/// BlockInfoCodes - The blockinfo block contains metadata about user-def ined | /// BlockInfoCodes - The blockinfo block contains metadata about user-def ined | |||
/// blocks. | /// blocks. | |||
enum BlockInfoCodes { | enum BlockInfoCodes { | |||
// DEFINE_ABBREV has magic semantics here, applying to the current SETB ID'd | // DEFINE_ABBREV has magic semantics here, applying to the current SETB ID'd | |||
// block, instead of the BlockInfo block. | // block, instead of the BlockInfo block. | |||
BLOCKINFO_CODE_SETBID = 1, // SETBID: [blockid#] | BLOCKINFO_CODE_SETBID = 1, // SETBID: [blockid#] | |||
BLOCKINFO_CODE_BLOCKNAME = 2, // BLOCKNAME: [name] | BLOCKINFO_CODE_BLOCKNAME = 2, // BLOCKNAME: [name] | |||
BLOCKINFO_CODE_SETRECORDNAME = 3 // BLOCKINFO_CODE_SETRECORDNAME: [id, | BLOCKINFO_CODE_SETRECORDNAME = 3 // BLOCKINFO_CODE_SETRECORDNAME: | |||
name] | // [id, n | |||
ame] | ||||
}; | }; | |||
} // End bitc namespace | } // End bitc namespace | |||
/// BitCodeAbbrevOp - This describes one or more operands in an abbreviatio n. | /// BitCodeAbbrevOp - This describes one or more operands in an abbreviatio n. | |||
/// This is actually a union of two different things: | /// This is actually a union of two different things: | |||
/// 1. It could be a literal integer value ("the operand is always 17"). | /// 1. It could be a literal integer value ("the operand is always 17"). | |||
/// 2. It could be an encoding specification ("this operand encoded like so"). | /// 2. It could be an encoding specification ("this operand encoded like so"). | |||
/// | /// | |||
class BitCodeAbbrevOp { | class BitCodeAbbrevOp { | |||
skipping to change at line 102 | skipping to change at line 103 | |||
VBR = 2, // A VBR field where Val specifies the width of each chunk. | VBR = 2, // A VBR field where Val specifies the width of each chunk. | |||
Array = 3, // A sequence of fields, next field species elt encoding. | Array = 3, // A sequence of fields, next field species elt encoding. | |||
Char6 = 4, // A 6-bit fixed field which maps to [a-zA-Z0-9._]. | Char6 = 4, // A 6-bit fixed field which maps to [a-zA-Z0-9._]. | |||
Blob = 5 // 32-bit aligned array of 8-bit characters. | Blob = 5 // 32-bit aligned array of 8-bit characters. | |||
}; | }; | |||
explicit BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {} | explicit BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {} | |||
explicit BitCodeAbbrevOp(Encoding E, uint64_t Data = 0) | explicit BitCodeAbbrevOp(Encoding E, uint64_t Data = 0) | |||
: Val(Data), IsLiteral(false), Enc(E) {} | : Val(Data), IsLiteral(false), Enc(E) {} | |||
bool isLiteral() const { return IsLiteral; } | bool isLiteral() const { return IsLiteral; } | |||
bool isEncoding() const { return !IsLiteral; } | bool isEncoding() const { return !IsLiteral; } | |||
// Accessors for literals. | // Accessors for literals. | |||
uint64_t getLiteralValue() const { assert(isLiteral()); return Val; } | uint64_t getLiteralValue() const { assert(isLiteral()); return Val; } | |||
// Accessors for encoding info. | // Accessors for encoding info. | |||
Encoding getEncoding() const { assert(isEncoding()); return (Encoding)Enc ; } | Encoding getEncoding() const { assert(isEncoding()); return (Encoding)Enc ; } | |||
uint64_t getEncodingData() const { | uint64_t getEncodingData() const { | |||
assert(isEncoding() && hasEncodingData()); | assert(isEncoding() && hasEncodingData()); | |||
return Val; | return Val; | |||
skipping to change at line 141 | skipping to change at line 142 | |||
if (C >= 'a' && C <= 'z') return true; | if (C >= 'a' && C <= 'z') return true; | |||
if (C >= 'A' && C <= 'Z') return true; | if (C >= 'A' && C <= 'Z') return true; | |||
if (C >= '0' && C <= '9') return true; | if (C >= '0' && C <= '9') return true; | |||
if (C == '.' || C == '_') return true; | if (C == '.' || C == '_') return true; | |||
return false; | return false; | |||
} | } | |||
static unsigned EncodeChar6(char C) { | static unsigned EncodeChar6(char C) { | |||
if (C >= 'a' && C <= 'z') return C-'a'; | if (C >= 'a' && C <= 'z') return C-'a'; | |||
if (C >= 'A' && C <= 'Z') return C-'A'+26; | if (C >= 'A' && C <= 'Z') return C-'A'+26; | |||
if (C >= '0' && C <= '9') return C-'0'+26+26; | if (C >= '0' && C <= '9') return C-'0'+26+26; | |||
if (C == '.') return 62; | if (C == '.') return 62; | |||
if (C == '_') return 63; | if (C == '_') return 63; | |||
llvm_unreachable("Not a value Char6 character!"); | llvm_unreachable("Not a value Char6 character!"); | |||
} | } | |||
static char DecodeChar6(unsigned V) { | static char DecodeChar6(unsigned V) { | |||
assert((V & ~63) == 0 && "Not a Char6 encoded character!"); | assert((V & ~63) == 0 && "Not a Char6 encoded character!"); | |||
if (V < 26) return V+'a'; | if (V < 26) return V+'a'; | |||
if (V < 26+26) return V-26+'A'; | if (V < 26+26) return V-26+'A'; | |||
if (V < 26+26+10) return V-26-26+'0'; | if (V < 26+26+10) return V-26-26+'0'; | |||
if (V == 62) return '.'; | if (V == 62) return '.'; | |||
if (V == 63) return '_'; | if (V == 63) return '_'; | |||
llvm_unreachable("Not a value Char6 character!"); | llvm_unreachable("Not a value Char6 character!"); | |||
} | } | |||
}; | }; | |||
template <> struct isPodLike<BitCodeAbbrevOp> { static const bool value=tru e; }; | template <> struct isPodLike<BitCodeAbbrevOp> { static const bool value=tru e; }; | |||
/// BitCodeAbbrev - This class represents an abbreviation record. An | /// BitCodeAbbrev - This class represents an abbreviation record. An | |||
/// abbreviation allows a complex record that has redundancy to be stored i n a | /// abbreviation allows a complex record that has redundancy to be stored i n a | |||
/// specialized format instead of the fully-general, fully-vbr, format. | /// specialized format instead of the fully-general, fully-vbr, format. | |||
End of changes. 6 change blocks. | ||||
13 lines changed or deleted | 14 lines changed or added | |||
BitVector.h | BitVector.h | |||
---|---|---|---|---|
skipping to change at line 100 | skipping to change at line 100 | |||
Bits = 0; | Bits = 0; | |||
Capacity = 0; | Capacity = 0; | |||
return; | return; | |||
} | } | |||
Capacity = NumBitWords(RHS.size()); | Capacity = NumBitWords(RHS.size()); | |||
Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); | Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); | |||
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); | std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
BitVector(BitVector &&RHS) | BitVector(BitVector &&RHS) | |||
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) { | : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) { | |||
RHS.Bits = 0; | RHS.Bits = 0; | |||
} | } | |||
#endif | #endif | |||
~BitVector() { | ~BitVector() { | |||
std::free(Bits); | std::free(Bits); | |||
} | } | |||
skipping to change at line 454 | skipping to change at line 454 | |||
BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); | BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord)); | |||
std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord)); | std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord)); | |||
// Destroy the old bits. | // Destroy the old bits. | |||
std::free(Bits); | std::free(Bits); | |||
Bits = NewBits; | Bits = NewBits; | |||
return *this; | return *this; | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
const BitVector &operator=(BitVector &&RHS) { | const BitVector &operator=(BitVector &&RHS) { | |||
if (this == &RHS) return *this; | if (this == &RHS) return *this; | |||
std::free(Bits); | std::free(Bits); | |||
Bits = RHS.Bits; | Bits = RHS.Bits; | |||
Size = RHS.Size; | Size = RHS.Size; | |||
Capacity = RHS.Capacity; | Capacity = RHS.Capacity; | |||
RHS.Bits = 0; | RHS.Bits = 0; | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
BitstreamReader.h | BitstreamReader.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This header defines the BitstreamReader class. This class can be used t o | // This header defines the BitstreamReader class. This class can be used t o | |||
// read an arbitrary bitstream, regardless of its contents. | // read an arbitrary bitstream, regardless of its contents. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef BITSTREAM_READER_H | #ifndef LLVM_BITCODE_BITSTREAMREADER_H | |||
#define BITSTREAM_READER_H | #define LLVM_BITCODE_BITSTREAMREADER_H | |||
#include "llvm/ADT/OwningPtr.h" | #include "llvm/ADT/OwningPtr.h" | |||
#include "llvm/Bitcode/BitCodes.h" | #include "llvm/Bitcode/BitCodes.h" | |||
#include "llvm/Support/Endian.h" | #include "llvm/Support/Endian.h" | |||
#include "llvm/Support/StreamableMemoryObject.h" | #include "llvm/Support/StreamableMemoryObject.h" | |||
#include <climits> | #include <climits> | |||
#include <string> | #include <string> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class Deserializer; | class Deserializer; | |||
/// BitstreamReader - This class is used to read from an LLVM bitcode strea | ||||
m, | ||||
/// maintaining information that is global to decoding the entire file. Wh | ||||
ile | ||||
/// a file is being read, multiple cursors can be independently advanced or | ||||
/// skipped around within the file. These are represented by the | ||||
/// BitstreamCursor class. | ||||
class BitstreamReader { | class BitstreamReader { | |||
public: | public: | |||
/// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK bloc ks. | /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK bloc ks. | |||
/// These describe abbreviations that all blocks of the specified ID inhe rit. | /// These describe abbreviations that all blocks of the specified ID inhe rit. | |||
struct BlockInfo { | struct BlockInfo { | |||
unsigned BlockID; | unsigned BlockID; | |||
std::vector<BitCodeAbbrev*> Abbrevs; | std::vector<BitCodeAbbrev*> Abbrevs; | |||
std::string Name; | std::string Name; | |||
std::vector<std::pair<unsigned, std::string> > RecordNames; | std::vector<std::pair<unsigned, std::string> > RecordNames; | |||
skipping to change at line 122 | skipping to change at line 127 | |||
BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { | BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { | |||
if (const BlockInfo *BI = getBlockInfo(BlockID)) | if (const BlockInfo *BI = getBlockInfo(BlockID)) | |||
return *const_cast<BlockInfo*>(BI); | return *const_cast<BlockInfo*>(BI); | |||
// Otherwise, add a new record. | // Otherwise, add a new record. | |||
BlockInfoRecords.push_back(BlockInfo()); | BlockInfoRecords.push_back(BlockInfo()); | |||
BlockInfoRecords.back().BlockID = BlockID; | BlockInfoRecords.back().BlockID = BlockID; | |||
return BlockInfoRecords.back(); | return BlockInfoRecords.back(); | |||
} | } | |||
}; | ||||
/// BitstreamEntry - When advancing through a bitstream cursor, each advanc | ||||
e can | ||||
/// discover a few different kinds of entries: | ||||
/// Error - Malformed bitcode was found. | ||||
/// EndBlock - We've reached the end of the current block, (or the end of | ||||
the | ||||
/// file, which is treated like a series of EndBlock records. | ||||
/// SubBlock - This is the start of a new subblock of a specific ID. | ||||
/// Record - This is a record with a specific AbbrevID. | ||||
/// | ||||
struct BitstreamEntry { | ||||
enum { | ||||
Error, | ||||
EndBlock, | ||||
SubBlock, | ||||
Record | ||||
} Kind; | ||||
unsigned ID; | ||||
static BitstreamEntry getError() { | ||||
BitstreamEntry E; E.Kind = Error; return E; | ||||
} | ||||
static BitstreamEntry getEndBlock() { | ||||
BitstreamEntry E; E.Kind = EndBlock; return E; | ||||
} | ||||
static BitstreamEntry getSubBlock(unsigned ID) { | ||||
BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; | ||||
} | ||||
static BitstreamEntry getRecord(unsigned AbbrevID) { | ||||
BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E; | ||||
} | ||||
}; | }; | |||
/// BitstreamCursor - This represents a position within a bitcode file. Th | ||||
ere | ||||
/// may be multiple independent cursors reading within one bitstream, each | ||||
/// maintaining their own local state. | ||||
/// | ||||
/// Unlike iterators, BitstreamCursors are heavy-weight objects that should | ||||
not | ||||
/// be passed by value. | ||||
class BitstreamCursor { | class BitstreamCursor { | |||
friend class Deserializer; | friend class Deserializer; | |||
BitstreamReader *BitStream; | BitstreamReader *BitStream; | |||
size_t NextChar; | size_t NextChar; | |||
/// CurWord - This is the current data we have pulled from the stream but | /// CurWord/word_t - This is the current data we have pulled from the str | |||
have | eam | |||
/// not returned to the client. | /// but have not returned to the client. This is specifically and | |||
uint32_t CurWord; | /// intentionally defined to follow the word size of the host machine for | |||
/// efficiency. We use word_t in places that are aware of this to make i | ||||
t | ||||
/// perfectly explicit what is going on. | ||||
typedef uint32_t word_t; | ||||
word_t CurWord; | ||||
/// BitsInCurWord - This is the number of bits in CurWord that are valid. This | /// BitsInCurWord - This is the number of bits in CurWord that are valid. This | |||
/// is always from [0...31] inclusive. | /// is always from [0...31/63] inclusive (depending on word size). | |||
unsigned BitsInCurWord; | unsigned BitsInCurWord; | |||
// CurCodeSize - This is the declared size of code values used for the cu rrent | // CurCodeSize - This is the declared size of code values used for the cu rrent | |||
// block, in bits. | // block, in bits. | |||
unsigned CurCodeSize; | unsigned CurCodeSize; | |||
/// CurAbbrevs - Abbrevs installed at in this block. | /// CurAbbrevs - Abbrevs installed at in this block. | |||
std::vector<BitCodeAbbrev*> CurAbbrevs; | std::vector<BitCodeAbbrev*> CurAbbrevs; | |||
struct Block { | struct Block { | |||
skipping to change at line 182 | skipping to change at line 228 | |||
NextChar = 0; | NextChar = 0; | |||
CurWord = 0; | CurWord = 0; | |||
BitsInCurWord = 0; | BitsInCurWord = 0; | |||
CurCodeSize = 2; | CurCodeSize = 2; | |||
} | } | |||
~BitstreamCursor() { | ~BitstreamCursor() { | |||
freeState(); | freeState(); | |||
} | } | |||
void operator=(const BitstreamCursor &RHS) { | void operator=(const BitstreamCursor &RHS); | |||
freeState(); | ||||
BitStream = RHS.BitStream; | ||||
NextChar = RHS.NextChar; | ||||
CurWord = RHS.CurWord; | ||||
BitsInCurWord = RHS.BitsInCurWord; | ||||
CurCodeSize = RHS.CurCodeSize; | ||||
// Copy abbreviations, and bump ref counts. | void freeState(); | |||
CurAbbrevs = RHS.CurAbbrevs; | ||||
for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size()); | ||||
i != e; ++i) | ||||
CurAbbrevs[i]->addRef(); | ||||
// Copy block scope and bump ref counts. | ||||
BlockScope = RHS.BlockScope; | ||||
for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size()); | ||||
S != e; ++S) { | ||||
std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs; | ||||
for (unsigned i = 0, e = static_cast<unsigned>(Abbrevs.size()); | ||||
i != e; ++i) | ||||
Abbrevs[i]->addRef(); | ||||
} | ||||
} | ||||
void freeState() { | ||||
// Free all the Abbrevs. | ||||
for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size()); | ||||
i != e; ++i) | ||||
CurAbbrevs[i]->dropRef(); | ||||
CurAbbrevs.clear(); | ||||
// Free all the Abbrevs in the block scope. | ||||
for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size()); | ||||
S != e; ++S) { | ||||
std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs; | ||||
for (unsigned i = 0, e = static_cast<unsigned>(Abbrevs.size()); | ||||
i != e; ++i) | ||||
Abbrevs[i]->dropRef(); | ||||
} | ||||
BlockScope.clear(); | ||||
} | ||||
/// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev | ||||
#. | ||||
unsigned GetAbbrevIDWidth() const { return CurCodeSize; } | ||||
bool isEndPos(size_t pos) { | bool isEndPos(size_t pos) { | |||
return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(p os)); | return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(p os)); | |||
} | } | |||
bool canSkipToPos(size_t pos) const { | bool canSkipToPos(size_t pos) const { | |||
// pos can be skipped to if it is a valid address or one byte past the end. | // pos can be skipped to if it is a valid address or one byte past the end. | |||
return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( | return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( | |||
static_cast<uint64_t>(pos - 1)); | static_cast<uint64_t>(pos - 1)); | |||
} | } | |||
unsigned char getByte(size_t pos) { | ||||
uint8_t byte = -1; | ||||
BitStream->getBitcodeBytes().readByte(pos, &byte); | ||||
return byte; | ||||
} | ||||
uint32_t getWord(size_t pos) { | uint32_t getWord(size_t pos) { | |||
uint8_t buf[sizeof(uint32_t)]; | uint8_t buf[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; | |||
memset(buf, 0xFF, sizeof(buf)); | BitStream->getBitcodeBytes().readBytes(pos, sizeof(buf), buf, NULL); | |||
BitStream->getBitcodeBytes().readBytes(pos, | ||||
sizeof(buf), | ||||
buf, | ||||
NULL); | ||||
return *reinterpret_cast<support::ulittle32_t *>(buf); | return *reinterpret_cast<support::ulittle32_t *>(buf); | |||
} | } | |||
bool AtEndOfStream() { | bool AtEndOfStream() { | |||
return isEndPos(NextChar) && BitsInCurWord == 0; | return BitsInCurWord == 0 && isEndPos(NextChar); | |||
} | } | |||
/// getAbbrevIDWidth - Return the number of bits used to encode an abbrev | ||||
#. | ||||
unsigned getAbbrevIDWidth() const { return CurCodeSize; } | ||||
/// GetCurrentBitNo - Return the bit # of the bit we are reading. | /// GetCurrentBitNo - Return the bit # of the bit we are reading. | |||
uint64_t GetCurrentBitNo() const { | uint64_t GetCurrentBitNo() const { | |||
return NextChar*CHAR_BIT - BitsInCurWord; | return NextChar*CHAR_BIT - BitsInCurWord; | |||
} | } | |||
BitstreamReader *getBitStreamReader() { | BitstreamReader *getBitStreamReader() { | |||
return BitStream; | return BitStream; | |||
} | } | |||
const BitstreamReader *getBitStreamReader() const { | const BitstreamReader *getBitStreamReader() const { | |||
return BitStream; | return BitStream; | |||
} | } | |||
/// Flags that modify the behavior of advance(). | ||||
enum { | ||||
/// AF_DontPopBlockAtEnd - If this flag is used, the advance() method d | ||||
oes | ||||
/// not automatically pop the block scope when the end of a block is | ||||
/// reached. | ||||
AF_DontPopBlockAtEnd = 1, | ||||
/// AF_DontAutoprocessAbbrevs - If this flag is used, abbrev entries ar | ||||
e | ||||
/// returned just like normal records. | ||||
AF_DontAutoprocessAbbrevs = 2 | ||||
}; | ||||
/// advance - Advance the current bitstream, returning the next entry in | ||||
the | ||||
/// stream. | ||||
BitstreamEntry advance(unsigned Flags = 0) { | ||||
while (1) { | ||||
unsigned Code = ReadCode(); | ||||
if (Code == bitc::END_BLOCK) { | ||||
// Pop the end of the block unless Flags tells us not to. | ||||
if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd()) | ||||
return BitstreamEntry::getError(); | ||||
return BitstreamEntry::getEndBlock(); | ||||
} | ||||
if (Code == bitc::ENTER_SUBBLOCK) | ||||
return BitstreamEntry::getSubBlock(ReadSubBlockID()); | ||||
if (Code == bitc::DEFINE_ABBREV && | ||||
!(Flags & AF_DontAutoprocessAbbrevs)) { | ||||
// We read and accumulate abbrev's, the client can't do anything wi | ||||
th | ||||
// them anyway. | ||||
ReadAbbrevRecord(); | ||||
continue; | ||||
} | ||||
return BitstreamEntry::getRecord(Code); | ||||
} | ||||
} | ||||
/// advanceSkippingSubblocks - This is a convenience function for clients | ||||
that | ||||
/// don't expect any subblocks. This just skips over them automatically. | ||||
BitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) { | ||||
while (1) { | ||||
// If we found a normal entry, return it. | ||||
BitstreamEntry Entry = advance(Flags); | ||||
if (Entry.Kind != BitstreamEntry::SubBlock) | ||||
return Entry; | ||||
// If we found a sub-block, just skip over it and check the next entr | ||||
y. | ||||
if (SkipBlock()) | ||||
return BitstreamEntry::getError(); | ||||
} | ||||
} | ||||
/// JumpToBit - Reset the stream to the specified bit number. | /// JumpToBit - Reset the stream to the specified bit number. | |||
void JumpToBit(uint64_t BitNo) { | void JumpToBit(uint64_t BitNo) { | |||
uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; | uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); | |||
uintptr_t WordBitNo = uintptr_t(BitNo) & 31; | unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); | |||
assert(canSkipToPos(ByteNo) && "Invalid location"); | assert(canSkipToPos(ByteNo) && "Invalid location"); | |||
// Move the cursor to the right word. | // Move the cursor to the right word. | |||
NextChar = ByteNo; | NextChar = ByteNo; | |||
BitsInCurWord = 0; | BitsInCurWord = 0; | |||
CurWord = 0; | CurWord = 0; | |||
// Skip over any bits that are already consumed. | // Skip over any bits that are already consumed. | |||
if (WordBitNo) | if (WordBitNo) { | |||
Read(static_cast<unsigned>(WordBitNo)); | if (sizeof(word_t) > 4) | |||
Read64(WordBitNo); | ||||
else | ||||
Read(WordBitNo); | ||||
} | ||||
} | } | |||
uint32_t Read(unsigned NumBits) { | uint32_t Read(unsigned NumBits) { | |||
assert(NumBits <= 32 && "Cannot return more than 32 bits!"); | assert(NumBits && NumBits <= 32 && | |||
"Cannot return zero or more than 32 bits!"); | ||||
// If the field is fully contained by CurWord, return it quickly. | // If the field is fully contained by CurWord, return it quickly. | |||
if (BitsInCurWord >= NumBits) { | if (BitsInCurWord >= NumBits) { | |||
uint32_t R = CurWord & ((1U << NumBits)-1); | uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits)); | |||
CurWord >>= NumBits; | CurWord >>= NumBits; | |||
BitsInCurWord -= NumBits; | BitsInCurWord -= NumBits; | |||
return R; | return R; | |||
} | } | |||
// If we run out of data, stop at the end of the stream. | // If we run out of data, stop at the end of the stream. | |||
if (isEndPos(NextChar)) { | if (isEndPos(NextChar)) { | |||
CurWord = 0; | CurWord = 0; | |||
BitsInCurWord = 0; | BitsInCurWord = 0; | |||
return 0; | return 0; | |||
} | } | |||
unsigned R = CurWord; | uint32_t R = uint32_t(CurWord); | |||
// Read the next word from the stream. | // Read the next word from the stream. | |||
CurWord = getWord(NextChar); | uint8_t Array[sizeof(word_t)] = {0}; | |||
NextChar += 4; | ||||
BitStream->getBitcodeBytes().readBytes(NextChar, sizeof(Array), | ||||
Array, NULL); | ||||
// Handle big-endian byte-swapping if necessary. | ||||
support::detail::packed_endian_specific_integral | ||||
<word_t, support::little, support::unaligned> EndianValue; | ||||
memcpy(&EndianValue, Array, sizeof(Array)); | ||||
CurWord = EndianValue; | ||||
NextChar += sizeof(word_t); | ||||
// Extract NumBits-BitsInCurWord from what we just read. | // Extract NumBits-BitsInCurWord from what we just read. | |||
unsigned BitsLeft = NumBits-BitsInCurWord; | unsigned BitsLeft = NumBits-BitsInCurWord; | |||
// Be careful here, BitsLeft is in the range [1..32] inclusive. | // Be careful here, BitsLeft is in the range [1..32]/[1..64] inclusive. | |||
R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord; | R |= uint32_t((CurWord & (word_t(~0ULL) >> (sizeof(word_t)*8-BitsLeft)) | |||
) | ||||
// BitsLeft bits have just been used up from CurWord. | << BitsInCurWord); | |||
if (BitsLeft != 32) | ||||
// BitsLeft bits have just been used up from CurWord. BitsLeft is in t | ||||
he | ||||
// range [1..32]/[1..64] so be careful how we shift. | ||||
if (BitsLeft != sizeof(word_t)*8) | ||||
CurWord >>= BitsLeft; | CurWord >>= BitsLeft; | |||
else | else | |||
CurWord = 0; | CurWord = 0; | |||
BitsInCurWord = 32-BitsLeft; | BitsInCurWord = sizeof(word_t)*8-BitsLeft; | |||
return R; | return R; | |||
} | } | |||
uint64_t Read64(unsigned NumBits) { | uint64_t Read64(unsigned NumBits) { | |||
if (NumBits <= 32) return Read(NumBits); | if (NumBits <= 32) return Read(NumBits); | |||
uint64_t V = Read(32); | uint64_t V = Read(32); | |||
return V | (uint64_t)Read(NumBits-32) << 32; | return V | (uint64_t)Read(NumBits-32) << 32; | |||
} | } | |||
skipping to change at line 370 | skipping to change at line 439 | |||
Result |= uint64_t(Piece & ((1U << (NumBits-1))-1)) << NextBit; | Result |= uint64_t(Piece & ((1U << (NumBits-1))-1)) << NextBit; | |||
if ((Piece & (1U << (NumBits-1))) == 0) | if ((Piece & (1U << (NumBits-1))) == 0) | |||
return Result; | return Result; | |||
NextBit += NumBits-1; | NextBit += NumBits-1; | |||
Piece = Read(NumBits); | Piece = Read(NumBits); | |||
} | } | |||
} | } | |||
void SkipToWord() { | private: | |||
void SkipToFourByteBoundary() { | ||||
// If word_t is 64-bits and if we've read less than 32 bits, just dump | ||||
// the bits we have up to the next 32-bit boundary. | ||||
if (sizeof(word_t) > 4 && | ||||
BitsInCurWord >= 32) { | ||||
CurWord >>= BitsInCurWord-32; | ||||
BitsInCurWord = 32; | ||||
return; | ||||
} | ||||
BitsInCurWord = 0; | BitsInCurWord = 0; | |||
CurWord = 0; | CurWord = 0; | |||
} | } | |||
public: | ||||
unsigned ReadCode() { | unsigned ReadCode() { | |||
return Read(CurCodeSize); | return Read(CurCodeSize); | |||
} | } | |||
// Block header: | // Block header: | |||
// [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] | // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] | |||
/// ReadSubBlockID - Having read the ENTER_SUBBLOCK code, read the BlockI D for | /// ReadSubBlockID - Having read the ENTER_SUBBLOCK code, read the BlockI D for | |||
/// the block. | /// the block. | |||
skipping to change at line 395 | skipping to change at line 475 | |||
return ReadVBR(bitc::BlockIDWidth); | return ReadVBR(bitc::BlockIDWidth); | |||
} | } | |||
/// SkipBlock - Having read the ENTER_SUBBLOCK abbrevid and a BlockID, sk ip | /// SkipBlock - Having read the ENTER_SUBBLOCK abbrevid and a BlockID, sk ip | |||
/// over the body of this block. If the block record is malformed, retur n | /// over the body of this block. If the block record is malformed, retur n | |||
/// true. | /// true. | |||
bool SkipBlock() { | bool SkipBlock() { | |||
// Read and ignore the codelen value. Since we are skipping this block , we | // Read and ignore the codelen value. Since we are skipping this block , we | |||
// don't care what code widths are used inside of it. | // don't care what code widths are used inside of it. | |||
ReadVBR(bitc::CodeLenWidth); | ReadVBR(bitc::CodeLenWidth); | |||
SkipToWord(); | SkipToFourByteBoundary(); | |||
unsigned NumWords = Read(bitc::BlockSizeWidth); | unsigned NumFourBytes = Read(bitc::BlockSizeWidth); | |||
// Check that the block wasn't partially defined, and that the offset i sn't | // Check that the block wasn't partially defined, and that the offset i sn't | |||
// bogus. | // bogus. | |||
size_t SkipTo = NextChar + NumWords*4; | size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8; | |||
if (AtEndOfStream() || !canSkipToPos(SkipTo)) | if (AtEndOfStream() || !canSkipToPos(SkipTo/8)) | |||
return true; | return true; | |||
NextChar = SkipTo; | JumpToBit(SkipTo); | |||
return false; | return false; | |||
} | } | |||
/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter | /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter | |||
/// the block, and return true if the block has an error. | /// the block, and return true if the block has an error. | |||
bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) { | bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0); | |||
// Save the current block's state on BlockScope. | ||||
BlockScope.push_back(Block(CurCodeSize)); | ||||
BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); | ||||
// Add the abbrevs specific to this block to the CurAbbrevs list. | ||||
if (const BitstreamReader::BlockInfo *Info = | ||||
BitStream->getBlockInfo(BlockID)) { | ||||
for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size()); | ||||
i != e; ++i) { | ||||
CurAbbrevs.push_back(Info->Abbrevs[i]); | ||||
CurAbbrevs.back()->addRef(); | ||||
} | ||||
} | ||||
// Get the codesize of this block. | ||||
CurCodeSize = ReadVBR(bitc::CodeLenWidth); | ||||
SkipToWord(); | ||||
unsigned NumWords = Read(bitc::BlockSizeWidth); | ||||
if (NumWordsP) *NumWordsP = NumWords; | ||||
// Validate that this block is sane. | ||||
if (CurCodeSize == 0 || AtEndOfStream()) | ||||
return true; | ||||
return false; | ||||
} | ||||
bool ReadBlockEnd() { | bool ReadBlockEnd() { | |||
if (BlockScope.empty()) return true; | if (BlockScope.empty()) return true; | |||
// Block tail: | // Block tail: | |||
// [END_BLOCK, <align4bytes>] | // [END_BLOCK, <align4bytes>] | |||
SkipToWord(); | SkipToFourByteBoundary(); | |||
PopBlockScope(); | popBlockScope(); | |||
return false; | return false; | |||
} | } | |||
private: | private: | |||
void PopBlockScope() { | ||||
void popBlockScope() { | ||||
CurCodeSize = BlockScope.back().PrevCodeSize; | CurCodeSize = BlockScope.back().PrevCodeSize; | |||
// Delete abbrevs from popped scope. | // Delete abbrevs from popped scope. | |||
for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size()); | for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size()); | |||
i != e; ++i) | i != e; ++i) | |||
CurAbbrevs[i]->dropRef(); | CurAbbrevs[i]->dropRef(); | |||
BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); | BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); | |||
BlockScope.pop_back(); | BlockScope.pop_back(); | |||
} | } | |||
//===--------------------------------------------------------------------= ==// | //===-------------------------------------------------------------------- ===// | |||
// Record Processing | // Record Processing | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
private: | private: | |||
void ReadAbbreviatedLiteral(const BitCodeAbbrevOp &Op, | void readAbbreviatedLiteral(const BitCodeAbbrevOp &Op, | |||
SmallVectorImpl<uint64_t> &Vals) { | SmallVectorImpl<uint64_t> &Vals); | |||
assert(Op.isLiteral() && "Not a literal"); | void readAbbreviatedField(const BitCodeAbbrevOp &Op, | |||
// If the abbrev specifies the literal value to use, use it. | SmallVectorImpl<uint64_t> &Vals); | |||
Vals.push_back(Op.getLiteralValue()); | void skipAbbreviatedField(const BitCodeAbbrevOp &Op); | |||
} | ||||
void ReadAbbreviatedField(const BitCodeAbbrevOp &Op, | ||||
SmallVectorImpl<uint64_t> &Vals) { | ||||
assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!"); | ||||
// Decode the value as we are commanded. | ||||
switch (Op.getEncoding()) { | ||||
default: llvm_unreachable("Unknown encoding!"); | ||||
case BitCodeAbbrevOp::Fixed: | ||||
Vals.push_back(Read((unsigned)Op.getEncodingData())); | ||||
break; | ||||
case BitCodeAbbrevOp::VBR: | ||||
Vals.push_back(ReadVBR64((unsigned)Op.getEncodingData())); | ||||
break; | ||||
case BitCodeAbbrevOp::Char6: | ||||
Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6))); | ||||
break; | ||||
} | ||||
} | ||||
public: | public: | |||
/// getAbbrev - Return the abbreviation for the specified AbbrevId. | /// getAbbrev - Return the abbreviation for the specified AbbrevId. | |||
const BitCodeAbbrev *getAbbrev(unsigned AbbrevID) { | const BitCodeAbbrev *getAbbrev(unsigned AbbrevID) { | |||
unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV; | unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV; | |||
assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); | assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); | |||
return CurAbbrevs[AbbrevNo]; | return CurAbbrevs[AbbrevNo]; | |||
} | } | |||
unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals, | /// skipRecord - Read the current record and discard it. | |||
const char **BlobStart = 0, unsigned *BlobLen = 0) { | void skipRecord(unsigned AbbrevID); | |||
if (AbbrevID == bitc::UNABBREV_RECORD) { | ||||
unsigned Code = ReadVBR(6); | ||||
unsigned NumElts = ReadVBR(6); | ||||
for (unsigned i = 0; i != NumElts; ++i) | ||||
Vals.push_back(ReadVBR64(6)); | ||||
return Code; | ||||
} | ||||
const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID); | unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals, | |||
StringRef *Blob = 0); | ||||
for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { | ||||
const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); | ||||
if (Op.isLiteral()) { | ||||
ReadAbbreviatedLiteral(Op, Vals); | ||||
} else if (Op.getEncoding() == BitCodeAbbrevOp::Array) { | ||||
// Array case. Read the number of elements as a vbr6. | ||||
unsigned NumElts = ReadVBR(6); | ||||
// Get the element encoding. | ||||
assert(i+2 == e && "array op not second to last?"); | ||||
const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); | ||||
// Read all the elements. | ||||
for (; NumElts; --NumElts) | ||||
ReadAbbreviatedField(EltEnc, Vals); | ||||
} else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { | ||||
// Blob case. Read the number of bytes as a vbr6. | ||||
unsigned NumElts = ReadVBR(6); | ||||
SkipToWord(); // 32-bit alignment | ||||
// Figure out where the end of this blob will be including tail pad | ||||
ding. | ||||
size_t NewEnd = NextChar+((NumElts+3)&~3); | ||||
// If this would read off the end of the bitcode file, just set the | ||||
// record to empty and return. | ||||
if (!canSkipToPos(NewEnd)) { | ||||
Vals.append(NumElts, 0); | ||||
NextChar = BitStream->getBitcodeBytes().getExtent(); | ||||
break; | ||||
} | ||||
// Otherwise, read the number of bytes. If we can return a referen | ||||
ce to | ||||
// the data, do so to avoid copying it. | ||||
if (BlobStart) { | ||||
*BlobStart = (const char*)BitStream->getBitcodeBytes().getPointer | ||||
( | ||||
NextChar, NumElts); | ||||
*BlobLen = NumElts; | ||||
} else { | ||||
for (; NumElts; ++NextChar, --NumElts) | ||||
Vals.push_back(getByte(NextChar)); | ||||
} | ||||
// Skip over tail padding. | ||||
NextChar = NewEnd; | ||||
} else { | ||||
ReadAbbreviatedField(Op, Vals); | ||||
} | ||||
} | ||||
unsigned Code = (unsigned)Vals[0]; | ||||
Vals.erase(Vals.begin()); | ||||
return Code; | ||||
} | ||||
unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals, | ||||
const char *&BlobStart, unsigned &BlobLen) { | ||||
return ReadRecord(AbbrevID, Vals, &BlobStart, &BlobLen); | ||||
} | ||||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Abbrev Processing | // Abbrev Processing | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
void ReadAbbrevRecord(); | ||||
void ReadAbbrevRecord() { | bool ReadBlockInfoBlock(); | |||
BitCodeAbbrev *Abbv = new BitCodeAbbrev(); | ||||
unsigned NumOpInfo = ReadVBR(5); | ||||
for (unsigned i = 0; i != NumOpInfo; ++i) { | ||||
bool IsLiteral = Read(1) ? true : false; | ||||
if (IsLiteral) { | ||||
Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8))); | ||||
continue; | ||||
} | ||||
BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3); | ||||
if (BitCodeAbbrevOp::hasEncodingData(E)) | ||||
Abbv->Add(BitCodeAbbrevOp(E, ReadVBR64(5))); | ||||
else | ||||
Abbv->Add(BitCodeAbbrevOp(E)); | ||||
} | ||||
CurAbbrevs.push_back(Abbv); | ||||
} | ||||
public: | ||||
bool ReadBlockInfoBlock() { | ||||
// If this is the second stream to get to the block info block, skip it | ||||
. | ||||
if (BitStream->hasBlockInfoRecords()) | ||||
return SkipBlock(); | ||||
if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true; | ||||
SmallVector<uint64_t, 64> Record; | ||||
BitstreamReader::BlockInfo *CurBlockInfo = 0; | ||||
// Read all the records for this module. | ||||
while (1) { | ||||
unsigned Code = ReadCode(); | ||||
if (Code == bitc::END_BLOCK) | ||||
return ReadBlockEnd(); | ||||
if (Code == bitc::ENTER_SUBBLOCK) { | ||||
ReadSubBlockID(); | ||||
if (SkipBlock()) return true; | ||||
continue; | ||||
} | ||||
// Read abbrev records, associate them with CurBID. | ||||
if (Code == bitc::DEFINE_ABBREV) { | ||||
if (!CurBlockInfo) return true; | ||||
ReadAbbrevRecord(); | ||||
// ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to | ||||
the | ||||
// appropriate BlockInfo. | ||||
BitCodeAbbrev *Abbv = CurAbbrevs.back(); | ||||
CurAbbrevs.pop_back(); | ||||
CurBlockInfo->Abbrevs.push_back(Abbv); | ||||
continue; | ||||
} | ||||
// Read a record. | ||||
Record.clear(); | ||||
switch (ReadRecord(Code, Record)) { | ||||
default: break; // Default behavior, ignore unknown content. | ||||
case bitc::BLOCKINFO_CODE_SETBID: | ||||
if (Record.size() < 1) return true; | ||||
CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0] | ||||
); | ||||
break; | ||||
case bitc::BLOCKINFO_CODE_BLOCKNAME: { | ||||
if (!CurBlockInfo) return true; | ||||
if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name. | ||||
std::string Name; | ||||
for (unsigned i = 0, e = Record.size(); i != e; ++i) | ||||
Name += (char)Record[i]; | ||||
CurBlockInfo->Name = Name; | ||||
break; | ||||
} | ||||
case bitc::BLOCKINFO_CODE_SETRECORDNAME: { | ||||
if (!CurBlockInfo) return true; | ||||
if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name. | ||||
std::string Name; | ||||
for (unsigned i = 1, e = Record.size(); i != e; ++i) | ||||
Name += (char)Record[i]; | ||||
CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record | ||||
[0], | ||||
Name)); | ||||
break; | ||||
} | ||||
} | ||||
} | ||||
} | ||||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 37 change blocks. | ||||
303 lines changed or deleted | 200 lines changed or added | |||
BitstreamWriter.h | BitstreamWriter.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This header defines the BitstreamWriter class. This class can be used t o | // This header defines the BitstreamWriter class. This class can be used t o | |||
// write an arbitrary bitstream, regardless of its contents. | // write an arbitrary bitstream, regardless of its contents. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef BITSTREAM_WRITER_H | #ifndef LLVM_BITCODE_BITSTREAMWRITER_H | |||
#define BITSTREAM_WRITER_H | #define LLVM_BITCODE_BITSTREAMWRITER_H | |||
#include "llvm/ADT/StringRef.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/StringRef.h" | ||||
#include "llvm/Bitcode/BitCodes.h" | #include "llvm/Bitcode/BitCodes.h" | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class BitstreamWriter { | class BitstreamWriter { | |||
SmallVectorImpl<char> &Out; | SmallVectorImpl<char> &Out; | |||
/// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use. | /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use. | |||
unsigned CurBit; | unsigned CurBit; | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
BlockFrequencyImpl.h | BlockFrequencyImpl.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// Shared implementation of BlockFrequency for IR and Machine Instructions. | // Shared implementation of BlockFrequency for IR and Machine Instructions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H | #ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H | |||
#define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H | #define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H | |||
#include "llvm/BasicBlock.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/PostOrderIterator.h" | #include "llvm/ADT/PostOrderIterator.h" | |||
#include "llvm/CodeGen/MachineBasicBlock.h" | #include "llvm/CodeGen/MachineBasicBlock.h" | |||
#include "llvm/CodeGen/MachineFunction.h" | #include "llvm/CodeGen/MachineFunction.h" | |||
#include "llvm/IR/BasicBlock.h" | ||||
#include "llvm/Support/BlockFrequency.h" | #include "llvm/Support/BlockFrequency.h" | |||
#include "llvm/Support/BranchProbability.h" | #include "llvm/Support/BranchProbability.h" | |||
#include "llvm/Support/Debug.h" | #include "llvm/Support/Debug.h" | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
#include <vector> | ||||
#include <string> | #include <string> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
class BlockFrequencyInfo; | class BlockFrequencyInfo; | |||
class MachineBlockFrequencyInfo; | class MachineBlockFrequencyInfo; | |||
/// BlockFrequencyImpl implements block frequency algorithm for IR and | /// BlockFrequencyImpl implements block frequency algorithm for IR and | |||
/// Machine Instructions. Algorithm starts with value 1024 (START_FREQ) | /// Machine Instructions. Algorithm starts with value 1024 (START_FREQ) | |||
/// for the entry block and then propagates frequencies using branch weight s | /// for the entry block and then propagates frequencies using branch weight s | |||
/// from (Machine)BranchProbabilityInfo. LoopInfo is not required because | /// from (Machine)BranchProbabilityInfo. LoopInfo is not required because | |||
skipping to change at line 272 | skipping to change at line 272 | |||
BPI = bpi; | BPI = bpi; | |||
// Clear everything. | // Clear everything. | |||
RPO.clear(); | RPO.clear(); | |||
POT.clear(); | POT.clear(); | |||
CycleProb.clear(); | CycleProb.clear(); | |||
Freqs.clear(); | Freqs.clear(); | |||
BlockT *EntryBlock = fn->begin(); | BlockT *EntryBlock = fn->begin(); | |||
copy(po_begin(EntryBlock), po_end(EntryBlock), back_inserter(POT)); | std::copy(po_begin(EntryBlock), po_end(EntryBlock), std::back_inserter( POT)); | |||
unsigned RPOidx = 0; | unsigned RPOidx = 0; | |||
for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) { | for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) { | |||
BlockT *BB = *I; | BlockT *BB = *I; | |||
RPO[BB] = ++RPOidx; | RPO[BB] = ++RPOidx; | |||
DEBUG(dbgs() << "RPO[" << getBlockName(BB) << "] = " << RPO[BB] << "\ n"); | DEBUG(dbgs() << "RPO[" << getBlockName(BB) << "] = " << RPO[BB] << "\ n"); | |||
} | } | |||
// Travel over all blocks in postorder. | // Travel over all blocks in postorder. | |||
for (pot_iterator I = pot_begin(), E = pot_end(); I != E; ++I) { | for (pot_iterator I = pot_begin(), E = pot_end(); I != E; ++I) { | |||
End of changes. 5 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
BranchProbabilityInfo.h | BranchProbabilityInfo.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This pass is used to evaluate branch probabilties. | // This pass is used to evaluate branch probabilties. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H | #ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H | |||
#define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H | #define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H | |||
#include "llvm/InitializePasses.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/InitializePasses.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/Support/BranchProbability.h" | #include "llvm/Support/BranchProbability.h" | |||
namespace llvm { | namespace llvm { | |||
class LoopInfo; | class LoopInfo; | |||
class raw_ostream; | class raw_ostream; | |||
/// \brief Analysis pass providing branch probability information. | /// \brief Analysis pass providing branch probability information. | |||
/// | /// | |||
/// This is a function analysis pass which provides information on the rela tive | /// This is a function analysis pass which provides information on the rela tive | |||
/// probabilities of each "edge" in the function's CFG where such an edge i s | /// probabilities of each "edge" in the function's CFG where such an edge i s | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Briggs.h | Briggs.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// PBQP graph representing a register allocation problem. Nodes which can b e | // PBQP graph representing a register allocation problem. Nodes which can b e | |||
// proven allocable (by a safe and relatively accurate test) are removed fr om | // proven allocable (by a safe and relatively accurate test) are removed fr om | |||
// the PBQP graph first. If no provably allocable node is present in the gr aph | // the PBQP graph first. If no provably allocable node is present in the gr aph | |||
// then the node with the minimal spill-cost to degree ratio is removed. | // then the node with the minimal spill-cost to degree ratio is removed. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H | #ifndef LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H | |||
#define LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H | #define LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H | |||
#include "../HeuristicSolver.h" | ||||
#include "../HeuristicBase.h" | #include "../HeuristicBase.h" | |||
#include "../HeuristicSolver.h" | ||||
#include <limits> | #include <limits> | |||
namespace PBQP { | namespace PBQP { | |||
namespace Heuristics { | namespace Heuristics { | |||
/// \brief PBQP Heuristic which applies an allocability test based on | /// \brief PBQP Heuristic which applies an allocability test based on | |||
/// Briggs. | /// Briggs. | |||
/// | /// | |||
/// This heuristic assumes that the elements of cost vectors in the PBQ P | /// This heuristic assumes that the elements of cost vectors in the PBQ P | |||
/// problem represent storage options, with the first being the spill | /// problem represent storage options, with the first being the spill | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 1 lines changed or added | |||
BuildLibCalls.h | BuildLibCalls.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file exposes an interface to build some C language libcalls for | // This file exposes an interface to build some C language libcalls for | |||
// optimization passes that need to call the various functions. | // optimization passes that need to call the various functions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef TRANSFORMS_UTILS_BUILDLIBCALLS_H | #ifndef LLVM_TRANSFORMS_UTILS_BUILDLIBCALLS_H | |||
#define TRANSFORMS_UTILS_BUILDLIBCALLS_H | #define LLVM_TRANSFORMS_UTILS_BUILDLIBCALLS_H | |||
#include "llvm/IRBuilder.h" | #include "llvm/IR/IRBuilder.h" | |||
namespace llvm { | namespace llvm { | |||
class Value; | class Value; | |||
class DataLayout; | class DataLayout; | |||
class TargetLibraryInfo; | class TargetLibraryInfo; | |||
/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. | /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. | |||
Value *CastToCStr(Value *V, IRBuilder<> &B); | Value *CastToCStr(Value *V, IRBuilder<> &B); | |||
/// EmitStrLen - Emit a call to the strlen function to the builder, for t he | /// EmitStrLen - Emit a call to the strlen function to the builder, for t he | |||
skipping to change at line 84 | skipping to change at line 84 | |||
/// EmitMemCmp - Emit a call to the memcmp function. | /// EmitMemCmp - Emit a call to the memcmp function. | |||
Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, | Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, | |||
const DataLayout *TD, const TargetLibraryInfo *TLI); | const DataLayout *TD, const TargetLibraryInfo *TLI); | |||
/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' | /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' | |||
/// (e.g. 'floor'). This function is known to take a single of type mat ching | /// (e.g. 'floor'). This function is known to take a single of type mat ching | |||
/// 'Op' and returns one value with the same type. If 'Op' is a long dou ble, | /// 'Op' and returns one value with the same type. If 'Op' is a long dou ble, | |||
/// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f' | /// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f' | |||
/// suffix. | /// suffix. | |||
Value *EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, | Value *EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, | |||
const AttrListPtr &Attrs); | const AttributeSet &Attrs); | |||
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char | /// EmitPutChar - Emit a call to the putchar function. This assumes that Char | |||
/// is an integer. | /// is an integer. | |||
Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD, | Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD, | |||
const TargetLibraryInfo *TLI); | const TargetLibraryInfo *TLI); | |||
/// EmitPutS - Emit a call to the puts function. This assumes that Str i s | /// EmitPutS - Emit a call to the puts function. This assumes that Str i s | |||
/// some pointer. | /// some pointer. | |||
Value *EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD, | Value *EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD, | |||
const TargetLibraryInfo *TLI); | const TargetLibraryInfo *TLI); | |||
End of changes. 3 change blocks. | ||||
4 lines changed or deleted | 4 lines changed or added | |||
BypassSlowDivision.h | BypassSlowDivision.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains an optimization for div and rem on architectures that | // This file contains an optimization for div and rem on architectures that | |||
// execute short instructions significantly faster than longer instructions . | // execute short instructions significantly faster than longer instructions . | |||
// For example, on Intel Atom 32-bit divides are slow enough that during | // For example, on Intel Atom 32-bit divides are slow enough that during | |||
// runtime it is profitable to check the value of the operands, and if they are | // runtime it is profitable to check the value of the operands, and if they are | |||
// positive and less than 256 use an unsigned 8-bit divide. | // positive and less than 256 use an unsigned 8-bit divide. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H | #ifndef LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H | |||
#define TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H | #define LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H | |||
#include "llvm/Function.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/IR/Function.h" | ||||
namespace llvm { | namespace llvm { | |||
/// This optimization identifies DIV instructions that can be | /// This optimization identifies DIV instructions that can be | |||
/// profitably bypassed and carried out with a shorter, faster divide. | /// profitably bypassed and carried out with a shorter, faster divide. | |||
bool bypassSlowDivision(Function &F, | bool bypassSlowDivision(Function &F, | |||
Function::iterator &I, | Function::iterator &I, | |||
const DenseMap<unsigned int, unsigned int> &BypassW idth); | const DenseMap<unsigned int, unsigned int> &BypassW idth); | |||
} // End llvm namespace | } // End llvm namespace | |||
End of changes. 2 change blocks. | ||||
3 lines changed or deleted | 4 lines changed or added | |||
CFG.h | CFG.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file defines specializations of GraphTraits that allow Function and | // This file defines specializations of GraphTraits that allow Function and | |||
// BasicBlock graphs to be treated as proper graphs for generic algorithms. | // BasicBlock graphs to be treated as proper graphs for generic algorithms. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_CFG_H | #ifndef LLVM_SUPPORT_CFG_H | |||
#define LLVM_SUPPORT_CFG_H | #define LLVM_SUPPORT_CFG_H | |||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/Function.h" | #include "llvm/IR/Function.h" | |||
#include "llvm/InstrTypes.h" | #include "llvm/IR/InstrTypes.h" | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// BasicBlock pred_iterator definition | // BasicBlock pred_iterator definition | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
template <class Ptr, class USE_iterator> // Predecessor Iterator | template <class Ptr, class USE_iterator> // Predecessor Iterator | |||
class PredIterator : public std::iterator<std::forward_iterator_tag, | class PredIterator : public std::iterator<std::forward_iterator_tag, | |||
Ptr, ptrdiff_t> { | Ptr, ptrdiff_t, Ptr*, Ptr*> { | |||
typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t> super; | typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*, | |||
Ptr*> s | ||||
uper; | ||||
typedef PredIterator<Ptr, USE_iterator> Self; | typedef PredIterator<Ptr, USE_iterator> Self; | |||
USE_iterator It; | USE_iterator It; | |||
inline void advancePastNonTerminators() { | inline void advancePastNonTerminators() { | |||
// Loop to ignore non terminator uses (for example BlockAddresses). | // Loop to ignore non terminator uses (for example BlockAddresses). | |||
while (!It.atEnd() && !isa<TerminatorInst>(*It)) | while (!It.atEnd() && !isa<TerminatorInst>(*It)) | |||
++It; | ++It; | |||
} | } | |||
public: | public: | |||
typedef typename super::pointer pointer; | typedef typename super::pointer pointer; | |||
typedef typename super::reference reference; | ||||
PredIterator() {} | PredIterator() {} | |||
explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) { | explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) { | |||
advancePastNonTerminators(); | advancePastNonTerminators(); | |||
} | } | |||
inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {} | inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {} | |||
inline bool operator==(const Self& x) const { return It == x.It; } | inline bool operator==(const Self& x) const { return It == x.It; } | |||
inline bool operator!=(const Self& x) const { return !operator==(x); } | inline bool operator!=(const Self& x) const { return !operator==(x); } | |||
inline pointer operator*() const { | inline reference operator*() const { | |||
assert(!It.atEnd() && "pred_iterator out of range!"); | assert(!It.atEnd() && "pred_iterator out of range!"); | |||
return cast<TerminatorInst>(*It)->getParent(); | return cast<TerminatorInst>(*It)->getParent(); | |||
} | } | |||
inline pointer *operator->() const { return &operator*(); } | inline pointer *operator->() const { return &operator*(); } | |||
inline Self& operator++() { // Preincrement | inline Self& operator++() { // Preincrement | |||
assert(!It.atEnd() && "pred_iterator out of range!"); | assert(!It.atEnd() && "pred_iterator out of range!"); | |||
++It; advancePastNonTerminators(); | ++It; advancePastNonTerminators(); | |||
return *this; | return *this; | |||
} | } | |||
skipping to change at line 101 | skipping to change at line 103 | |||
inline const_pred_iterator pred_end(const BasicBlock *BB) { | inline const_pred_iterator pred_end(const BasicBlock *BB) { | |||
return const_pred_iterator(BB, true); | return const_pred_iterator(BB, true); | |||
} | } | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// BasicBlock succ_iterator definition | // BasicBlock succ_iterator definition | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
template <class Term_, class BB_> // Successor Iterator | template <class Term_, class BB_> // Successor Iterator | |||
class SuccIterator : public std::iterator<std::bidirectional_iterator_tag, | class SuccIterator : public std::iterator<std::bidirectional_iterator_tag, | |||
BB_, ptrdiff_t> { | BB_, ptrdiff_t, BB_*, BB_*> { | |||
const Term_ Term; | const Term_ Term; | |||
unsigned idx; | unsigned idx; | |||
typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t> su | typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t, BB | |||
per; | _*, | |||
BB_*> s | ||||
uper; | ||||
typedef SuccIterator<Term_, BB_> Self; | typedef SuccIterator<Term_, BB_> Self; | |||
inline bool index_is_valid(int idx) { | inline bool index_is_valid(int idx) { | |||
return idx >= 0 && (unsigned) idx < Term->getNumSuccessors(); | return idx >= 0 && (unsigned) idx < Term->getNumSuccessors(); | |||
} | } | |||
public: | public: | |||
typedef typename super::pointer pointer; | typedef typename super::pointer pointer; | |||
typedef typename super::reference reference; | ||||
// TODO: This can be random access iterator, only operator[] missing. | // TODO: This can be random access iterator, only operator[] missing. | |||
explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterato r | explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterato r | |||
} | } | |||
inline SuccIterator(Term_ T, bool) // end iterator | inline SuccIterator(Term_ T, bool) // end iterator | |||
: Term(T) { | : Term(T) { | |||
if (Term) | if (Term) | |||
idx = Term->getNumSuccessors(); | idx = Term->getNumSuccessors(); | |||
else | else | |||
// Term == NULL happens, if a basic block is not fully constructed an d | // Term == NULL happens, if a basic block is not fully constructed an d | |||
skipping to change at line 143 | skipping to change at line 147 | |||
return *this; | return *this; | |||
} | } | |||
/// getSuccessorIndex - This is used to interface between code that wants to | /// getSuccessorIndex - This is used to interface between code that wants to | |||
/// operate on terminator instructions directly. | /// operate on terminator instructions directly. | |||
unsigned getSuccessorIndex() const { return idx; } | unsigned getSuccessorIndex() const { return idx; } | |||
inline bool operator==(const Self& x) const { return idx == x.idx; } | inline bool operator==(const Self& x) const { return idx == x.idx; } | |||
inline bool operator!=(const Self& x) const { return !operator==(x); } | inline bool operator!=(const Self& x) const { return !operator==(x); } | |||
inline pointer operator*() const { return Term->getSuccessor(idx); } | inline reference operator*() const { return Term->getSuccessor(idx); } | |||
inline pointer operator->() const { return operator*(); } | inline pointer operator->() const { return operator*(); } | |||
inline Self& operator++() { ++idx; return *this; } // Preincrement | inline Self& operator++() { ++idx; return *this; } // Preincrement | |||
inline Self operator++(int) { // Postincrement | inline Self operator++(int) { // Postincrement | |||
Self tmp = *this; ++*this; return tmp; | Self tmp = *this; ++*this; return tmp; | |||
} | } | |||
inline Self& operator--() { --idx; return *this; } // Predecrement | inline Self& operator--() { --idx; return *this; } // Predecrement | |||
inline Self operator--(int) { // Postdecrement | inline Self operator--(int) { // Postdecrement | |||
End of changes. 8 change blocks. | ||||
9 lines changed or deleted | 15 lines changed or added | |||
CFGPrinter.h | CFGPrinter.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines external functions that can be called to explicitly | // This file defines external functions that can be called to explicitly | |||
// instantiate the CFG printer. | // instantiate the CFG printer. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_CFGPRINTER_H | #ifndef LLVM_ANALYSIS_CFGPRINTER_H | |||
#define LLVM_ANALYSIS_CFGPRINTER_H | #define LLVM_ANALYSIS_CFGPRINTER_H | |||
#include "llvm/Constants.h" | ||||
#include "llvm/Function.h" | ||||
#include "llvm/Instructions.h" | ||||
#include "llvm/Assembly/Writer.h" | #include "llvm/Assembly/Writer.h" | |||
#include "llvm/IR/Constants.h" | ||||
#include "llvm/IR/Function.h" | ||||
#include "llvm/IR/Instructions.h" | ||||
#include "llvm/Support/CFG.h" | #include "llvm/Support/CFG.h" | |||
#include "llvm/Support/GraphWriter.h" | #include "llvm/Support/GraphWriter.h" | |||
namespace llvm { | namespace llvm { | |||
template<> | template<> | |||
struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits { | struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits { | |||
DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} | DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} | |||
static std::string getGraphName(const Function *F) { | static std::string getGraphName(const Function *F) { | |||
End of changes. 2 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
CalcSpillWeights.h | CalcSpillWeights.h | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H | #ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H | |||
#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H | #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H | |||
#include "llvm/CodeGen/SlotIndexes.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/CodeGen/SlotIndexes.h" | ||||
namespace llvm { | namespace llvm { | |||
class LiveInterval; | class LiveInterval; | |||
class LiveIntervals; | class LiveIntervals; | |||
class MachineLoopInfo; | class MachineLoopInfo; | |||
/// normalizeSpillWeight - The spill weight of a live interval is compute d as: | /// normalizeSpillWeight - The spill weight of a live interval is compute d as: | |||
/// | /// | |||
/// (sum(use freq) + sum(def freq)) / (K + size) | /// (sum(use freq) + sum(def freq)) / (K + size) | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
CallGraph.h | CallGraph.h | |||
---|---|---|---|---|
skipping to change at line 54 | skipping to change at line 54 | |||
// CallGraph is, which it currently does by looking for a function named 'm ain'. | // CallGraph is, which it currently does by looking for a function named 'm ain'. | |||
// If no function named 'main' is found, the external node is used as the e ntry | // If no function named 'main' is found, the external node is used as the e ntry | |||
// node, reflecting the fact that any function without internal linkage cou ld | // node, reflecting the fact that any function without internal linkage cou ld | |||
// be called into (which is common for libraries). | // be called into (which is common for libraries). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_CALLGRAPH_H | #ifndef LLVM_ANALYSIS_CALLGRAPH_H | |||
#define LLVM_ANALYSIS_CALLGRAPH_H | #define LLVM_ANALYSIS_CALLGRAPH_H | |||
#include "llvm/Function.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/ADT/STLExtras.h" | #include "llvm/ADT/STLExtras.h" | |||
#include "llvm/IR/Function.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/Support/CallSite.h" | #include "llvm/Support/CallSite.h" | |||
#include "llvm/Support/ValueHandle.h" | ||||
#include "llvm/Support/IncludeFile.h" | #include "llvm/Support/IncludeFile.h" | |||
#include "llvm/Support/ValueHandle.h" | ||||
#include <map> | #include <map> | |||
namespace llvm { | namespace llvm { | |||
class Function; | class Function; | |||
class Module; | class Module; | |||
class CallGraphNode; | class CallGraphNode; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// CallGraph class definition | // CallGraph class definition | |||
End of changes. 4 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
CallGraphSCCPass.h | CallGraphSCCPass.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// are implemented as bottom-up traversals on the call graph. Because ther e may | // are implemented as bottom-up traversals on the call graph. Because ther e may | |||
// be cycles in the call graph, passes of this type operate on the call-gra ph in | // be cycles in the call graph, passes of this type operate on the call-gra ph in | |||
// SCC order: that is, they process function bottom-up, except for recursiv e | // SCC order: that is, they process function bottom-up, except for recursiv e | |||
// functions, which they process all at once. | // functions, which they process all at once. | |||
// | // | |||
// These passes are inherently interprocedural, and are required to keep th e | // These passes are inherently interprocedural, and are required to keep th e | |||
// call graph up-to-date if they do anything which could modify it. | // call graph up-to-date if they do anything which could modify it. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CALL_GRAPH_SCC_PASS_H | #ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H | |||
#define LLVM_CALL_GRAPH_SCC_PASS_H | #define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/Analysis/CallGraph.h" | #include "llvm/Analysis/CallGraph.h" | |||
#include "llvm/Pass.h" | ||||
namespace llvm { | namespace llvm { | |||
class CallGraphNode; | class CallGraphNode; | |||
class CallGraph; | class CallGraph; | |||
class PMStack; | class PMStack; | |||
class CallGraphSCC; | class CallGraphSCC; | |||
class CallGraphSCCPass : public Pass { | class CallGraphSCCPass : public Pass { | |||
public: | public: | |||
explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {} | explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {} | |||
/// createPrinterPass - Get a pass that prints the Module | /// createPrinterPass - Get a pass that prints the Module | |||
/// corresponding to a CallGraph. | /// corresponding to a CallGraph. | |||
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; | Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; | |||
using llvm::Pass::doInitialization; | ||||
using llvm::Pass::doFinalization; | ||||
/// doInitialization - This method is called before the SCC's of the prog ram | /// doInitialization - This method is called before the SCC's of the prog ram | |||
/// has been processed, allowing the pass to do initialization as necessa ry. | /// has been processed, allowing the pass to do initialization as necessa ry. | |||
virtual bool doInitialization(CallGraph &CG) { | virtual bool doInitialization(CallGraph &CG) { | |||
return false; | return false; | |||
} | } | |||
/// runOnSCC - This method should be implemented by the subclass to perfo rm | /// runOnSCC - This method should be implemented by the subclass to perfo rm | |||
/// whatever action is necessary for the specified SCC. Note that | /// whatever action is necessary for the specified SCC. Note that | |||
/// non-recursive (or only self-recursive) functions will have an SCC siz e of | /// non-recursive (or only self-recursive) functions will have an SCC siz e of | |||
/// 1, where recursive portions of the call graph will have SCC size > 1. | /// 1, where recursive portions of the call graph will have SCC size > 1. | |||
End of changes. 4 change blocks. | ||||
3 lines changed or deleted | 6 lines changed or added | |||
CallSite.h | CallSite.h | |||
---|---|---|---|---|
skipping to change at line 29 | skipping to change at line 29 | |||
// equivalent to copying a pointer (notice that they have only a single dat a | // equivalent to copying a pointer (notice that they have only a single dat a | |||
// member). The internal representation carries a flag which indicates whic h of | // member). The internal representation carries a flag which indicates whic h of | |||
// the two variants is enclosed. This allows for cheaper checks when variou s | // the two variants is enclosed. This allows for cheaper checks when variou s | |||
// accessors of CallSite are employed. | // accessors of CallSite are employed. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_CALLSITE_H | #ifndef LLVM_SUPPORT_CALLSITE_H | |||
#define LLVM_SUPPORT_CALLSITE_H | #define LLVM_SUPPORT_CALLSITE_H | |||
#include "llvm/Attributes.h" | ||||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/BasicBlock.h" | #include "llvm/IR/Attributes.h" | |||
#include "llvm/CallingConv.h" | #include "llvm/IR/CallingConv.h" | |||
#include "llvm/Instructions.h" | #include "llvm/IR/Instructions.h" | |||
namespace llvm { | namespace llvm { | |||
class CallInst; | class CallInst; | |||
class InvokeInst; | class InvokeInst; | |||
template <typename FunTy = const Function, | template <typename FunTy = const Function, | |||
typename ValTy = const Value, | typename ValTy = const Value, | |||
typename UserTy = const User, | typename UserTy = const User, | |||
typename InstrTy = const Instruction, | typename InstrTy = const Instruction, | |||
skipping to change at line 180 | skipping to change at line 179 | |||
/// call. | /// call. | |||
CallingConv::ID getCallingConv() const { | CallingConv::ID getCallingConv() const { | |||
CALLSITE_DELEGATE_GETTER(getCallingConv()); | CALLSITE_DELEGATE_GETTER(getCallingConv()); | |||
} | } | |||
void setCallingConv(CallingConv::ID CC) { | void setCallingConv(CallingConv::ID CC) { | |||
CALLSITE_DELEGATE_SETTER(setCallingConv(CC)); | CALLSITE_DELEGATE_SETTER(setCallingConv(CC)); | |||
} | } | |||
/// getAttributes/setAttributes - get or set the parameter attributes of | /// getAttributes/setAttributes - get or set the parameter attributes of | |||
/// the call. | /// the call. | |||
const AttrListPtr &getAttributes() const { | const AttributeSet &getAttributes() const { | |||
CALLSITE_DELEGATE_GETTER(getAttributes()); | CALLSITE_DELEGATE_GETTER(getAttributes()); | |||
} | } | |||
void setAttributes(const AttrListPtr &PAL) { | void setAttributes(const AttributeSet &PAL) { | |||
CALLSITE_DELEGATE_SETTER(setAttributes(PAL)); | CALLSITE_DELEGATE_SETTER(setAttributes(PAL)); | |||
} | } | |||
/// \brief Return true if this function has the given attribute. | /// \brief Return true if this function has the given attribute. | |||
bool hasFnAttr(Attributes::AttrVal A) const { | bool hasFnAttr(Attribute::AttrKind A) const { | |||
CALLSITE_DELEGATE_GETTER(hasFnAttr(A)); | CALLSITE_DELEGATE_GETTER(hasFnAttr(A)); | |||
} | } | |||
/// \brief Return true if the call or the callee has the given attribute. | /// \brief Return true if the call or the callee has the given attribute. | |||
bool paramHasAttr(unsigned i, Attributes::AttrVal A) const { | bool paramHasAttr(unsigned i, Attribute::AttrKind A) const { | |||
CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A)); | CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A)); | |||
} | } | |||
/// @brief Extract the alignment for a call or parameter (0=unknown). | /// @brief Extract the alignment for a call or parameter (0=unknown). | |||
uint16_t getParamAlignment(uint16_t i) const { | uint16_t getParamAlignment(uint16_t i) const { | |||
CALLSITE_DELEGATE_GETTER(getParamAlignment(i)); | CALLSITE_DELEGATE_GETTER(getParamAlignment(i)); | |||
} | } | |||
/// @brief Return true if the call should not be inlined. | /// @brief Return true if the call should not be inlined. | |||
bool isNoInline() const { | bool isNoInline() const { | |||
skipping to change at line 247 | skipping to change at line 246 | |||
} | } | |||
void setDoesNotThrow() { | void setDoesNotThrow() { | |||
CALLSITE_DELEGATE_SETTER(setDoesNotThrow()); | CALLSITE_DELEGATE_SETTER(setDoesNotThrow()); | |||
} | } | |||
#undef CALLSITE_DELEGATE_GETTER | #undef CALLSITE_DELEGATE_GETTER | |||
#undef CALLSITE_DELEGATE_SETTER | #undef CALLSITE_DELEGATE_SETTER | |||
/// @brief Determine whether this argument is not captured. | /// @brief Determine whether this argument is not captured. | |||
bool doesNotCapture(unsigned ArgNo) const { | bool doesNotCapture(unsigned ArgNo) const { | |||
return paramHasAttr(ArgNo + 1, Attributes::NoCapture); | return paramHasAttr(ArgNo + 1, Attribute::NoCapture); | |||
} | } | |||
/// @brief Determine whether this argument is passed by value. | /// @brief Determine whether this argument is passed by value. | |||
bool isByValArgument(unsigned ArgNo) const { | bool isByValArgument(unsigned ArgNo) const { | |||
return paramHasAttr(ArgNo + 1, Attributes::ByVal); | return paramHasAttr(ArgNo + 1, Attribute::ByVal); | |||
} | } | |||
/// hasArgument - Returns true if this CallSite passes the given Value* a s an | /// hasArgument - Returns true if this CallSite passes the given Value* a s an | |||
/// argument to the called function. | /// argument to the called function. | |||
bool hasArgument(const Value *Arg) const { | bool hasArgument(const Value *Arg) const { | |||
for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E; | for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E; | |||
++AI) | ++AI) | |||
if (AI->get() == Arg) | if (AI->get() == Arg) | |||
return true; | return true; | |||
return false; | return false; | |||
End of changes. 8 change blocks. | ||||
10 lines changed or deleted | 9 lines changed or added | |||
CallingConv.h | CallingConv.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines LLVM's set of calling conventions. | // This file defines LLVM's set of calling conventions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CALLINGCONV_H | #ifndef LLVM_IR_CALLINGCONV_H | |||
#define LLVM_CALLINGCONV_H | #define LLVM_IR_CALLINGCONV_H | |||
namespace llvm { | namespace llvm { | |||
/// CallingConv Namespace - This namespace contains an enum with a value fo r | /// CallingConv Namespace - This namespace contains an enum with a value fo r | |||
/// the well-known calling conventions. | /// the well-known calling conventions. | |||
/// | /// | |||
namespace CallingConv { | namespace CallingConv { | |||
/// A set of enums which specify the assigned numeric values for known ll vm | /// A set of enums which specify the assigned numeric values for known ll vm | |||
/// calling conventions. | /// calling conventions. | |||
/// @brief LLVM Calling Convention Representation | /// @brief LLVM Calling Convention Representation | |||
skipping to change at line 50 | skipping to change at line 50 | |||
// Cold - This calling convention attempts to make code in the caller a s | // Cold - This calling convention attempts to make code in the caller a s | |||
// efficient as possible under the assumption that the call is not comm only | // efficient as possible under the assumption that the call is not comm only | |||
// executed. As such, these calls often preserve all registers so that the | // executed. As such, these calls often preserve all registers so that the | |||
// call does not break any live ranges in the caller side. | // call does not break any live ranges in the caller side. | |||
Cold = 9, | Cold = 9, | |||
// GHC - Calling convention used by the Glasgow Haskell Compiler (GHC). | // GHC - Calling convention used by the Glasgow Haskell Compiler (GHC). | |||
GHC = 10, | GHC = 10, | |||
// HiPE - Calling convention used by the High-Performance Erlang Compil | ||||
er | ||||
// (HiPE). | ||||
HiPE = 11, | ||||
// Target - This is the start of the target-specific calling convention s, | // Target - This is the start of the target-specific calling convention s, | |||
// e.g. fastcall and thiscall on X86. | // e.g. fastcall and thiscall on X86. | |||
FirstTargetCC = 64, | FirstTargetCC = 64, | |||
/// X86_StdCall - stdcall is the calling conventions mostly used by the | /// X86_StdCall - stdcall is the calling conventions mostly used by the | |||
/// Win32 API. It is basically the same as the C convention with the | /// Win32 API. It is basically the same as the C convention with the | |||
/// difference in that the callee is responsible for popping the argume nts | /// difference in that the callee is responsible for popping the argume nts | |||
/// from the stack. | /// from the stack. | |||
X86_StdCall = 64, | X86_StdCall = 64, | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 7 lines changed or added | |||
CallingConvLower.h | CallingConvLower.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file declares the CCState and CCValAssign classes, used for lowerin g | // This file declares the CCState and CCValAssign classes, used for lowerin g | |||
// and implementing calling conventions. | // and implementing calling conventions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H | #ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H | |||
#define LLVM_CODEGEN_CALLINGCONVLOWER_H | #define LLVM_CODEGEN_CALLINGCONVLOWER_H | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/CodeGen/MachineFunction.h" | ||||
#include "llvm/CodeGen/MachineFrameInfo.h" | #include "llvm/CodeGen/MachineFrameInfo.h" | |||
#include "llvm/CodeGen/MachineFunction.h" | ||||
#include "llvm/CodeGen/ValueTypes.h" | #include "llvm/CodeGen/ValueTypes.h" | |||
#include "llvm/IR/CallingConv.h" | ||||
#include "llvm/Target/TargetCallingConv.h" | #include "llvm/Target/TargetCallingConv.h" | |||
#include "llvm/CallingConv.h" | ||||
namespace llvm { | namespace llvm { | |||
class TargetRegisterInfo; | class TargetRegisterInfo; | |||
class TargetMachine; | class TargetMachine; | |||
class CCState; | class CCState; | |||
/// CCValAssign - Represent assignment of one arg/retval to a location. | /// CCValAssign - Represent assignment of one arg/retval to a location. | |||
class CCValAssign { | class CCValAssign { | |||
public: | public: | |||
enum LocInfo { | enum LocInfo { | |||
skipping to change at line 53 | skipping to change at line 53 | |||
// TODO: a subset of the value is in the location. | // TODO: a subset of the value is in the location. | |||
}; | }; | |||
private: | private: | |||
/// ValNo - This is the value number begin assigned (e.g. an argument num ber). | /// ValNo - This is the value number begin assigned (e.g. an argument num ber). | |||
unsigned ValNo; | unsigned ValNo; | |||
/// Loc is either a stack offset or a register number. | /// Loc is either a stack offset or a register number. | |||
unsigned Loc; | unsigned Loc; | |||
/// isMem - True if this is a memory loc, false if it is a register loc. | /// isMem - True if this is a memory loc, false if it is a register loc. | |||
bool isMem : 1; | unsigned isMem : 1; | |||
/// isCustom - True if this arg/retval requires special handling. | /// isCustom - True if this arg/retval requires special handling. | |||
bool isCustom : 1; | unsigned isCustom : 1; | |||
/// Information about how the value is assigned. | /// Information about how the value is assigned. | |||
LocInfo HTP : 6; | LocInfo HTP : 6; | |||
/// ValVT - The type of the value being assigned. | /// ValVT - The type of the value being assigned. | |||
MVT ValVT; | MVT ValVT; | |||
/// LocVT - The type of the location being assigned to. | /// LocVT - The type of the location being assigned to. | |||
MVT LocVT; | MVT LocVT; | |||
public: | public: | |||
skipping to change at line 166 | skipping to change at line 166 | |||
CallingConv::ID CallingConv; | CallingConv::ID CallingConv; | |||
bool IsVarArg; | bool IsVarArg; | |||
MachineFunction &MF; | MachineFunction &MF; | |||
const TargetMachine &TM; | const TargetMachine &TM; | |||
const TargetRegisterInfo &TRI; | const TargetRegisterInfo &TRI; | |||
SmallVector<CCValAssign, 16> &Locs; | SmallVector<CCValAssign, 16> &Locs; | |||
LLVMContext &Context; | LLVMContext &Context; | |||
unsigned StackOffset; | unsigned StackOffset; | |||
SmallVector<uint32_t, 16> UsedRegs; | SmallVector<uint32_t, 16> UsedRegs; | |||
unsigned FirstByValReg; | ||||
bool FirstByValRegValid; | // ByValInfo and SmallVector<ByValInfo, 4> ByValRegs: | |||
// | ||||
// Vector of ByValInfo instances (ByValRegs) is introduced for byval regi | ||||
sters | ||||
// tracking. | ||||
// Or, in another words it tracks byval parameters that are stored in | ||||
// general purpose registers. | ||||
// | ||||
// For 4 byte stack alignment, | ||||
// instance index means byval parameter number in formal | ||||
// arguments set. Assume, we have some "struct_type" with size = 4 bytes, | ||||
// then, for function "foo": | ||||
// | ||||
// i32 foo(i32 %p, %struct_type* %r, i32 %s, %struct_type* %t) | ||||
// | ||||
// ByValRegs[0] describes how "%r" is stored (Begin == r1, End == r2) | ||||
// ByValRegs[1] describes how "%t" is stored (Begin == r3, End == r4). | ||||
// | ||||
// In case of 8 bytes stack alignment, | ||||
// ByValRegs may also contain information about wasted registers. | ||||
// In function shown above, r3 would be wasted according to AAPCS rules. | ||||
// And in that case ByValRegs[1].Waste would be "true". | ||||
// ByValRegs vector size still would be 2, | ||||
// while "%t" goes to the stack: it wouldn't be described in ByValRegs. | ||||
// | ||||
// Supposed use-case for this collection: | ||||
// 1. Initially ByValRegs is empty, InRegsParamsProceed is 0. | ||||
// 2. HandleByVal fillups ByValRegs. | ||||
// 3. Argument analysis (LowerFormatArguments, for example). After | ||||
// some byval argument was analyzed, InRegsParamsProceed is increased. | ||||
struct ByValInfo { | ||||
ByValInfo(unsigned B, unsigned E, bool IsWaste = false) : | ||||
Begin(B), End(E), Waste(IsWaste) {} | ||||
// First register allocated for current parameter. | ||||
unsigned Begin; | ||||
// First after last register allocated for current parameter. | ||||
unsigned End; | ||||
// Means that current range of registers doesn't belong to any | ||||
// parameters. It was wasted due to stack alignment rules. | ||||
// For more information see: | ||||
// AAPCS, 5.5 Parameter Passing, Stage C, C.3. | ||||
bool Waste; | ||||
}; | ||||
SmallVector<ByValInfo, 4 > ByValRegs; | ||||
// InRegsParamsProceed - shows how many instances of ByValRegs was procee | ||||
d | ||||
// during argument analysis. | ||||
unsigned InRegsParamsProceed; | ||||
protected: | protected: | |||
ParmContext CallOrPrologue; | ParmContext CallOrPrologue; | |||
public: | public: | |||
CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, | CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, | |||
const TargetMachine &TM, SmallVector<CCValAssign, 16> &locs, | const TargetMachine &TM, SmallVector<CCValAssign, 16> &locs, | |||
LLVMContext &C); | LLVMContext &C); | |||
void addLoc(const CCValAssign &V) { | void addLoc(const CCValAssign &V) { | |||
skipping to change at line 309 | skipping to change at line 357 | |||
return AllocateStack(Size, Align); | return AllocateStack(Size, Align); | |||
} | } | |||
// HandleByVal - Allocate a stack slot large enough to pass an argument b y | // HandleByVal - Allocate a stack slot large enough to pass an argument b y | |||
// value. The size and alignment information of the argument is encoded i n its | // value. The size and alignment information of the argument is encoded i n its | |||
// parameter attribute. | // parameter attribute. | |||
void HandleByVal(unsigned ValNo, MVT ValVT, | void HandleByVal(unsigned ValNo, MVT ValVT, | |||
MVT LocVT, CCValAssign::LocInfo LocInfo, | MVT LocVT, CCValAssign::LocInfo LocInfo, | |||
int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags); | int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags); | |||
// First GPR that carries part of a byval aggregate that's split | // Returns count of byval arguments that are to be stored (even partly) | |||
// between registers and memory. | // in registers. | |||
unsigned getFirstByValReg() const { return FirstByValRegValid ? FirstByVa | unsigned getInRegsParamsCount() const { return ByValRegs.size(); } | |||
lReg : 0; } | ||||
void setFirstByValReg(unsigned r) { FirstByValReg = r; FirstByValRegValid | // Returns count of byval in-regs arguments proceed. | |||
= true; } | unsigned getInRegsParamsProceed() const { return InRegsParamsProceed; } | |||
void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false | ||||
; } | // Get information about N-th byval parameter that is stored in registers | |||
bool isFirstByValRegValid() const { return FirstByValRegValid; } | . | |||
// Here "ByValParamIndex" is N. | ||||
void getInRegsParamInfo(unsigned InRegsParamRecordIndex, | ||||
unsigned& BeginReg, unsigned& EndReg) const { | ||||
assert(InRegsParamRecordIndex < ByValRegs.size() && | ||||
"Wrong ByVal parameter index"); | ||||
const ByValInfo& info = ByValRegs[InRegsParamRecordIndex]; | ||||
BeginReg = info.Begin; | ||||
EndReg = info.End; | ||||
} | ||||
// Add information about parameter that is kept in registers. | ||||
void addInRegsParamInfo(unsigned RegBegin, unsigned RegEnd) { | ||||
ByValRegs.push_back(ByValInfo(RegBegin, RegEnd)); | ||||
} | ||||
// Goes either to next byval parameter (excluding "waste" record), or | ||||
// to the end of collection. | ||||
// Returns false, if end is reached. | ||||
bool nextInRegsParam() { | ||||
unsigned e = ByValRegs.size(); | ||||
if (InRegsParamsProceed < e) | ||||
++InRegsParamsProceed; | ||||
return InRegsParamsProceed < e; | ||||
} | ||||
// Clear byval registers tracking info. | ||||
void clearByValRegsInfo() { | ||||
InRegsParamsProceed = 0; | ||||
ByValRegs.clear(); | ||||
} | ||||
ParmContext getCallOrPrologue() const { return CallOrPrologue; } | ParmContext getCallOrPrologue() const { return CallOrPrologue; } | |||
private: | private: | |||
/// MarkAllocated - Mark a register and all of its aliases as allocated. | /// MarkAllocated - Mark a register and all of its aliases as allocated. | |||
void MarkAllocated(unsigned Reg); | void MarkAllocated(unsigned Reg); | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
End of changes. 8 change blocks. | ||||
15 lines changed or deleted | 96 lines changed or added | |||
CaptureTracking.h | CaptureTracking.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains routines that help determine which pointers are captu red. | // This file contains routines that help determine which pointers are captu red. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_CAPTURETRACKING_H | #ifndef LLVM_ANALYSIS_CAPTURETRACKING_H | |||
#define LLVM_ANALYSIS_CAPTURETRACKING_H | #define LLVM_ANALYSIS_CAPTURETRACKING_H | |||
#include "llvm/Constants.h" | ||||
#include "llvm/Instructions.h" | ||||
#include "llvm/Analysis/AliasAnalysis.h" | ||||
#include "llvm/Support/CallSite.h" | ||||
namespace llvm { | namespace llvm { | |||
class Value; | ||||
class Use; | ||||
/// PointerMayBeCaptured - Return true if this pointer value may be captu red | /// PointerMayBeCaptured - Return true if this pointer value may be captu red | |||
/// by the enclosing function (which is required to exist). This routine can | /// by the enclosing function (which is required to exist). This routine can | |||
/// be expensive, so consider caching the results. The boolean ReturnCap tures | /// be expensive, so consider caching the results. The boolean ReturnCap tures | |||
/// specifies whether returning the value (or part of it) from the functi on | /// specifies whether returning the value (or part of it) from the functi on | |||
/// counts as capturing it or not. The boolean StoreCaptures specified | /// counts as capturing it or not. The boolean StoreCaptures specified | |||
/// whether storing the value (or part of it) into memory anywhere | /// whether storing the value (or part of it) into memory anywhere | |||
/// automatically counts as capturing it or not. | /// automatically counts as capturing it or not. | |||
bool PointerMayBeCaptured(const Value *V, | bool PointerMayBeCaptured(const Value *V, | |||
bool ReturnCaptures, | bool ReturnCaptures, | |||
bool StoreCaptures); | bool StoreCaptures); | |||
End of changes. 2 change blocks. | ||||
5 lines changed or deleted | 4 lines changed or added | |||
Casting.h | Casting.h | |||
---|---|---|---|---|
skipping to change at line 39 | skipping to change at line 39 | |||
// template selection process... the default implementation is a noop. | // template selection process... the default implementation is a noop. | |||
// | // | |||
template<typename From> struct simplify_type { | template<typename From> struct simplify_type { | |||
typedef From SimpleType; // The real type this represents... | typedef From SimpleType; // The real type this represents... | |||
// An accessor to get the real value... | // An accessor to get the real value... | |||
static SimpleType &getSimplifiedValue(From &Val) { return Val; } | static SimpleType &getSimplifiedValue(From &Val) { return Val; } | |||
}; | }; | |||
template<typename From> struct simplify_type<const From> { | template<typename From> struct simplify_type<const From> { | |||
typedef const From SimpleType; | typedef typename simplify_type<From>::SimpleType NonConstSimpleType; | |||
static SimpleType &getSimplifiedValue(const From &Val) { | typedef typename add_const_past_pointer<NonConstSimpleType>::type | |||
return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val)) | SimpleType; | |||
; | typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type | |||
RetType; | ||||
static RetType getSimplifiedValue(const From& Val) { | ||||
return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); | ||||
} | } | |||
}; | }; | |||
// The core of the implementation of isa<X> is here; To and From should be | // The core of the implementation of isa<X> is here; To and From should be | |||
// the names of classes. This template can be specialized to customize the | // the names of classes. This template can be specialized to customize the | |||
// implementation of isa<> without rewriting it from scratch. | // implementation of isa<> without rewriting it from scratch. | |||
template <typename To, typename From, typename Enabler = void> | template <typename To, typename From, typename Enabler = void> | |||
struct isa_impl { | struct isa_impl { | |||
static inline bool doit(const From &Val) { | static inline bool doit(const From &Val) { | |||
return To::classof(&Val); | return To::classof(&Val); | |||
} | } | |||
}; | }; | |||
/// \brief Always allow upcasts, and perform no dynamic check for them. | /// \brief Always allow upcasts, and perform no dynamic check for them. | |||
template <typename To, typename From> | template <typename To, typename From> | |||
struct isa_impl<To, From, | struct isa_impl<To, From, | |||
typename llvm::enable_if_c< | typename enable_if< | |||
llvm::is_base_of<To, From>::value | llvm::is_base_of<To, From> | |||
>::type | >::type | |||
> { | > { | |||
static inline bool doit(const From &) { return true; } | static inline bool doit(const From &) { return true; } | |||
}; | }; | |||
template <typename To, typename From> struct isa_impl_cl { | template <typename To, typename From> struct isa_impl_cl { | |||
static inline bool doit(const From &Val) { | static inline bool doit(const From &Val) { | |||
return isa_impl<To, From>::doit(Val); | return isa_impl<To, From>::doit(Val); | |||
} | } | |||
}; | }; | |||
skipping to change at line 84 | skipping to change at line 88 | |||
} | } | |||
}; | }; | |||
template <typename To, typename From> struct isa_impl_cl<To, From*> { | template <typename To, typename From> struct isa_impl_cl<To, From*> { | |||
static inline bool doit(const From *Val) { | static inline bool doit(const From *Val) { | |||
assert(Val && "isa<> used on a null pointer"); | assert(Val && "isa<> used on a null pointer"); | |||
return isa_impl<To, From>::doit(*Val); | return isa_impl<To, From>::doit(*Val); | |||
} | } | |||
}; | }; | |||
template <typename To, typename From> struct isa_impl_cl<To, From*const> { | ||||
static inline bool doit(const From *Val) { | ||||
assert(Val && "isa<> used on a null pointer"); | ||||
return isa_impl<To, From>::doit(*Val); | ||||
} | ||||
}; | ||||
template <typename To, typename From> struct isa_impl_cl<To, const From*> { | template <typename To, typename From> struct isa_impl_cl<To, const From*> { | |||
static inline bool doit(const From *Val) { | static inline bool doit(const From *Val) { | |||
assert(Val && "isa<> used on a null pointer"); | assert(Val && "isa<> used on a null pointer"); | |||
return isa_impl<To, From>::doit(*Val); | return isa_impl<To, From>::doit(*Val); | |||
} | } | |||
}; | }; | |||
template <typename To, typename From> struct isa_impl_cl<To, const From*con st> { | template <typename To, typename From> struct isa_impl_cl<To, const From*con st> { | |||
static inline bool doit(const From *Val) { | static inline bool doit(const From *Val) { | |||
assert(Val && "isa<> used on a null pointer"); | assert(Val && "isa<> used on a null pointer"); | |||
skipping to change at line 105 | skipping to change at line 116 | |||
} | } | |||
}; | }; | |||
template<typename To, typename From, typename SimpleFrom> | template<typename To, typename From, typename SimpleFrom> | |||
struct isa_impl_wrap { | struct isa_impl_wrap { | |||
// When From != SimplifiedType, we can simplify the type some more by usi ng | // When From != SimplifiedType, we can simplify the type some more by usi ng | |||
// the simplify_type template. | // the simplify_type template. | |||
static bool doit(const From &Val) { | static bool doit(const From &Val) { | |||
return isa_impl_wrap<To, SimpleFrom, | return isa_impl_wrap<To, SimpleFrom, | |||
typename simplify_type<SimpleFrom>::SimpleType>::doit( | typename simplify_type<SimpleFrom>::SimpleType>::doit( | |||
simplify_type<From>::getSimplifiedValue(Val)); | simplify_type<const From>::getSimplifiedValue(Val )); | |||
} | } | |||
}; | }; | |||
template<typename To, typename FromTy> | template<typename To, typename FromTy> | |||
struct isa_impl_wrap<To, FromTy, FromTy> { | struct isa_impl_wrap<To, FromTy, FromTy> { | |||
// When From == SimpleType, we are as simple as we are going to get. | // When From == SimpleType, we are as simple as we are going to get. | |||
static bool doit(const FromTy &Val) { | static bool doit(const FromTy &Val) { | |||
return isa_impl_cl<To,FromTy>::doit(Val); | return isa_impl_cl<To,FromTy>::doit(Val); | |||
} | } | |||
}; | }; | |||
// isa<X> - Return true if the parameter to the template is an instance of the | // isa<X> - Return true if the parameter to the template is an instance of the | |||
// template type argument. Used like this: | // template type argument. Used like this: | |||
// | // | |||
// if (isa<Type>(myVal)) { ... } | // if (isa<Type>(myVal)) { ... } | |||
// | // | |||
template <class X, class Y> | template <class X, class Y> | |||
inline bool isa(const Y &Val) { | inline bool isa(const Y &Val) { | |||
return isa_impl_wrap<X, Y, typename simplify_type<Y>::SimpleType>::doit(V | return isa_impl_wrap<X, const Y, | |||
al); | typename simplify_type<const Y>::SimpleType>::doit(V | |||
al); | ||||
} | } | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// cast<x> Support Templates | // cast<x> Support Templates | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
template<class To, class From> struct cast_retty; | template<class To, class From> struct cast_retty; | |||
// Calculate what type the 'cast' function should return, based on a reques ted | // Calculate what type the 'cast' function should return, based on a reques ted | |||
// type of To and a source type of From. | // type of To and a source type of From. | |||
skipping to change at line 179 | skipping to change at line 191 | |||
struct cast_retty { | struct cast_retty { | |||
typedef typename cast_retty_wrap<To, From, | typedef typename cast_retty_wrap<To, From, | |||
typename simplify_type<From>::SimpleType>::ret_type ret_ type; | typename simplify_type<From>::SimpleType>::ret_type ret_ type; | |||
}; | }; | |||
// Ensure the non-simple values are converted using the simplify_type templ ate | // Ensure the non-simple values are converted using the simplify_type templ ate | |||
// that may be specialized by smart pointers... | // that may be specialized by smart pointers... | |||
// | // | |||
template<class To, class From, class SimpleFrom> struct cast_convert_val { | template<class To, class From, class SimpleFrom> struct cast_convert_val { | |||
// This is not a simple type, use the template to simplify it... | // This is not a simple type, use the template to simplify it... | |||
static typename cast_retty<To, From>::ret_type doit(const From &Val) { | static typename cast_retty<To, From>::ret_type doit(From &Val) { | |||
return cast_convert_val<To, SimpleFrom, | return cast_convert_val<To, SimpleFrom, | |||
typename simplify_type<SimpleFrom>::SimpleType>::doit( | typename simplify_type<SimpleFrom>::SimpleType>::doit( | |||
simplify_type<From>::getSimplifiedValue(Val)); | simplify_type<From>::getSimplifiedValue(Val)); | |||
} | } | |||
}; | }; | |||
template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { | template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { | |||
// This _is_ a simple type, just cast it. | // This _is_ a simple type, just cast it. | |||
static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { | static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { | |||
typename cast_retty<To, FromTy>::ret_type Res2 | typename cast_retty<To, FromTy>::ret_type Res2 | |||
skipping to change at line 203 | skipping to change at line 215 | |||
}; | }; | |||
// cast<X> - Return the argument parameter cast to the specified type. Thi s | // cast<X> - Return the argument parameter cast to the specified type. Thi s | |||
// casting operator asserts that the type is correct, so it does not return null | // casting operator asserts that the type is correct, so it does not return null | |||
// on failure. It does not allow a null argument (use cast_or_null for tha t). | // on failure. It does not allow a null argument (use cast_or_null for tha t). | |||
// It is typically used like this: | // It is typically used like this: | |||
// | // | |||
// cast<Instruction>(myVal)->getParent() | // cast<Instruction>(myVal)->getParent() | |||
// | // | |||
template <class X, class Y> | template <class X, class Y> | |||
inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) { | inline typename cast_retty<X, const Y>::ret_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); | ||||
} | ||||
template <class X, class Y> | ||||
inline typename cast_retty<X, Y>::ret_type cast(Y &Val) { | ||||
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); | |||
return cast_convert_val<X, Y, | return cast_convert_val<X, Y, | |||
typename simplify_type<Y>::SimpleType>::doit(Val) ; | typename simplify_type<Y>::SimpleType>::doit(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) { | ||||
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); | ||||
return cast_convert_val<X, Y*, | ||||
typename simplify_type<Y*>::SimpleType>::doit(Val | ||||
); | ||||
} | ||||
// cast_or_null<X> - Functionally identical to cast, except that a null val ue is | // cast_or_null<X> - Functionally identical to cast, except that a null val ue is | |||
// accepted. | // accepted. | |||
// | // | |||
template <class X, class Y> | template <class X, class Y> | |||
inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) { | inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) { | |||
if (Val == 0) return 0; | if (Val == 0) return 0; | |||
assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ); | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ); | |||
return cast<X>(Val); | return cast<X>(Val); | |||
} | } | |||
// dyn_cast<X> - Return the argument parameter cast to the specified type. This | // dyn_cast<X> - Return the argument parameter cast to the specified type. This | |||
// casting operator returns null if the argument is of the wrong type, so i t can | // casting operator returns null if the argument is of the wrong type, so i t can | |||
// be used to test for a type as well as cast if successful. This should b e | // be used to test for a type as well as cast if successful. This should b e | |||
// used in the context of an if statement like this: | // used in the context of an if statement like this: | |||
// | // | |||
// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } | // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } | |||
// | // | |||
template <class X, class Y> | template <class X, class Y> | |||
inline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) { | inline typename cast_retty<X, const Y>::ret_type dyn_cast(const Y &Val) { | |||
return isa<X>(Val) ? cast<X, Y>(Val) : 0; | return isa<X>(Val) ? cast<X>(Val) : 0; | |||
} | ||||
template <class X, class Y> | ||||
inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { | ||||
return isa<X>(Val) ? cast<X>(Val) : 0; | ||||
} | ||||
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) { | ||||
return isa<X>(Val) ? cast<X>(Val) : 0; | ||||
} | } | |||
// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null | // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null | |||
// value is accepted. | // value is accepted. | |||
// | // | |||
template <class X, class Y> | template <class X, class Y> | |||
inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) { | inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) { | |||
return (Val && isa<X>(Val)) ? cast<X>(Val) : 0; | return (Val && isa<X>(Val)) ? cast<X>(Val) : 0; | |||
} | } | |||
End of changes. 9 change blocks. | ||||
13 lines changed or deleted | 56 lines changed or added | |||
Cloning.h | Cloning.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// code for various purposes. This varies from copying whole modules into new | // code for various purposes. This varies from copying whole modules into new | |||
// modules, to cloning functions with different arguments, to inlining | // modules, to cloning functions with different arguments, to inlining | |||
// functions, to copying basic blocks to support loop unrolling or superblo ck | // functions, to copying basic blocks to support loop unrolling or superblo ck | |||
// formation, etc. | // formation, etc. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_UTILS_CLONING_H | #ifndef LLVM_TRANSFORMS_UTILS_CLONING_H | |||
#define LLVM_TRANSFORMS_UTILS_CLONING_H | #define LLVM_TRANSFORMS_UTILS_CLONING_H | |||
#include "llvm/ADT/ValueMap.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | |||
#include "llvm/ADT/ValueMap.h" | ||||
#include "llvm/Support/ValueHandle.h" | #include "llvm/Support/ValueHandle.h" | |||
#include "llvm/Transforms/Utils/ValueMapper.h" | #include "llvm/Transforms/Utils/ValueMapper.h" | |||
namespace llvm { | namespace llvm { | |||
class Module; | class Module; | |||
class Function; | class Function; | |||
class Instruction; | class Instruction; | |||
class Pass; | class Pass; | |||
class LPPassManager; | class LPPassManager; | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
CmpInstAnalysis.h | CmpInstAnalysis.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file holds routines to help analyse compare instructions | // This file holds routines to help analyse compare instructions | |||
// and fold them into constants or other compare instructions | // and fold them into constants or other compare instructions | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H | #ifndef LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H | |||
#define LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H | #define LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H | |||
#include "llvm/InstrTypes.h" | #include "llvm/IR/InstrTypes.h" | |||
namespace llvm { | namespace llvm { | |||
class ICmpInst; | class ICmpInst; | |||
class Value; | class Value; | |||
/// getICmpCode - Encode a icmp predicate into a three bit mask. These b its | /// getICmpCode - Encode a icmp predicate into a three bit mask. These b its | |||
/// are carefully arranged to allow folding of expressions such as: | /// are carefully arranged to allow folding of expressions such as: | |||
/// | /// | |||
/// (A < B) | (A > B) --> (A != B) | /// (A < B) | (A > B) --> (A != B) | |||
/// | /// | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
CodeGen.h | CodeGen.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file define some types which define code generation concepts. For | // This file define some types which define code generation concepts. For | |||
// example, relocation model. | // example, relocation model. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_CODEGEN_H | #ifndef LLVM_SUPPORT_CODEGEN_H | |||
#define LLVM_SUPPORT_CODEGEN_H | #define LLVM_SUPPORT_CODEGEN_H | |||
#include "llvm-c/TargetMachine.h" | ||||
#include "llvm/Support/ErrorHandling.h" | ||||
namespace llvm { | namespace llvm { | |||
// Relocation model types. | // Relocation model types. | |||
namespace Reloc { | namespace Reloc { | |||
enum Model { Default, Static, PIC_, DynamicNoPIC }; | enum Model { Default, Static, PIC_, DynamicNoPIC }; | |||
} | } | |||
// Code model types. | // Code model types. | |||
namespace CodeModel { | namespace CodeModel { | |||
enum Model { Default, JITDefault, Small, Kernel, Medium, Large }; | enum Model { Default, JITDefault, Small, Kernel, Medium, Large }; | |||
skipping to change at line 50 | skipping to change at line 53 | |||
// Code generation optimization level. | // Code generation optimization level. | |||
namespace CodeGenOpt { | namespace CodeGenOpt { | |||
enum Level { | enum Level { | |||
None, // -O0 | None, // -O0 | |||
Less, // -O1 | Less, // -O1 | |||
Default, // -O2, -Os | Default, // -O2, -Os | |||
Aggressive // -O3 | Aggressive // -O3 | |||
}; | }; | |||
} | } | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
inline CodeModel::Model unwrap(LLVMCodeModel Model) { | ||||
switch (Model) { | ||||
case LLVMCodeModelDefault: | ||||
return CodeModel::Default; | ||||
case LLVMCodeModelJITDefault: | ||||
return CodeModel::JITDefault; | ||||
case LLVMCodeModelSmall: | ||||
return CodeModel::Small; | ||||
case LLVMCodeModelKernel: | ||||
return CodeModel::Kernel; | ||||
case LLVMCodeModelMedium: | ||||
return CodeModel::Medium; | ||||
case LLVMCodeModelLarge: | ||||
return CodeModel::Large; | ||||
} | ||||
return CodeModel::Default; | ||||
} | ||||
inline LLVMCodeModel wrap(CodeModel::Model Model) { | ||||
switch (Model) { | ||||
case CodeModel::Default: | ||||
return LLVMCodeModelDefault; | ||||
case CodeModel::JITDefault: | ||||
return LLVMCodeModelJITDefault; | ||||
case CodeModel::Small: | ||||
return LLVMCodeModelSmall; | ||||
case CodeModel::Kernel: | ||||
return LLVMCodeModelKernel; | ||||
case CodeModel::Medium: | ||||
return LLVMCodeModelMedium; | ||||
case CodeModel::Large: | ||||
return LLVMCodeModelLarge; | ||||
} | ||||
llvm_unreachable("Bad CodeModel!"); | ||||
} | ||||
} // end llvm namespace | } // end llvm namespace | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 39 lines changed or added | |||
CodeMetrics.h | CodeMetrics.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_CODEMETRICS_H | #ifndef LLVM_ANALYSIS_CODEMETRICS_H | |||
#define LLVM_ANALYSIS_CODEMETRICS_H | #define LLVM_ANALYSIS_CODEMETRICS_H | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/Support/CallSite.h" | #include "llvm/Support/CallSite.h" | |||
namespace llvm { | namespace llvm { | |||
class BasicBlock; | class BasicBlock; | |||
class Function; | class Function; | |||
class Instruction; | class Instruction; | |||
class DataLayout; | class DataLayout; | |||
class Value; | class TargetTransformInfo; | |||
class Value; | ||||
/// \brief Check whether a call will lower to something small. | ||||
/// | ||||
/// This tests checks whether this callsite will lower to something | ||||
/// significantly cheaper than a traditional call, often a single | ||||
/// instruction. Note that if isInstructionFree(CS.getInstruction()) would | ||||
/// return true, so will this function. | ||||
bool callIsSmall(ImmutableCallSite CS); | ||||
/// \brief Utility to calculate the size and a few similar metrics for a se | ||||
t | ||||
/// of basic blocks. | ||||
struct CodeMetrics { | ||||
/// \brief True if this function contains a call to setjmp or other funct | ||||
ions | ||||
/// with attribute "returns twice" without having the attribute itself. | ||||
bool exposesReturnsTwice; | ||||
/// \brief Check whether an instruction is likely to be "free" when lower | /// \brief True if this function calls itself. | |||
ed. | bool isRecursive; | |||
bool isInstructionFree(const Instruction *I, const DataLayout *TD = 0); | ||||
/// \brief Check whether a call will lower to something small. | /// \brief True if this function cannot be duplicated. | |||
/// | /// | |||
/// This tests checks whether this callsite will lower to something | /// True if this function contains one or more indirect branches, or it c | |||
/// significantly cheaper than a traditional call, often a single | ontains | |||
/// instruction. Note that if isInstructionFree(CS.getInstruction()) woul | /// one or more 'noduplicate' instructions. | |||
d | bool notDuplicatable; | |||
/// return true, so will this function. | ||||
bool callIsSmall(ImmutableCallSite CS); | /// \brief True if this function calls alloca (in the C sense). | |||
bool usesDynamicAlloca; | ||||
/// \brief Utility to calculate the size and a few similar metrics for a | ||||
set | /// \brief Number of instructions in the analyzed blocks. | |||
/// of basic blocks. | unsigned NumInsts; | |||
struct CodeMetrics { | ||||
/// \brief True if this function contains a call to setjmp or other fun | /// \brief Number of analyzed blocks. | |||
ctions | unsigned NumBlocks; | |||
/// with attribute "returns twice" without having the attribute itself. | ||||
bool exposesReturnsTwice; | /// \brief Keeps track of basic block code size estimates. | |||
DenseMap<const BasicBlock *, unsigned> NumBBInsts; | ||||
/// \brief True if this function calls itself. | ||||
bool isRecursive; | /// \brief Keep track of the number of calls to 'big' functions. | |||
unsigned NumCalls; | ||||
/// \brief True if this function contains one or more indirect branches | ||||
. | /// \brief The number of calls to internal functions with a single caller | |||
bool containsIndirectBr; | . | |||
/// | ||||
/// \brief True if this function calls alloca (in the C sense). | /// These are likely targets for future inlining, likely exposed by | |||
bool usesDynamicAlloca; | /// interleaved devirtualization. | |||
unsigned NumInlineCandidates; | ||||
/// \brief Number of instructions in the analyzed blocks. | ||||
unsigned NumInsts; | /// \brief How many instructions produce vector values. | |||
/// | ||||
/// \brief Number of analyzed blocks. | /// The inliner is more aggressive with inlining vector kernels. | |||
unsigned NumBlocks; | unsigned NumVectorInsts; | |||
/// \brief Keeps track of basic block code size estimates. | /// \brief How many 'ret' instructions the blocks contain. | |||
DenseMap<const BasicBlock *, unsigned> NumBBInsts; | unsigned NumRets; | |||
/// \brief Keep track of the number of calls to 'big' functions. | CodeMetrics() | |||
unsigned NumCalls; | : exposesReturnsTwice(false), isRecursive(false), notDuplicatable(fal | |||
se), | ||||
/// \brief The number of calls to internal functions with a single call | usesDynamicAlloca(false), NumInsts(0), NumBlocks(0), NumCalls(0), | |||
er. | NumInlineCandidates(0), NumVectorInsts(0), NumRets(0) {} | |||
/// | ||||
/// These are likely targets for future inlining, likely exposed by | /// \brief Add information about a block to the current state. | |||
/// interleaved devirtualization. | void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &T | |||
unsigned NumInlineCandidates; | TI); | |||
}; | ||||
/// \brief How many instructions produce vector values. | ||||
/// | ||||
/// The inliner is more aggressive with inlining vector kernels. | ||||
unsigned NumVectorInsts; | ||||
/// \brief How many 'ret' instructions the blocks contain. | ||||
unsigned NumRets; | ||||
CodeMetrics() : exposesReturnsTwice(false), isRecursive(false), | ||||
containsIndirectBr(false), usesDynamicAlloca(false), | ||||
NumInsts(0), NumBlocks(0), NumCalls(0), | ||||
NumInlineCandidates(0), NumVectorInsts(0), | ||||
NumRets(0) {} | ||||
/// \brief Add information about a block to the current state. | ||||
void analyzeBasicBlock(const BasicBlock *BB, const DataLayout *TD = 0); | ||||
/// \brief Add information about a function to the current state. | ||||
void analyzeFunction(Function *F, const DataLayout *TD = 0); | ||||
}; | ||||
} | } | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
74 lines changed or deleted | 72 lines changed or added | |||
CommandFlags.h | CommandFlags.h | |||
---|---|---|---|---|
//===-- CommandFlags.h - Register Coalescing Interface ----------*- C++ -*- ===// | //===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains codegen-specific flags that are shared between differ ent | // This file contains codegen-specific flags that are shared between differ ent | |||
// command line tools. The tools "llc" and "opt" both use this file to prev ent | // command line tools. The tools "llc" and "opt" both use this file to prev ent | |||
// flag duplication. | // flag duplication. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_COMMAND_LINE_FLAGS_H | #ifndef LLVM_CODEGEN_COMMANDFLAGS_H | |||
#define LLVM_CODEGEN_COMMAND_LINE_FLAGS_H | #define LLVM_CODEGEN_COMMANDFLAGS_H | |||
#include "llvm/Support/CommandLine.h" | ||||
#include "llvm/Support/CodeGen.h" | #include "llvm/Support/CodeGen.h" | |||
#include "llvm/Support/CommandLine.h" | ||||
#include "llvm/Target/TargetMachine.h" | #include "llvm/Target/TargetMachine.h" | |||
#include <string> | #include <string> | |||
using namespace llvm; | using namespace llvm; | |||
cl::opt<std::string> | cl::opt<std::string> | |||
MArch("march", cl::desc("Architecture to generate code for (see --version)" )); | MArch("march", cl::desc("Architecture to generate code for (see --version)" )); | |||
cl::opt<std::string> | cl::opt<std::string> | |||
MCPU("mcpu", | MCPU("mcpu", | |||
cl::desc("Target a specific cpu type (-mcpu=help for details)"), | cl::desc("Target a specific cpu type (-mcpu=help for details)"), | |||
cl::value_desc("cpu-name"), | cl::value_desc("cpu-name"), | |||
End of changes. 5 change blocks. | ||||
5 lines changed or deleted | 4 lines changed or added | |||
CommandLine.h | CommandLine.h | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// | // | |||
// Note that rather than trying to figure out what this code does, you shou ld | // Note that rather than trying to figure out what this code does, you shou ld | |||
// read the library documentation located in docs/CommandLine.html or looks at | // read the library documentation located in docs/CommandLine.html or looks at | |||
// the many example usages in tools/*/*.cpp | // the many example usages in tools/*/*.cpp | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_COMMANDLINE_H | #ifndef LLVM_SUPPORT_COMMANDLINE_H | |||
#define LLVM_SUPPORT_COMMANDLINE_H | #define LLVM_SUPPORT_COMMANDLINE_H | |||
#include "llvm/Support/type_traits.h" | ||||
#include "llvm/Support/Compiler.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | |||
#include "llvm/ADT/StringMap.h" | ||||
#include "llvm/Support/Compiler.h" | ||||
#include "llvm/Support/type_traits.h" | ||||
#include <cassert> | #include <cassert> | |||
#include <climits> | #include <climits> | |||
#include <cstdarg> | #include <cstdarg> | |||
#include <utility> | #include <utility> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
/// cl Namespace - This namespace contains all of the command line option | /// cl Namespace - This namespace contains all of the command line option | |||
/// processing machinery. It is intentionally a short name to make qualifi ed | /// processing machinery. It is intentionally a short name to make qualifi ed | |||
skipping to change at line 140 | skipping to change at line 141 | |||
Grouping = 0x03 // Can this option group with other options? | Grouping = 0x03 // Can this option group with other options? | |||
}; | }; | |||
enum MiscFlags { // Miscellaneous flags to adjust argument | enum MiscFlags { // Miscellaneous flags to adjust argument | |||
CommaSeparated = 0x01, // Should this cl::list split between commas? | CommaSeparated = 0x01, // Should this cl::list split between commas? | |||
PositionalEatsArgs = 0x02, // Should this positional cl::list eat -args? | PositionalEatsArgs = 0x02, // Should this positional cl::list eat -args? | |||
Sink = 0x04 // Should this cl::list eat all unknown optio ns? | Sink = 0x04 // Should this cl::list eat all unknown optio ns? | |||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Option Category class | ||||
// | ||||
class OptionCategory { | ||||
private: | ||||
const char *const Name; | ||||
const char *const Description; | ||||
void registerCategory(); | ||||
public: | ||||
OptionCategory(const char *const Name, const char *const Description = 0) | ||||
: Name(Name), Description(Description) { registerCategory(); } | ||||
const char *getName() { return Name; } | ||||
const char *getDescription() { return Description; } | ||||
}; | ||||
// The general Option Category (used as default category). | ||||
extern OptionCategory GeneralCategory; | ||||
//===---------------------------------------------------------------------- | ||||
===// | ||||
// Option Base class | // Option Base class | |||
// | // | |||
class alias; | class alias; | |||
class Option { | class Option { | |||
friend class alias; | friend class alias; | |||
// handleOccurrences - Overriden by subclasses to handle the value passed into | // handleOccurrences - Overriden by subclasses to handle the value passed into | |||
// an argument. Should return true if there was an error processing the | // an argument. Should return true if there was an error processing the | |||
// argument and the program should exit. | // argument and the program should exit. | |||
// | // | |||
skipping to change at line 173 | skipping to change at line 192 | |||
unsigned Occurrences : 3; // enum NumOccurrencesFlag | unsigned Occurrences : 3; // enum NumOccurrencesFlag | |||
// not using the enum type for 'Value' because zero is an implementation | // not using the enum type for 'Value' because zero is an implementation | |||
// detail representing the non-value | // detail representing the non-value | |||
unsigned Value : 2; | unsigned Value : 2; | |||
unsigned HiddenFlag : 2; // enum OptionHidden | unsigned HiddenFlag : 2; // enum OptionHidden | |||
unsigned Formatting : 2; // enum FormattingFlags | unsigned Formatting : 2; // enum FormattingFlags | |||
unsigned Misc : 3; | unsigned Misc : 3; | |||
unsigned Position; // Position of last occurrence of the option | unsigned Position; // Position of last occurrence of the option | |||
unsigned AdditionalVals;// Greater than 0 for multi-valued option. | unsigned AdditionalVals;// Greater than 0 for multi-valued option. | |||
Option *NextRegistered; // Singly linked list of registered options. | Option *NextRegistered; // Singly linked list of registered options. | |||
public: | public: | |||
const char *ArgStr; // The argument string itself (ex: "help", "o") | const char *ArgStr; // The argument string itself (ex: "help", "o") | |||
const char *HelpStr; // The descriptive text message for -help | const char *HelpStr; // The descriptive text message for -help | |||
const char *ValueStr; // String describing what the value of this optio | const char *ValueStr; // String describing what the value of this option | |||
n is | is | |||
OptionCategory *Category; // The Category this option belongs to | ||||
inline enum NumOccurrencesFlag getNumOccurrencesFlag() const { | inline enum NumOccurrencesFlag getNumOccurrencesFlag() const { | |||
return (enum NumOccurrencesFlag)Occurrences; | return (enum NumOccurrencesFlag)Occurrences; | |||
} | } | |||
inline enum ValueExpected getValueExpectedFlag() const { | inline enum ValueExpected getValueExpectedFlag() const { | |||
return Value ? ((enum ValueExpected)Value) | return Value ? ((enum ValueExpected)Value) | |||
: getValueExpectedFlagDefault(); | : getValueExpectedFlagDefault(); | |||
} | } | |||
inline enum OptionHidden getOptionHiddenFlag() const { | inline enum OptionHidden getOptionHiddenFlag() const { | |||
return (enum OptionHidden)HiddenFlag; | return (enum OptionHidden)HiddenFlag; | |||
skipping to change at line 214 | skipping to change at line 235 | |||
void setDescription(const char *S) { HelpStr = S; } | void setDescription(const char *S) { HelpStr = S; } | |||
void setValueStr(const char *S) { ValueStr = S; } | void setValueStr(const char *S) { ValueStr = S; } | |||
void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) { | void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) { | |||
Occurrences = Val; | Occurrences = Val; | |||
} | } | |||
void setValueExpectedFlag(enum ValueExpected Val) { Value = Val; } | void setValueExpectedFlag(enum ValueExpected Val) { Value = Val; } | |||
void setHiddenFlag(enum OptionHidden Val) { HiddenFlag = Val; } | void setHiddenFlag(enum OptionHidden Val) { HiddenFlag = Val; } | |||
void setFormattingFlag(enum FormattingFlags V) { Formatting = V; } | void setFormattingFlag(enum FormattingFlags V) { Formatting = V; } | |||
void setMiscFlag(enum MiscFlags M) { Misc |= M; } | void setMiscFlag(enum MiscFlags M) { Misc |= M; } | |||
void setPosition(unsigned pos) { Position = pos; } | void setPosition(unsigned pos) { Position = pos; } | |||
void setCategory(OptionCategory &C) { Category = &C; } | ||||
protected: | protected: | |||
explicit Option(enum NumOccurrencesFlag OccurrencesFlag, | explicit Option(enum NumOccurrencesFlag OccurrencesFlag, | |||
enum OptionHidden Hidden) | enum OptionHidden Hidden) | |||
: NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), | : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), | |||
HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), | HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), | |||
Position(0), AdditionalVals(0), NextRegistered(0), | Position(0), AdditionalVals(0), NextRegistered(0), | |||
ArgStr(""), HelpStr(""), ValueStr("") { | ArgStr(""), HelpStr(""), ValueStr(""), Category(&GeneralCategory) { | |||
} | } | |||
inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; } | inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; } | |||
public: | public: | |||
// addArgument - Register this argument with the commandline system. | // addArgument - Register this argument with the commandline system. | |||
// | // | |||
void addArgument(); | void addArgument(); | |||
Option *getNextRegisteredOption() const { return NextRegistered; } | Option *getNextRegisteredOption() const { return NextRegistered; } | |||
skipping to change at line 310 | skipping to change at line 332 | |||
Ty &Loc; | Ty &Loc; | |||
LocationClass(Ty &L) : Loc(L) {} | LocationClass(Ty &L) : Loc(L) {} | |||
template<class Opt> | template<class Opt> | |||
void apply(Opt &O) const { O.setLocation(O, Loc); } | void apply(Opt &O) const { O.setLocation(O, Loc); } | |||
}; | }; | |||
template<class Ty> | template<class Ty> | |||
LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); } | LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); } | |||
// cat - Specifiy the Option category for the command line argument to belo | ||||
ng | ||||
// to. | ||||
struct cat { | ||||
OptionCategory &Category; | ||||
cat(OptionCategory &c) : Category(c) {} | ||||
template<class Opt> | ||||
void apply(Opt &O) const { O.setCategory(Category); } | ||||
}; | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// OptionValue class | // OptionValue class | |||
// Support value comparison outside the template. | // Support value comparison outside the template. | |||
struct GenericOptionValue { | struct GenericOptionValue { | |||
virtual ~GenericOptionValue() {} | virtual ~GenericOptionValue() {} | |||
virtual bool compare(const GenericOptionValue &V) const = 0; | virtual bool compare(const GenericOptionValue &V) const = 0; | |||
private: | private: | |||
virtual void anchor(); | virtual void anchor(); | |||
}; | }; | |||
skipping to change at line 466 | skipping to change at line 498 | |||
while (const char *enumName = va_arg(ValueArgs, const char *)) { | while (const char *enumName = va_arg(ValueArgs, const char *)) { | |||
DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int)); | DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int)); | |||
const char *EnumDesc = va_arg(ValueArgs, const char *); | const char *EnumDesc = va_arg(ValueArgs, const char *); | |||
Values.push_back(std::make_pair(enumName, // Add value to value map | Values.push_back(std::make_pair(enumName, // Add value to value map | |||
std::make_pair(EnumVal, EnumDesc))); | std::make_pair(EnumVal, EnumDesc))); | |||
} | } | |||
} | } | |||
template<class Opt> | template<class Opt> | |||
void apply(Opt &O) const { | void apply(Opt &O) const { | |||
for (unsigned i = 0, e = static_cast<unsigned>(Values.size()); | for (size_t i = 0, e = Values.size(); i != e; ++i) | |||
i != e; ++i) | ||||
O.getParser().addLiteralOption(Values[i].first, Values[i].second.firs t, | O.getParser().addLiteralOption(Values[i].first, Values[i].second.firs t, | |||
Values[i].second.second); | Values[i].second.second); | |||
} | } | |||
}; | }; | |||
template<class DataType> | template<class DataType> | |||
ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val, | ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val, | |||
const char *Desc, ...) { | const char *Desc, ...) { | |||
va_list ValueArgs; | va_list ValueArgs; | |||
va_start(ValueArgs, Desc); | va_start(ValueArgs, Desc); | |||
skipping to change at line 625 | skipping to change at line 656 | |||
} | } | |||
// parse - Return true on error. | // parse - Return true on error. | |||
bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) { | bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) { | |||
StringRef ArgVal; | StringRef ArgVal; | |||
if (hasArgStr) | if (hasArgStr) | |||
ArgVal = Arg; | ArgVal = Arg; | |||
else | else | |||
ArgVal = ArgName; | ArgVal = ArgName; | |||
for (unsigned i = 0, e = static_cast<unsigned>(Values.size()); | for (size_t i = 0, e = Values.size(); i != e; ++i) | |||
i != e; ++i) | ||||
if (Values[i].Name == ArgVal) { | if (Values[i].Name == ArgVal) { | |||
V = Values[i].V.getValue(); | V = Values[i].V.getValue(); | |||
return false; | return false; | |||
} | } | |||
return O.error("Cannot find option named '" + ArgVal + "'!"); | return O.error("Cannot find option named '" + ArgVal + "'!"); | |||
} | } | |||
/// addLiteralOption - Add an entry to the mapping table. | /// addLiteralOption - Add an entry to the mapping table. | |||
/// | /// | |||
skipping to change at line 1087 | skipping to change at line 1117 | |||
// to get at the value. | // to get at the value. | |||
// | // | |||
template<class DataType> | template<class DataType> | |||
class opt_storage<DataType, false, false> { | class opt_storage<DataType, false, false> { | |||
public: | public: | |||
DataType Value; | DataType Value; | |||
OptionValue<DataType> Default; | OptionValue<DataType> Default; | |||
// Make sure we initialize the value with the default constructor for the | // Make sure we initialize the value with the default constructor for the | |||
// type. | // type. | |||
opt_storage() : Value(DataType()) {} | opt_storage() : Value(DataType()), Default(DataType()) {} | |||
template<class T> | template<class T> | |||
void setValue(const T &V, bool initial = false) { | void setValue(const T &V, bool initial = false) { | |||
Value = V; | Value = V; | |||
if (initial) | if (initial) | |||
Default = V; | Default = V; | |||
} | } | |||
DataType &getValue() { return Value; } | DataType &getValue() { return Value; } | |||
DataType getValue() const { return Value; } | DataType getValue() const { return Value; } | |||
skipping to change at line 1665 | skipping to change at line 1695 | |||
// extrahelp - provide additional help at the end of the normal help | // extrahelp - provide additional help at the end of the normal help | |||
// output. All occurrences of cl::extrahelp will be accumulated and | // output. All occurrences of cl::extrahelp will be accumulated and | |||
// printed to stderr at the end of the regular help, just before | // printed to stderr at the end of the regular help, just before | |||
// exit is called. | // exit is called. | |||
struct extrahelp { | struct extrahelp { | |||
const char * morehelp; | const char * morehelp; | |||
explicit extrahelp(const char* help); | explicit extrahelp(const char* help); | |||
}; | }; | |||
void PrintVersionMessage(); | void PrintVersionMessage(); | |||
// This function just prints the help message, exactly the same way as if t | ||||
he | /// This function just prints the help message, exactly the same way as if | |||
// -help option had been given on the command line. | the | |||
// NOTE: THIS FUNCTION TERMINATES THE PROGRAM! | /// -help or -help-hidden option had been given on the command line. | |||
void PrintHelpMessage(); | /// | |||
/// NOTE: THIS FUNCTION TERMINATES THE PROGRAM! | ||||
/// | ||||
/// \param hidden if true will print hidden options | ||||
/// \param categorized if true print options in categories | ||||
void PrintHelpMessage(bool Hidden=false, bool Categorized=false); | ||||
//===---------------------------------------------------------------------- | ||||
===// | ||||
// Public interface for accessing registered options. | ||||
// | ||||
/// \brief Use this to get a StringMap to all registered named options | ||||
/// (e.g. -help). Note \p Map Should be an empty StringMap. | ||||
/// | ||||
/// \param [out] map will be filled with mappings where the key is the | ||||
/// Option argument string (e.g. "help") and value is the corresponding | ||||
/// Option*. | ||||
/// | ||||
/// Access to unnamed arguments (i.e. positional) are not provided because | ||||
/// it is expected that the client already has access to these. | ||||
/// | ||||
/// Typical usage: | ||||
/// \code | ||||
/// main(int argc,char* argv[]) { | ||||
/// StringMap<llvm::cl::Option*> opts; | ||||
/// llvm::cl::getRegisteredOptions(opts); | ||||
/// assert(opts.count("help") == 1) | ||||
/// opts["help"]->setDescription("Show alphabetical help information") | ||||
/// // More code | ||||
/// llvm::cl::ParseCommandLineOptions(argc,argv); | ||||
/// //More code | ||||
/// } | ||||
/// \endcode | ||||
/// | ||||
/// This interface is useful for modifying options in libraries that are ou | ||||
t of | ||||
/// the control of the client. The options should be modified before callin | ||||
g | ||||
/// llvm::cl::ParseCommandLineOptions(). | ||||
void getRegisteredOptions(StringMap<Option*> &Map); | ||||
} // End namespace cl | } // End namespace cl | |||
} // End namespace llvm | } // End namespace llvm | |||
#endif | #endif | |||
End of changes. 12 change blocks. | ||||
17 lines changed or deleted | 89 lines changed or added | |||
Compiler.h | Compiler.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines several macros, based on the current compiler. This a llows | // This file defines several macros, based on the current compiler. This a llows | |||
// use of compiler-specific features in a way that remains portable. | // use of compiler-specific features in a way that remains portable. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_COMPILER_H | #ifndef LLVM_SUPPORT_COMPILER_H | |||
#define LLVM_SUPPORT_COMPILER_H | #define LLVM_SUPPORT_COMPILER_H | |||
#include "llvm/Config/llvm-config.h" | ||||
#ifndef __has_feature | #ifndef __has_feature | |||
# define __has_feature(x) 0 | # define __has_feature(x) 0 | |||
#endif | #endif | |||
/// LLVM_HAS_RVALUE_REFERENCES - Does the compiler provide r-value referenc es? | /// \brief Does the compiler support r-value references? | |||
/// This implies that <utility> provides the one-argument std::move; it | /// This implies that <utility> provides the one-argument std::move; it | |||
/// does not imply the existence of any other C++ library features. | /// does not imply the existence of any other C++ library features. | |||
#if (__has_feature(cxx_rvalue_references) \ | #if (__has_feature(cxx_rvalue_references) \ | |||
|| defined(__GXX_EXPERIMENTAL_CXX0X__) \ | || defined(__GXX_EXPERIMENTAL_CXX0X__) \ | |||
|| (defined(_MSC_VER) && _MSC_VER >= 1600)) | || (defined(_MSC_VER) && _MSC_VER >= 1600)) | |||
#define LLVM_USE_RVALUE_REFERENCES 1 | #define LLVM_HAS_RVALUE_REFERENCES 1 | |||
#else | ||||
#define LLVM_HAS_RVALUE_REFERENCES 0 | ||||
#endif | ||||
/// \brief Does the compiler support r-value reference *this? | ||||
/// | ||||
/// Sadly, this is separate from just r-value reference support because GCC | ||||
/// implemented everything but this thus far. No release of GCC yet has sup | ||||
port | ||||
/// for this feature so it is enabled with Clang only. | ||||
/// FIXME: This should change to a version check when GCC grows support for | ||||
it. | ||||
#if __has_feature(cxx_rvalue_references) | ||||
#define LLVM_HAS_RVALUE_REFERENCE_THIS 1 | ||||
#else | ||||
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0 | ||||
#endif | ||||
/// \macro LLVM_HAS_CXX11_TYPETRAITS | ||||
/// \brief Does the compiler have the C++11 type traits. | ||||
/// | ||||
/// #include <type_traits> | ||||
/// | ||||
/// * enable_if | ||||
/// * {true,false}_type | ||||
/// * is_constructible | ||||
/// * etc... | ||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) \ | ||||
|| (defined(_MSC_VER) && _MSC_VER >= 1700) | ||||
#define LLVM_HAS_CXX11_TYPETRAITS 1 | ||||
#else | ||||
#define LLVM_HAS_CXX11_TYPETRAITS 0 | ||||
#endif | ||||
/// \macro LLVM_HAS_CXX11_STDLIB | ||||
/// \brief Does the compiler have the C++11 standard library. | ||||
/// | ||||
/// Implies LLVM_HAS_RVALUE_REFERENCES, LLVM_HAS_CXX11_TYPETRAITS | ||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) \ | ||||
|| (defined(_MSC_VER) && _MSC_VER >= 1700) | ||||
#define LLVM_HAS_CXX11_STDLIB 1 | ||||
#else | #else | |||
#define LLVM_USE_RVALUE_REFERENCES 0 | #define LLVM_HAS_CXX11_STDLIB 0 | |||
#endif | ||||
/// \macro LLVM_HAS_VARIADIC_TEMPLATES | ||||
/// \brief Does this compiler support variadic templates. | ||||
/// | ||||
/// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward. | ||||
#if __has_feature(cxx_variadic_templates) | ||||
# define LLVM_HAS_VARIADIC_TEMPLATES 1 | ||||
#else | ||||
# define LLVM_HAS_VARIADIC_TEMPLATES 0 | ||||
#endif | #endif | |||
/// llvm_move - Expands to ::std::move if the compiler supports | /// llvm_move - Expands to ::std::move if the compiler supports | |||
/// r-value references; otherwise, expands to the argument. | /// r-value references; otherwise, expands to the argument. | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
#define llvm_move(value) (::std::move(value)) | #define llvm_move(value) (::std::move(value)) | |||
#else | #else | |||
#define llvm_move(value) (value) | #define llvm_move(value) (value) | |||
#endif | #endif | |||
/// Expands to '&' if r-value references are supported. | ||||
/// | ||||
/// This can be used to provide l-value/r-value overrides of member functio | ||||
ns. | ||||
/// The r-value override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THI | ||||
S | ||||
#if LLVM_HAS_RVALUE_REFERENCE_THIS | ||||
#define LLVM_LVALUE_FUNCTION & | ||||
#else | ||||
#define LLVM_LVALUE_FUNCTION | ||||
#endif | ||||
/// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it . | /// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it . | |||
/// Use to mark functions as uncallable. Member functions with this should | /// Use to mark functions as uncallable. Member functions with this should | |||
/// be declared private so that some behavior is kept in C++03 mode. | /// be declared private so that some behavior is kept in C++03 mode. | |||
/// | /// | |||
/// class DontCopy { | /// class DontCopy { | |||
/// private: | /// private: | |||
/// DontCopy(const DontCopy&) LLVM_DELETED_FUNCTION; | /// DontCopy(const DontCopy&) LLVM_DELETED_FUNCTION; | |||
/// DontCopy &operator =(const DontCopy&) LLVM_DELETED_FUNCTION; | /// DontCopy &operator =(const DontCopy&) LLVM_DELETED_FUNCTION; | |||
/// public: | /// public: | |||
/// ... | /// ... | |||
skipping to change at line 62 | skipping to change at line 123 | |||
#if (__has_feature(cxx_deleted_functions) \ | #if (__has_feature(cxx_deleted_functions) \ | |||
|| defined(__GXX_EXPERIMENTAL_CXX0X__)) | || defined(__GXX_EXPERIMENTAL_CXX0X__)) | |||
// No version of MSVC currently supports this. | // No version of MSVC currently supports this. | |||
#define LLVM_DELETED_FUNCTION = delete | #define LLVM_DELETED_FUNCTION = delete | |||
#else | #else | |||
#define LLVM_DELETED_FUNCTION | #define LLVM_DELETED_FUNCTION | |||
#endif | #endif | |||
/// LLVM_FINAL - Expands to 'final' if the compiler supports it. | /// LLVM_FINAL - Expands to 'final' if the compiler supports it. | |||
/// Use to mark classes or virtual methods as final. | /// Use to mark classes or virtual methods as final. | |||
#if (__has_feature(cxx_override_control)) | #if __has_feature(cxx_override_control) \ | |||
|| (defined(_MSC_VER) && _MSC_VER >= 1700) | ||||
#define LLVM_FINAL final | #define LLVM_FINAL final | |||
#else | #else | |||
#define LLVM_FINAL | #define LLVM_FINAL | |||
#endif | #endif | |||
/// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it. | /// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it. | |||
/// Use to mark virtual methods as overriding a base class method. | /// Use to mark virtual methods as overriding a base class method. | |||
#if (__has_feature(cxx_override_control)) | #if __has_feature(cxx_override_control) \ | |||
|| (defined(_MSC_VER) && _MSC_VER >= 1700) | ||||
#define LLVM_OVERRIDE override | #define LLVM_OVERRIDE override | |||
#else | #else | |||
#define LLVM_OVERRIDE | #define LLVM_OVERRIDE | |||
#endif | #endif | |||
#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__) | ||||
# define LLVM_CONSTEXPR constexpr | ||||
#else | ||||
# define LLVM_CONSTEXPR | ||||
#endif | ||||
/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is link ed | /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is link ed | |||
/// into a shared library, then the class should be private to the library and | /// 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 | /// not accessible from outside it. Can also be used to mark variables and | |||
/// functions, making them private to any shared library they are linked in to. | /// functions, making them private to any shared library they are linked in to. | |||
#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__) | #if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__) | |||
#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) | #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) | |||
#else | #else | |||
#define LLVM_LIBRARY_VISIBILITY | #define LLVM_LIBRARY_VISIBILITY | |||
#endif | #endif | |||
skipping to change at line 145 | skipping to change at line 214 | |||
// in the .cpp file, use this: | // in the .cpp file, use this: | |||
// TEMPLATE_INSTANTIATION(class foo<bar>); | // TEMPLATE_INSTANTIATION(class foo<bar>); | |||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X | #define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X | |||
#define TEMPLATE_INSTANTIATION(X) template X | #define TEMPLATE_INSTANTIATION(X) template X | |||
#else | #else | |||
#define EXTERN_TEMPLATE_INSTANTIATION(X) | #define EXTERN_TEMPLATE_INSTANTIATION(X) | |||
#define TEMPLATE_INSTANTIATION(X) | #define TEMPLATE_INSTANTIATION(X) | |||
#endif | #endif | |||
// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do s | /// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do | |||
o, | so, | |||
// mark a method "not for inlining". | /// mark a method "not for inlining". | |||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) | #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) | |||
#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) | #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) | |||
#elif defined(_MSC_VER) | #elif defined(_MSC_VER) | |||
#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline) | #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline) | |||
#else | #else | |||
#define LLVM_ATTRIBUTE_NOINLINE | #define LLVM_ATTRIBUTE_NOINLINE | |||
#endif | #endif | |||
// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to | /// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive t | |||
do | o do | |||
// so, mark a method "always inline" because it is performance sensitive. G | /// so, mark a method "always inline" because it is performance sensitive. | |||
CC | GCC | |||
// 3.4 supported this but is buggy in various cases and produces unimplemen | /// 3.4 supported this but is buggy in various cases and produces unimpleme | |||
ted | nted | |||
// errors, just use it in GCC 4.0 and later. | /// errors, just use it in GCC 4.0 and later. | |||
#if __GNUC__ > 3 | #if __GNUC__ > 3 | |||
#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) | #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) | |||
#elif defined(_MSC_VER) | #elif defined(_MSC_VER) | |||
#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline | #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline | |||
#else | #else | |||
#define LLVM_ATTRIBUTE_ALWAYS_INLINE | #define LLVM_ATTRIBUTE_ALWAYS_INLINE | |||
#endif | #endif | |||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
#define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn)) | #define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn)) | |||
#elif defined(_MSC_VER) | #elif defined(_MSC_VER) | |||
#define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn) | #define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn) | |||
#else | #else | |||
#define LLVM_ATTRIBUTE_NORETURN | #define LLVM_ATTRIBUTE_NORETURN | |||
#endif | #endif | |||
// LLVM_EXTENSION - Support compilers where we have a keyword to suppress | /// LLVM_EXTENSION - Support compilers where we have a keyword to suppress | |||
// pedantic diagnostics. | /// pedantic diagnostics. | |||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
#define LLVM_EXTENSION __extension__ | #define LLVM_EXTENSION __extension__ | |||
#else | #else | |||
#define LLVM_EXTENSION | #define LLVM_EXTENSION | |||
#endif | #endif | |||
// LLVM_ATTRIBUTE_DEPRECATED(decl, "message") | // LLVM_ATTRIBUTE_DEPRECATED(decl, "message") | |||
#if __has_feature(attribute_deprecated_with_message) | #if __has_feature(attribute_deprecated_with_message) | |||
# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ | # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ | |||
decl __attribute__((deprecated(message))) | decl __attribute__((deprecated(message))) | |||
skipping to change at line 198 | skipping to change at line 267 | |||
# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ | # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ | |||
decl __attribute__((deprecated)) | decl __attribute__((deprecated)) | |||
#elif defined(_MSC_VER) | #elif defined(_MSC_VER) | |||
# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ | # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ | |||
__declspec(deprecated(message)) decl | __declspec(deprecated(message)) decl | |||
#else | #else | |||
# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ | # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ | |||
decl | decl | |||
#endif | #endif | |||
// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands | /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands | |||
// to an expression which states that it is undefined behavior for the | /// to an expression which states that it is undefined behavior for the | |||
// compiler to reach this point. Otherwise is not defined. | /// compiler to reach this point. Otherwise is not defined. | |||
#if defined(__clang__) || (__GNUC__ > 4) \ | #if defined(__clang__) || (__GNUC__ > 4) \ | |||
|| (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) | || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) | |||
# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() | # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() | |||
#elif defined(_MSC_VER) | ||||
# define LLVM_BUILTIN_UNREACHABLE __assume(false) | ||||
#endif | #endif | |||
// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an express | /// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expres | |||
ion | sion | |||
// which causes the program to exit abnormally. | /// which causes the program to exit abnormally. | |||
#if defined(__clang__) || (__GNUC__ > 4) \ | #if defined(__clang__) || (__GNUC__ > 4) \ | |||
|| (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) | || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) | |||
# define LLVM_BUILTIN_TRAP __builtin_trap() | # define LLVM_BUILTIN_TRAP __builtin_trap() | |||
#else | #else | |||
# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 | # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 | |||
#endif | #endif | |||
/// \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. | ||||
# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) | ||||
#elif defined(LLVM_BUILTIN_UNREACHABLE) | ||||
# define LLVM_ASSUME_ALIGNED(p, a) \ | ||||
(((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, | ||||
(p))) | ||||
#else | ||||
# define LLVM_ASSUME_ALIGNED(p, a) (p) | ||||
#endif | ||||
/// \macro LLVM_FUNCTION_NAME | ||||
/// \brief Expands to __func__ on compilers which support it. Otherwise, | ||||
/// expands to a compiler-dependent replacement. | ||||
#if defined(_MSC_VER) | ||||
# define LLVM_FUNCTION_NAME __FUNCTION__ | ||||
#else | ||||
# define LLVM_FUNCTION_NAME __func__ | ||||
#endif | ||||
#if defined(HAVE_SANITIZER_MSAN_INTERFACE_H) | ||||
# include <sanitizer/msan_interface.h> | ||||
#else | ||||
# define __msan_allocated_memory(p, size) | ||||
# define __msan_unpoison(p, size) | ||||
#endif | ||||
/// \macro LLVM_MEMORY_SANITIZER_BUILD | ||||
/// \brief Whether LLVM itself is built with MemorySanitizer instrumentatio | ||||
n. | ||||
#if __has_feature(memory_sanitizer) | ||||
# define LLVM_MEMORY_SANITIZER_BUILD 1 | ||||
#else | ||||
# define LLVM_MEMORY_SANITIZER_BUILD 0 | ||||
#endif | ||||
/// \macro LLVM_ADDRESS_SANITIZER_BUILD | ||||
/// \brief Whether LLVM itself is built with AddressSanitizer instrumentati | ||||
on. | ||||
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) | ||||
# define LLVM_ADDRESS_SANITIZER_BUILD 1 | ||||
#else | ||||
# define LLVM_ADDRESS_SANITIZER_BUILD 0 | ||||
#endif | ||||
/// \macro LLVM_IS_UNALIGNED_ACCESS_FAST | ||||
/// \brief Is unaligned memory access fast on the host machine. | ||||
/// | ||||
/// Don't specialize on alignment for platforms where unaligned memory acce | ||||
sses | ||||
/// generates the same code as aligned memory accesses for common types. | ||||
#if defined(_M_AMD64) || defined(_M_IX86) || defined(__amd64) || \ | ||||
defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || \ | ||||
defined(_X86_) || defined(__i386) || defined(__i386__) | ||||
# define LLVM_IS_UNALIGNED_ACCESS_FAST 1 | ||||
#else | ||||
# define LLVM_IS_UNALIGNED_ACCESS_FAST 0 | ||||
#endif | ||||
/// \macro LLVM_EXPLICIT | ||||
/// \brief Expands to explicit on compilers which support explicit conversi | ||||
on | ||||
/// operators. Otherwise expands to nothing. | ||||
#if (__has_feature(cxx_explicit_conversions) \ | ||||
|| defined(__GXX_EXPERIMENTAL_CXX0X__)) | ||||
#define LLVM_EXPLICIT explicit | ||||
#else | ||||
#define LLVM_EXPLICIT | ||||
#endif | ||||
/// \macro LLVM_STATIC_ASSERT | ||||
/// \brief Expands to C/C++'s static_assert on compilers which support it. | ||||
#if __has_feature(cxx_static_assert) | ||||
# define LLVM_STATIC_ASSERT(expr, msg) static_assert(expr, msg) | ||||
#elif __has_feature(c_static_assert) | ||||
# define LLVM_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg) | ||||
#else | ||||
# define LLVM_STATIC_ASSERT(expr, msg) | ||||
#endif | ||||
#endif | #endif | |||
End of changes. 16 change blocks. | ||||
24 lines changed or deleted | 182 lines changed or added | |||
Constant.h | Constant.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the declaration of the Constant class. | // This file contains the declaration of the Constant class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CONSTANT_H | #ifndef LLVM_IR_CONSTANT_H | |||
#define LLVM_CONSTANT_H | #define LLVM_IR_CONSTANT_H | |||
#include "llvm/User.h" | #include "llvm/IR/User.h" | |||
namespace llvm { | namespace llvm { | |||
class APInt; | class APInt; | |||
template<typename T> class SmallVectorImpl; | template<typename T> class SmallVectorImpl; | |||
/// This is an important base class in LLVM. It provides the common facilit ies | /// This is an important base class in LLVM. It provides the common facilit ies | |||
/// of all constant values in an LLVM program. A constant is a value that i s | /// of all constant values in an LLVM program. A constant is a value that i s | |||
/// immutable at runtime. Functions are constants because their address is | /// immutable at runtime. Functions are constants because their address is | |||
/// immutable. Same with global variables. | /// immutable. Same with global variables. | |||
skipping to change at line 64 | skipping to change at line 64 | |||
bool isNullValue() const; | bool isNullValue() const; | |||
/// isAllOnesValue - Return true if this is the value that would be retur ned by | /// isAllOnesValue - Return true if this is the value that would be retur ned by | |||
/// getAllOnesValue. | /// getAllOnesValue. | |||
bool isAllOnesValue() const; | bool isAllOnesValue() const; | |||
/// isNegativeZeroValue - Return true if the value is what would be retur ned | /// isNegativeZeroValue - Return true if the value is what would be retur ned | |||
/// by getZeroValueForNegation. | /// by getZeroValueForNegation. | |||
bool isNegativeZeroValue() const; | bool isNegativeZeroValue() const; | |||
/// Return true if the value is negative zero or null value. | ||||
bool isZeroValue() const; | ||||
/// canTrap - Return true if evaluation of this constant could trap. Thi s is | /// canTrap - Return true if evaluation of this constant could trap. Thi s is | |||
/// true for things like constant expressions that could divide by zero. | /// true for things like constant expressions that could divide by zero. | |||
bool canTrap() const; | bool canTrap() const; | |||
/// isThreadDependent - Return true if the value can vary between threads . | /// isThreadDependent - Return true if the value can vary between threads . | |||
bool isThreadDependent() const; | bool isThreadDependent() const; | |||
/// isConstantUsed - Return true if the constant has users other than con stant | /// isConstantUsed - Return true if the constant has users other than con stant | |||
/// exprs and other dangling things. | /// exprs and other dangling things. | |||
bool isConstantUsed() const; | bool isConstantUsed() const; | |||
skipping to change at line 104 | skipping to change at line 107 | |||
/// FIXME: This really should not be in VMCore. | /// FIXME: This really should not be in VMCore. | |||
PossibleRelocationsTy getRelocationInfo() const; | PossibleRelocationsTy getRelocationInfo() const; | |||
/// getAggregateElement - For aggregates (struct/array/vector) return the | /// getAggregateElement - For aggregates (struct/array/vector) return the | |||
/// constant that corresponds to the specified element if possible, or nu ll if | /// constant that corresponds to the specified element if possible, or nu ll if | |||
/// not. This can return null if the element index is a ConstantExpr, or if | /// not. This can return null if the element index is a ConstantExpr, or if | |||
/// 'this' is a constant expr. | /// 'this' is a constant expr. | |||
Constant *getAggregateElement(unsigned Elt) const; | Constant *getAggregateElement(unsigned Elt) const; | |||
Constant *getAggregateElement(Constant *Elt) const; | Constant *getAggregateElement(Constant *Elt) const; | |||
/// getSplatValue - If this is a splat vector constant, meaning that all | ||||
of | ||||
/// the elements have the same value, return that value. Otherwise return | ||||
0. | ||||
Constant *getSplatValue() const; | ||||
/// If C is a constant integer then return its value, otherwise C must be | ||||
a | ||||
/// vector of constant integers, all equal, and the common value is retur | ||||
ned. | ||||
const APInt &getUniqueInteger() const; | ||||
/// destroyConstant - Called if some element of this constant is no longe r | /// destroyConstant - Called if some element of this constant is no longe r | |||
/// valid. At this point only other constants may be on the use_list for this | /// valid. At this point only other constants may be on the use_list for this | |||
/// constant. Any constants on our Use list must also be destroy'd. The | /// constant. Any constants on our Use list must also be destroy'd. The | |||
/// implementation must be sure to remove the constant from the list of | /// implementation must be sure to remove the constant from the list of | |||
/// available cached constants. Implementations should call | /// available cached constants. Implementations should call | |||
/// destroyConstantImpl as the last thing they do, to destroy all users a nd | /// destroyConstantImpl as the last thing they do, to destroy all users a nd | |||
/// delete this. | /// delete this. | |||
virtual void destroyConstant() { llvm_unreachable("Not reached!"); } | virtual void destroyConstant() { llvm_unreachable("Not reached!"); } | |||
//// Methods for support type inquiry through isa, cast, and dyn_cast: | //// Methods for support type inquiry through isa, cast, and dyn_cast: | |||
End of changes. 4 change blocks. | ||||
3 lines changed or deleted | 18 lines changed or added | |||
ConstantFolder.h | ConstantFolder.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file defines the ConstantFolder class, a helper for IRBuilder. | // This file defines the ConstantFolder class, a helper for IRBuilder. | |||
// It provides IRBuilder with a set of methods for creating constants | // It provides IRBuilder with a set of methods for creating constants | |||
// with minimal folding. For general constant creation and folding, | // with minimal folding. For general constant creation and folding, | |||
// use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h. | // use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_CONSTANTFOLDER_H | #ifndef LLVM_SUPPORT_CONSTANTFOLDER_H | |||
#define LLVM_SUPPORT_CONSTANTFOLDER_H | #define LLVM_SUPPORT_CONSTANTFOLDER_H | |||
#include "llvm/Constants.h" | #include "llvm/IR/Constants.h" | |||
#include "llvm/InstrTypes.h" | #include "llvm/IR/InstrTypes.h" | |||
namespace llvm { | namespace llvm { | |||
/// ConstantFolder - Create constants with minimum, target independent, fol ding. | /// ConstantFolder - Create constants with minimum, target independent, fol ding. | |||
class ConstantFolder { | class ConstantFolder { | |||
public: | public: | |||
explicit ConstantFolder() {} | explicit ConstantFolder() {} | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Binary Operators | // Binary Operators | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
ConstantRange.h | ConstantRange.h | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
// The other integral ranges use min/max values for special range values. F or | // The other integral ranges use min/max values for special range values. F or | |||
// example, for 8-bit types, it uses: | // example, for 8-bit types, it uses: | |||
// [0, 0) = {} = Empty set | // [0, 0) = {} = Empty set | |||
// [255, 255) = {0..255} = Full Set | // [255, 255) = {0..255} = Full Set | |||
// | // | |||
// Note that ConstantRange can be used to represent either signed or | // Note that ConstantRange can be used to represent either signed or | |||
// unsigned ranges. | // unsigned ranges. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_CONSTANT_RANGE_H | #ifndef LLVM_SUPPORT_CONSTANTRANGE_H | |||
#define LLVM_SUPPORT_CONSTANT_RANGE_H | #define LLVM_SUPPORT_CONSTANTRANGE_H | |||
#include "llvm/ADT/APInt.h" | #include "llvm/ADT/APInt.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
/// ConstantRange - This class represents an range of values. | /// ConstantRange - This class represents an range of values. | |||
/// | /// | |||
class ConstantRange { | class ConstantRange { | |||
APInt Lower, Upper; | APInt Lower, Upper; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Constants.h | Constants.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
/// This file contains the declarations for the subclasses of Constant, | /// This file contains the declarations for the subclasses of Constant, | |||
/// which represent the different flavors of constant values that live in L LVM. | /// which represent the different flavors of constant values that live in L LVM. | |||
/// Note that Constants are immutable (once created they never change) and are | /// Note that Constants are immutable (once created they never change) and are | |||
/// fully shared by structural equivalence. This means that two structural ly | /// fully shared by structural equivalence. This means that two structural ly | |||
/// equivalent constants will always have the same address. Constant's are | /// equivalent constants will always have the same address. Constant's are | |||
/// created on demand as needed and never deleted: thus clients don't have to | /// created on demand as needed and never deleted: thus clients don't have to | |||
/// worry about the lifetime of the objects. | /// worry about the lifetime of the objects. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CONSTANTS_H | #ifndef LLVM_IR_CONSTANTS_H | |||
#define LLVM_CONSTANTS_H | #define LLVM_IR_CONSTANTS_H | |||
#include "llvm/Constant.h" | ||||
#include "llvm/OperandTraits.h" | ||||
#include "llvm/ADT/APInt.h" | ||||
#include "llvm/ADT/APFloat.h" | #include "llvm/ADT/APFloat.h" | |||
#include "llvm/ADT/APInt.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/IR/Constant.h" | ||||
#include "llvm/IR/OperandTraits.h" | ||||
#include "llvm/IR/DerivedTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
class ArrayType; | class ArrayType; | |||
class IntegerType; | class IntegerType; | |||
class StructType; | class StructType; | |||
class PointerType; | class PointerType; | |||
class VectorType; | class VectorType; | |||
class SequentialType; | class SequentialType; | |||
skipping to change at line 141 | skipping to change at line 142 | |||
/// because this is all that can be represented with all types. | /// because this is all that can be represented with all types. | |||
/// @brief Determine if this constant's value is same as an unsigned char . | /// @brief Determine if this constant's value is same as an unsigned char . | |||
bool equalsInt(uint64_t V) const { | bool equalsInt(uint64_t V) const { | |||
return Val == V; | return Val == V; | |||
} | } | |||
/// getType - Specialize the getType() method to always return an Integer Type, | /// getType - Specialize the getType() method to always return an Integer Type, | |||
/// which reduces the amount of casting needed in parts of the compiler. | /// which reduces the amount of casting needed in parts of the compiler. | |||
/// | /// | |||
inline IntegerType *getType() const { | inline IntegerType *getType() const { | |||
return reinterpret_cast<IntegerType*>(Value::getType()); | return cast<IntegerType>(Value::getType()); | |||
} | } | |||
/// This static method returns true if the type Ty is big enough to | /// This static method returns true if the type Ty is big enough to | |||
/// represent the value V. This can be used to avoid having the get metho d | /// represent the value V. This can be used to avoid having the get metho d | |||
/// assert when V is larger than Ty can represent. Note that there are tw o | /// assert when V is larger than Ty can represent. Note that there are tw o | |||
/// versions of this method, one for unsigned and one for signed integers . | /// versions of this method, one for unsigned and one for signed integers . | |||
/// Although ConstantInt canonicalizes everything to an unsigned integer, | /// Although ConstantInt canonicalizes everything to an unsigned integer, | |||
/// the signed version avoids callers having to convert a signed quantity | /// the signed version avoids callers having to convert a signed quantity | |||
/// to the appropriate unsigned type before calling the method. | /// to the appropriate unsigned type before calling the method. | |||
/// @returns true if V is a valid value for type Ty | /// @returns true if V is a valid value for type Ty | |||
skipping to change at line 355 | skipping to change at line 356 | |||
// ConstantArray accessors | // ConstantArray accessors | |||
static Constant *get(ArrayType *T, ArrayRef<Constant*> V); | static Constant *get(ArrayType *T, ArrayRef<Constant*> V); | |||
/// Transparently provide more efficient getOperand methods. | /// Transparently provide more efficient getOperand methods. | |||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); | |||
/// getType - Specialize the getType() method to always return an ArrayTy pe, | /// getType - Specialize the getType() method to always return an ArrayTy pe, | |||
/// which reduces the amount of casting needed in parts of the compiler. | /// which reduces the amount of casting needed in parts of the compiler. | |||
/// | /// | |||
inline ArrayType *getType() const { | inline ArrayType *getType() const { | |||
return reinterpret_cast<ArrayType*>(Value::getType()); | return cast<ArrayType>(Value::getType()); | |||
} | } | |||
virtual void destroyConstant(); | virtual void destroyConstant(); | |||
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); | virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); | |||
/// Methods for support type inquiry through isa, cast, and dyn_cast: | /// Methods for support type inquiry through isa, cast, and dyn_cast: | |||
static bool classof(const Value *V) { | static bool classof(const Value *V) { | |||
return V->getValueID() == ConstantArrayVal; | return V->getValueID() == ConstantArrayVal; | |||
} | } | |||
}; | }; | |||
skipping to change at line 413 | skipping to change at line 414 | |||
static StructType *getTypeForElements(LLVMContext &Ctx, | static StructType *getTypeForElements(LLVMContext &Ctx, | |||
ArrayRef<Constant*> V, | ArrayRef<Constant*> V, | |||
bool Packed = false); | bool Packed = false); | |||
/// Transparently provide more efficient getOperand methods. | /// Transparently provide more efficient getOperand methods. | |||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); | |||
/// getType() specialization - Reduce amount of casting... | /// getType() specialization - Reduce amount of casting... | |||
/// | /// | |||
inline StructType *getType() const { | inline StructType *getType() const { | |||
return reinterpret_cast<StructType*>(Value::getType()); | return cast<StructType>(Value::getType()); | |||
} | } | |||
virtual void destroyConstant(); | virtual void destroyConstant(); | |||
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); | virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); | |||
/// Methods for support type inquiry through isa, cast, and dyn_cast: | /// Methods for support type inquiry through isa, cast, and dyn_cast: | |||
static bool classof(const Value *V) { | static bool classof(const Value *V) { | |||
return V->getValueID() == ConstantStructVal; | return V->getValueID() == ConstantStructVal; | |||
} | } | |||
}; | }; | |||
skipping to change at line 455 | skipping to change at line 456 | |||
/// element. | /// element. | |||
static Constant *getSplat(unsigned NumElts, Constant *Elt); | static Constant *getSplat(unsigned NumElts, Constant *Elt); | |||
/// Transparently provide more efficient getOperand methods. | /// Transparently provide more efficient getOperand methods. | |||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); | |||
/// getType - Specialize the getType() method to always return a VectorTy pe, | /// getType - Specialize the getType() method to always return a VectorTy pe, | |||
/// which reduces the amount of casting needed in parts of the compiler. | /// which reduces the amount of casting needed in parts of the compiler. | |||
/// | /// | |||
inline VectorType *getType() const { | inline VectorType *getType() const { | |||
return reinterpret_cast<VectorType*>(Value::getType()); | return cast<VectorType>(Value::getType()); | |||
} | } | |||
/// getSplatValue - If this is a splat constant, meaning that all of the | /// getSplatValue - If this is a splat constant, meaning that all of the | |||
/// elements have the same value, return that value. Otherwise return NUL L. | /// elements have the same value, return that value. Otherwise return NUL L. | |||
Constant *getSplatValue() const; | Constant *getSplatValue() const; | |||
virtual void destroyConstant(); | virtual void destroyConstant(); | |||
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); | virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); | |||
/// Methods for support type inquiry through isa, cast, and dyn_cast: | /// Methods for support type inquiry through isa, cast, and dyn_cast: | |||
skipping to change at line 486 | skipping to change at line 487 | |||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant) | DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant) | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// ConstantPointerNull - a constant pointer value that points to null | /// ConstantPointerNull - a constant pointer value that points to null | |||
/// | /// | |||
class ConstantPointerNull : public Constant { | class ConstantPointerNull : public Constant { | |||
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; | void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; | |||
ConstantPointerNull(const ConstantPointerNull &) LLVM_DELETED_FUNCTION; | ConstantPointerNull(const ConstantPointerNull &) LLVM_DELETED_FUNCTION; | |||
protected: | protected: | |||
explicit ConstantPointerNull(PointerType *T) | explicit ConstantPointerNull(PointerType *T) | |||
: Constant(reinterpret_cast<Type*>(T), | : Constant(T, | |||
Value::ConstantPointerNullVal, 0, 0) {} | Value::ConstantPointerNullVal, 0, 0) {} | |||
protected: | protected: | |||
// allocate space for exactly zero operands | // allocate space for exactly zero operands | |||
void *operator new(size_t s) { | void *operator new(size_t s) { | |||
return User::operator new(s, 0); | return User::operator new(s, 0); | |||
} | } | |||
public: | public: | |||
/// get() - Static factory methods - Return objects of the specified valu e | /// get() - Static factory methods - Return objects of the specified valu e | |||
static ConstantPointerNull *get(PointerType *T); | static ConstantPointerNull *get(PointerType *T); | |||
virtual void destroyConstant(); | virtual void destroyConstant(); | |||
/// getType - Specialize the getType() method to always return an Pointer Type, | /// getType - Specialize the getType() method to always return an Pointer Type, | |||
/// which reduces the amount of casting needed in parts of the compiler. | /// which reduces the amount of casting needed in parts of the compiler. | |||
/// | /// | |||
inline PointerType *getType() const { | inline PointerType *getType() const { | |||
return reinterpret_cast<PointerType*>(Value::getType()); | return cast<PointerType>(Value::getType()); | |||
} | } | |||
/// Methods for support type inquiry through isa, cast, and dyn_cast: | /// Methods for support type inquiry through isa, cast, and dyn_cast: | |||
static bool classof(const Value *V) { | static bool classof(const Value *V) { | |||
return V->getValueID() == ConstantPointerNullVal; | return V->getValueID() == ConstantPointerNullVal; | |||
} | } | |||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// ConstantDataSequential - A vector or array constant whose element type is a | /// ConstantDataSequential - A vector or array constant whose element type is a | |||
skipping to change at line 580 | skipping to change at line 581 | |||
/// getElementAsConstant - Return a Constant for a specified index's elem ent. | /// getElementAsConstant - Return a Constant for a specified index's elem ent. | |||
/// Note that this has to compute a new constant to return, so it isn't a s | /// Note that this has to compute a new constant to return, so it isn't a s | |||
/// efficient as getElementAsInteger/Float/Double. | /// efficient as getElementAsInteger/Float/Double. | |||
Constant *getElementAsConstant(unsigned i) const; | Constant *getElementAsConstant(unsigned i) const; | |||
/// getType - Specialize the getType() method to always return a | /// getType - Specialize the getType() method to always return a | |||
/// SequentialType, which reduces the amount of casting needed in parts o f the | /// SequentialType, which reduces the amount of casting needed in parts o f the | |||
/// compiler. | /// compiler. | |||
inline SequentialType *getType() const { | inline SequentialType *getType() const { | |||
return reinterpret_cast<SequentialType*>(Value::getType()); | return cast<SequentialType>(Value::getType()); | |||
} | } | |||
/// getElementType - Return the element type of the array/vector. | /// getElementType - Return the element type of the array/vector. | |||
Type *getElementType() const; | Type *getElementType() const; | |||
/// getNumElements - Return the number of elements in the array or vector . | /// getNumElements - Return the number of elements in the array or vector . | |||
unsigned getNumElements() const; | unsigned getNumElements() const; | |||
/// getElementByteSize - Return the size (in bytes) of each element in th e | /// getElementByteSize - Return the size (in bytes) of each element in th e | |||
/// array/vector. The size of the elements is known to be a multiple of one | /// array/vector. The size of the elements is known to be a multiple of one | |||
skipping to change at line 678 | skipping to change at line 679 | |||
/// be placed at the end of the array (increasing the length of the strin g by | /// be placed at the end of the array (increasing the length of the strin g by | |||
/// one more than the StringRef would normally indicate. Pass AddNull=fa lse | /// one more than the StringRef would normally indicate. Pass AddNull=fa lse | |||
/// to disable this behavior. | /// to disable this behavior. | |||
static Constant *getString(LLVMContext &Context, StringRef Initializer, | static Constant *getString(LLVMContext &Context, StringRef Initializer, | |||
bool AddNull = true); | bool AddNull = true); | |||
/// getType - Specialize the getType() method to always return an ArrayTy pe, | /// getType - Specialize the getType() method to always return an ArrayTy pe, | |||
/// which reduces the amount of casting needed in parts of the compiler. | /// which reduces the amount of casting needed in parts of the compiler. | |||
/// | /// | |||
inline ArrayType *getType() const { | inline ArrayType *getType() const { | |||
return reinterpret_cast<ArrayType*>(Value::getType()); | return cast<ArrayType>(Value::getType()); | |||
} | } | |||
/// Methods for support type inquiry through isa, cast, and dyn_cast: | /// Methods for support type inquiry through isa, cast, and dyn_cast: | |||
/// | /// | |||
static bool classof(const Value *V) { | static bool classof(const Value *V) { | |||
return V->getValueID() == ConstantDataArrayVal; | return V->getValueID() == ConstantDataArrayVal; | |||
} | } | |||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
skipping to change at line 731 | skipping to change at line 732 | |||
static Constant *getSplat(unsigned NumElts, Constant *Elt); | static Constant *getSplat(unsigned NumElts, Constant *Elt); | |||
/// getSplatValue - If this is a splat constant, meaning that all of the | /// getSplatValue - If this is a splat constant, meaning that all of the | |||
/// elements have the same value, return that value. Otherwise return NUL L. | /// elements have the same value, return that value. Otherwise return NUL L. | |||
Constant *getSplatValue() const; | Constant *getSplatValue() const; | |||
/// getType - Specialize the getType() method to always return a VectorTy pe, | /// getType - Specialize the getType() method to always return a VectorTy pe, | |||
/// which reduces the amount of casting needed in parts of the compiler. | /// which reduces the amount of casting needed in parts of the compiler. | |||
/// | /// | |||
inline VectorType *getType() const { | inline VectorType *getType() const { | |||
return reinterpret_cast<VectorType*>(Value::getType()); | return cast<VectorType>(Value::getType()); | |||
} | } | |||
/// Methods for support type inquiry through isa, cast, and dyn_cast: | /// Methods for support type inquiry through isa, cast, and dyn_cast: | |||
/// | /// | |||
static bool classof(const Value *V) { | static bool classof(const Value *V) { | |||
return V->getValueID() == ConstantDataVectorVal; | return V->getValueID() == ConstantDataVectorVal; | |||
} | } | |||
}; | }; | |||
/// BlockAddress - The address of a basic block. | /// BlockAddress - The address of a basic block. | |||
skipping to change at line 1072 | skipping to change at line 1073 | |||
Constant *getWithOperands(ArrayRef<Constant*> Ops) const { | Constant *getWithOperands(ArrayRef<Constant*> Ops) const { | |||
return getWithOperands(Ops, getType()); | return getWithOperands(Ops, getType()); | |||
} | } | |||
/// getWithOperands - This returns the current constant expression with t he | /// getWithOperands - This returns the current constant expression with t he | |||
/// operands replaced with the specified values and with the specified re sult | /// operands replaced with the specified values and with the specified re sult | |||
/// type. The specified array must have the same number of operands as o ur | /// type. The specified array must have the same number of operands as o ur | |||
/// current one. | /// current one. | |||
Constant *getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const; | Constant *getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const; | |||
/// getAsInstruction - Returns an Instruction which implements the same o | ||||
peration | ||||
/// as this ConstantExpr. The instruction is not linked to any basic bloc | ||||
k. | ||||
/// | ||||
/// A better approach to this could be to have a constructor for Instruct | ||||
ion | ||||
/// which would take a ConstantExpr parameter, but that would have spread | ||||
/// implementation details of ConstantExpr outside of Constants.cpp, whic | ||||
h | ||||
/// would make it harder to remove ConstantExprs altogether. | ||||
Instruction *getAsInstruction(); | ||||
virtual void destroyConstant(); | virtual void destroyConstant(); | |||
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); | virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); | |||
/// Methods for support type inquiry through isa, cast, and dyn_cast: | /// Methods for support type inquiry through isa, cast, and dyn_cast: | |||
static inline bool classof(const Value *V) { | static inline bool classof(const Value *V) { | |||
return V->getValueID() == ConstantExprVal; | return V->getValueID() == ConstantExprVal; | |||
} | } | |||
private: | private: | |||
// Shadow Value::setValueSubclassData with a private forwarding method so that | // Shadow Value::setValueSubclassData with a private forwarding method so that | |||
End of changes. 14 change blocks. | ||||
14 lines changed or deleted | 28 lines changed or added | |||
Core.h | Core.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
|* the LLVM intermediate representation. *| | |* the LLVM intermediate representation. *| | |||
|* *| | |* *| | |||
\*===---------------------------------------------------------------------- ===*/ | \*===---------------------------------------------------------------------- ===*/ | |||
#ifndef LLVM_C_CORE_H | #ifndef LLVM_C_CORE_H | |||
#define LLVM_C_CORE_H | #define LLVM_C_CORE_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
/* Need these includes to support the LLVM 'cast' template for the C++ 'wra | ||||
p' | ||||
and 'unwrap' conversion functions. */ | ||||
#include "llvm/IRBuilder.h" | ||||
#include "llvm/Module.h" | ||||
#include "llvm/PassRegistry.h" | ||||
extern "C" { | extern "C" { | |||
#endif | #endif | |||
/** | /** | |||
* @defgroup LLVMC LLVM-C: C interface to LLVM | * @defgroup LLVMC LLVM-C: C interface to LLVM | |||
* | * | |||
* This module exposes parts of the LLVM library as a C API. | * This module exposes parts of the LLVM library as a C API. | |||
* | * | |||
* @{ | * @{ | |||
*/ | */ | |||
skipping to change at line 63 | skipping to change at line 56 | |||
* The declared parameter names are descriptive and specify which type is | * The declared parameter names are descriptive and specify which type is | |||
* required. Additionally, each type hierarchy is documented along with the | * required. Additionally, each type hierarchy is documented along with the | |||
* functions that operate upon it. For more detail, refer to LLVM's C++ cod e. | * functions that operate upon it. For more detail, refer to LLVM's C++ cod e. | |||
* If in doubt, refer to Core.cpp, which performs parameter downcasts in th e | * If in doubt, refer to Core.cpp, which performs parameter downcasts in th e | |||
* form unwrap<RequiredType>(Param). | * form unwrap<RequiredType>(Param). | |||
* | * | |||
* Many exotic languages can interoperate with C code but have a harder tim e | * Many exotic languages can interoperate with C code but have a harder tim e | |||
* with C++ due to name mangling. So in addition to C, this interface enabl es | * with C++ due to name mangling. So in addition to C, this interface enabl es | |||
* tools written in such languages. | * tools written in such languages. | |||
* | * | |||
* When included into a C++ source file, also declares 'wrap' and 'unwrap' | ||||
* helpers to perform opaque reference<-->pointer conversions. These helper | ||||
s | ||||
* are shorter and more tightly typed than writing the casts by hand when | ||||
* authoring bindings. In assert builds, they will do runtime type checking | ||||
. | ||||
* | ||||
* @{ | * @{ | |||
*/ | */ | |||
/** | /** | |||
* @defgroup LLVMCCoreTypes Types and Enumerations | * @defgroup LLVMCCoreTypes Types and Enumerations | |||
* | * | |||
* @{ | * @{ | |||
*/ | */ | |||
typedef int LLVMBool; | typedef int LLVMBool; | |||
skipping to change at line 176 | skipping to change at line 164 | |||
LLVMNoCaptureAttribute = 1<<21, | LLVMNoCaptureAttribute = 1<<21, | |||
LLVMNoRedZoneAttribute = 1<<22, | LLVMNoRedZoneAttribute = 1<<22, | |||
LLVMNoImplicitFloatAttribute = 1<<23, | LLVMNoImplicitFloatAttribute = 1<<23, | |||
LLVMNakedAttribute = 1<<24, | LLVMNakedAttribute = 1<<24, | |||
LLVMInlineHintAttribute = 1<<25, | LLVMInlineHintAttribute = 1<<25, | |||
LLVMStackAlignment = 7<<26, | LLVMStackAlignment = 7<<26, | |||
LLVMReturnsTwice = 1 << 29, | LLVMReturnsTwice = 1 << 29, | |||
LLVMUWTable = 1 << 30, | LLVMUWTable = 1 << 30, | |||
LLVMNonLazyBind = 1 << 31 | LLVMNonLazyBind = 1 << 31 | |||
/* FIXME: This attribute is currently not included in the C API as | /* FIXME: These attributes are currently not included in the C API as | |||
a temporary measure until the API/ABI impact to the C API is underst ood | a temporary measure until the API/ABI impact to the C API is underst ood | |||
and the path forward agreed upon. | and the path forward agreed upon. | |||
LLVMAddressSafety = 1ULL << 32 | LLVMAddressSafety = 1ULL << 32, | |||
LLVMStackProtectStrongAttribute = 1ULL<<33 | ||||
*/ | */ | |||
} LLVMAttribute; | } LLVMAttribute; | |||
typedef enum { | typedef enum { | |||
/* Terminator Instructions */ | /* Terminator Instructions */ | |||
LLVMRet = 1, | LLVMRet = 1, | |||
LLVMBr = 2, | LLVMBr = 2, | |||
LLVMSwitch = 3, | LLVMSwitch = 3, | |||
LLVMIndirectBr = 4, | LLVMIndirectBr = 4, | |||
LLVMInvoke = 5, | LLVMInvoke = 5, | |||
skipping to change at line 354 | skipping to change at line 343 | |||
LLVMRealULE, /**< True if unordered, less than, or equal */ | LLVMRealULE, /**< True if unordered, less than, or equal */ | |||
LLVMRealUNE, /**< True if unordered or not equal */ | LLVMRealUNE, /**< True if unordered or not equal */ | |||
LLVMRealPredicateTrue /**< Always true (always folded) */ | LLVMRealPredicateTrue /**< Always true (always folded) */ | |||
} LLVMRealPredicate; | } LLVMRealPredicate; | |||
typedef enum { | typedef enum { | |||
LLVMLandingPadCatch, /**< A catch clause */ | LLVMLandingPadCatch, /**< A catch clause */ | |||
LLVMLandingPadFilter /**< A filter clause */ | LLVMLandingPadFilter /**< A filter clause */ | |||
} LLVMLandingPadClauseTy; | } LLVMLandingPadClauseTy; | |||
typedef enum { | ||||
LLVMNotThreadLocal = 0, | ||||
LLVMGeneralDynamicTLSModel, | ||||
LLVMLocalDynamicTLSModel, | ||||
LLVMInitialExecTLSModel, | ||||
LLVMLocalExecTLSModel | ||||
} LLVMThreadLocalMode; | ||||
typedef enum { | ||||
LLVMAtomicOrderingNotAtomic = 0, /**< A load or store which is not atomic | ||||
*/ | ||||
LLVMAtomicOrderingUnordered = 1, /**< Lowest level of atomicity, guarante | ||||
es | ||||
somewhat sane results, lock free. */ | ||||
LLVMAtomicOrderingMonotonic = 2, /**< guarantees that if you take all the | ||||
operations affecting a specific addres | ||||
s, | ||||
a consistent ordering exists */ | ||||
LLVMAtomicOrderingAcquire = 4, /**< Acquire provides a barrier of the sor | ||||
t | ||||
necessary to acquire a lock to access ot | ||||
her | ||||
memory with normal loads and stores. */ | ||||
LLVMAtomicOrderingRelease = 5, /**< Release is similar to Acquire, but wi | ||||
th | ||||
a barrier of the sort necessary to relea | ||||
se | ||||
a lock. */ | ||||
LLVMAtomicOrderingAcquireRelease = 6, /**< provides both an Acquire and a | ||||
Release barrier (for fences and | ||||
operations which both read and wr | ||||
ite | ||||
memory). */ | ||||
LLVMAtomicOrderingSequentiallyConsistent = 7 /**< provides Acquire semant | ||||
ics | ||||
for loads and Release | ||||
semantics for stores. | ||||
Additionally, it guarantee | ||||
s | ||||
that a total ordering exis | ||||
ts | ||||
between all | ||||
SequentiallyConsistent | ||||
operations. */ | ||||
} LLVMAtomicOrdering; | ||||
typedef enum { | ||||
LLVMAtomicRMWBinOpXchg, /**< Set the new value and return the one old * | ||||
/ | ||||
LLVMAtomicRMWBinOpAdd, /**< Add a value and return the old one */ | ||||
LLVMAtomicRMWBinOpSub, /**< Subtract a value and return the old one */ | ||||
LLVMAtomicRMWBinOpAnd, /**< And a value and return the old one */ | ||||
LLVMAtomicRMWBinOpNand, /**< Not-And a value and return the old one */ | ||||
LLVMAtomicRMWBinOpOr, /**< OR a value and return the old one */ | ||||
LLVMAtomicRMWBinOpXor, /**< Xor a value and return the old one */ | ||||
LLVMAtomicRMWBinOpMax, /**< Sets the value if it's greater than the | ||||
original using a signed comparison and return | ||||
the old one */ | ||||
LLVMAtomicRMWBinOpMin, /**< Sets the value if it's Smaller than the | ||||
original using a signed comparison and return | ||||
the old one */ | ||||
LLVMAtomicRMWBinOpUMax, /**< Sets the value if it's greater than the | ||||
original using an unsigned comparison and retu | ||||
rn | ||||
the old one */ | ||||
LLVMAtomicRMWBinOpUMin /**< Sets the value if it's greater than the | ||||
original using an unsigned comparison and ret | ||||
urn | ||||
the old one */ | ||||
} LLVMAtomicRMWBinOp; | ||||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
void LLVMInitializeCore(LLVMPassRegistryRef R); | void LLVMInitializeCore(LLVMPassRegistryRef R); | |||
/** Deallocate and destroy all ManagedStatic variables. | ||||
@see llvm::llvm_shutdown | ||||
@see ManagedStatic */ | ||||
void LLVMShutdown(); | ||||
/*===-- Error handling ---------------------------------------------------- ===*/ | /*===-- Error handling ---------------------------------------------------- ===*/ | |||
void LLVMDisposeMessage(char *Message); | void LLVMDisposeMessage(char *Message); | |||
/** | /** | |||
* @defgroup LLVMCCoreContext Contexts | * @defgroup LLVMCCoreContext Contexts | |||
* | * | |||
* Contexts are execution states for the core LLVM IR system. | * Contexts are execution states for the core LLVM IR system. | |||
* | * | |||
* Most types are tied to a context instance. Multiple contexts can | * Most types are tied to a context instance. Multiple contexts can | |||
skipping to change at line 1051 | skipping to change at line 1102 | |||
macro(ShuffleVectorInst) \ | macro(ShuffleVectorInst) \ | |||
macro(StoreInst) \ | macro(StoreInst) \ | |||
macro(TerminatorInst) \ | macro(TerminatorInst) \ | |||
macro(BranchInst) \ | macro(BranchInst) \ | |||
macro(IndirectBrInst) \ | macro(IndirectBrInst) \ | |||
macro(InvokeInst) \ | macro(InvokeInst) \ | |||
macro(ReturnInst) \ | macro(ReturnInst) \ | |||
macro(SwitchInst) \ | macro(SwitchInst) \ | |||
macro(UnreachableInst) \ | macro(UnreachableInst) \ | |||
macro(ResumeInst) \ | macro(ResumeInst) \ | |||
macro(UnaryInstruction) \ | macro(UnaryInstruction) \ | |||
macro(AllocaInst) \ | macro(AllocaInst) \ | |||
macro(CastInst) \ | macro(CastInst) \ | |||
macro(BitCastInst) \ | macro(BitCastInst) \ | |||
macro(FPExtInst) \ | macro(FPExtInst) \ | |||
macro(FPToSIInst) \ | macro(FPToSIInst) \ | |||
macro(FPToUIInst) \ | macro(FPToUIInst) \ | |||
macro(FPTruncInst) \ | macro(FPTruncInst) \ | |||
macro(IntToPtrInst) \ | macro(IntToPtrInst) \ | |||
macro(PtrToIntInst) \ | macro(PtrToIntInst) \ | |||
macro(SExtInst) \ | macro(SExtInst) \ | |||
macro(SIToFPInst) \ | macro(SIToFPInst) \ | |||
macro(TruncInst) \ | macro(TruncInst) \ | |||
macro(UIToFPInst) \ | macro(UIToFPInst) \ | |||
macro(ZExtInst) \ | macro(ZExtInst) \ | |||
macro(ExtractValueInst) \ | macro(ExtractValueInst) \ | |||
macro(LoadInst) \ | macro(LoadInst) \ | |||
macro(VAArgInst) | macro(VAArgInst) | |||
/** | /** | |||
* @defgroup LLVMCCoreValueGeneral General APIs | * @defgroup LLVMCCoreValueGeneral General APIs | |||
* | * | |||
* Functions in this section work on all LLVMValueRef instances, | * Functions in this section work on all LLVMValueRef instances, | |||
* regardless of their sub-type. They correspond to functions available | * regardless of their sub-type. They correspond to functions available | |||
* on llvm::Value. | * on llvm::Value. | |||
* | * | |||
* @{ | * @{ | |||
*/ | */ | |||
skipping to change at line 1600 | skipping to change at line 1651 | |||
LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M); | LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M); | |||
LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar); | LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar); | |||
LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar); | LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar); | |||
void LLVMDeleteGlobal(LLVMValueRef GlobalVar); | void LLVMDeleteGlobal(LLVMValueRef GlobalVar); | |||
LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar); | LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar); | |||
void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal); | void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal); | |||
LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar); | LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar); | |||
void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal); | void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal); | |||
LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar); | LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar); | |||
void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant); | void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant); | |||
LLVMThreadLocalMode LLVMGetThreadLocalMode(LLVMValueRef GlobalVar); | ||||
void LLVMSetThreadLocalMode(LLVMValueRef GlobalVar, LLVMThreadLocalMode Mod | ||||
e); | ||||
LLVMBool LLVMIsExternallyInitialized(LLVMValueRef GlobalVar); | ||||
void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtIni | ||||
t); | ||||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
/** | /** | |||
* @defgroup LLVMCoreValueConstantGlobalAlias Global Aliases | * @defgroup LLVMCoreValueConstantGlobalAlias Global Aliases | |||
* | * | |||
* This group contains function that operate on global alias values. | * This group contains function that operate on global alias values. | |||
* | * | |||
skipping to change at line 1688 | skipping to change at line 1743 | |||
void LLVMSetGC(LLVMValueRef Fn, const char *Name); | void LLVMSetGC(LLVMValueRef Fn, const char *Name); | |||
/** | /** | |||
* Add an attribute to a function. | * Add an attribute to a function. | |||
* | * | |||
* @see llvm::Function::addAttribute() | * @see llvm::Function::addAttribute() | |||
*/ | */ | |||
void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); | void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); | |||
/** | /** | |||
* Add a target-dependent attribute to a fuction | ||||
* @see llvm::AttrBuilder::addAttribute() | ||||
*/ | ||||
void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A, | ||||
const char *V); | ||||
/** | ||||
* Obtain an attribute from a function. | * Obtain an attribute from a function. | |||
* | * | |||
* @see llvm::Function::getAttributes() | * @see llvm::Function::getAttributes() | |||
*/ | */ | |||
LLVMAttribute LLVMGetFunctionAttr(LLVMValueRef Fn); | LLVMAttribute LLVMGetFunctionAttr(LLVMValueRef Fn); | |||
/** | /** | |||
* Remove an attribute from a function. | * Remove an attribute from a function. | |||
*/ | */ | |||
void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); | void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); | |||
skipping to change at line 2508 | skipping to change at line 2570 | |||
LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef, LLVMValueRef AggVal, | LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef, LLVMValueRef AggVal, | |||
LLVMValueRef EltVal, unsigned Index, | LLVMValueRef EltVal, unsigned Index, | |||
const char *Name); | const char *Name); | |||
LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef, LLVMValueRef Val, | LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef, LLVMValueRef Val, | |||
const char *Name); | const char *Name); | |||
LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef, LLVMValueRef Val, | LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef, LLVMValueRef Val, | |||
const char *Name); | const char *Name); | |||
LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS, | LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS, | |||
LLVMValueRef RHS, const char *Name); | LLVMValueRef RHS, const char *Name); | |||
LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, | ||||
LLVMValueRef PTR, LLVMValueRef Val, | ||||
LLVMAtomicOrdering ordering, | ||||
LLVMBool singleThread); | ||||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
/** | /** | |||
* @defgroup LLVMCCoreModuleProvider Module Providers | * @defgroup LLVMCCoreModuleProvider Module Providers | |||
* | * | |||
* @{ | * @{ | |||
*/ | */ | |||
skipping to change at line 2546 | skipping to change at line 2612 | |||
* @defgroup LLVMCCoreMemoryBuffers Memory Buffers | * @defgroup LLVMCCoreMemoryBuffers Memory Buffers | |||
* | * | |||
* @{ | * @{ | |||
*/ | */ | |||
LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path, | LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path, | |||
LLVMMemoryBufferRef *OutM emBuf, | LLVMMemoryBufferRef *OutM emBuf, | |||
char **OutMessage); | char **OutMessage); | |||
LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, | LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, | |||
char **OutMessage); | char **OutMessage); | |||
LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange(const char *Input | ||||
Data, | ||||
size_t InputDataL | ||||
ength, | ||||
const char *Buffe | ||||
rName, | ||||
LLVMBool Requires | ||||
NullTerminator); | ||||
LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy(const char *I | ||||
nputData, | ||||
size_t InputD | ||||
ataLength, | ||||
const char *B | ||||
ufferName); | ||||
const char *LLVMGetBufferStart(LLVMMemoryBufferRef MemBuf); | ||||
size_t LLVMGetBufferSize(LLVMMemoryBufferRef MemBuf); | ||||
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf); | void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf); | |||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
/** | /** | |||
* @defgroup LLVMCCorePassRegistry Pass Registry | * @defgroup LLVMCCorePassRegistry Pass Registry | |||
* | * | |||
* @{ | * @{ | |||
skipping to change at line 2618 | skipping to change at line 2693 | |||
/** Frees the memory of a pass pipeline. For function pipelines, does not f ree | /** Frees the memory of a pass pipeline. For function pipelines, does not f ree | |||
the module provider. | the module provider. | |||
@see llvm::PassManagerBase::~PassManagerBase. */ | @see llvm::PassManagerBase::~PassManagerBase. */ | |||
void LLVMDisposePassManager(LLVMPassManagerRef PM); | void LLVMDisposePassManager(LLVMPassManagerRef PM); | |||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
/** | /** | |||
* @defgroup LLVMCCoreThreading Threading | ||||
* | ||||
* Handle the structures needed to make LLVM safe for multithreading. | ||||
* | ||||
* @{ | ||||
*/ | ||||
/** Allocate and initialize structures needed to make LLVM safe for | ||||
multithreading. The return value indicates whether multithreaded | ||||
initialization succeeded. Must be executed in isolation from all | ||||
other LLVM api calls. | ||||
@see llvm::llvm_start_multithreaded */ | ||||
LLVMBool LLVMStartMultithreaded(); | ||||
/** Deallocate structures necessary to make LLVM safe for multithreading. | ||||
Must be executed in isolation from all other LLVM api calls. | ||||
@see llvm::llvm_stop_multithreaded */ | ||||
void LLVMStopMultithreaded(); | ||||
/** Check whether LLVM is executing in thread-safe mode or not. | ||||
@see llvm::llvm_is_multithreaded */ | ||||
LLVMBool LLVMIsMultithreaded(); | ||||
/** | ||||
* @} | * @} | |||
*/ | */ | |||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
#ifdef __cplusplus | /** | |||
} | * @} | |||
*/ | ||||
namespace llvm { | #ifdef __cplusplus | |||
class MemoryBuffer; | ||||
class PassManagerBase; | ||||
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \ | ||||
inline ty *unwrap(ref P) { \ | ||||
return reinterpret_cast<ty*>(P); \ | ||||
} \ | ||||
\ | ||||
inline ref wrap(const ty *P) { \ | ||||
return reinterpret_cast<ref>(const_cast<ty*>(P)); \ | ||||
} | ||||
#define DEFINE_ISA_CONVERSION_FUNCTIONS(ty, ref) \ | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \ | ||||
\ | ||||
template<typename T> \ | ||||
inline T *unwrap(ref P) { \ | ||||
return cast<T>(unwrap(P)); \ | ||||
} | ||||
#define DEFINE_STDCXX_CONVERSION_FUNCTIONS(ty, ref) \ | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \ | ||||
\ | ||||
template<typename T> \ | ||||
inline T *unwrap(ref P) { \ | ||||
T *Q = (T*)unwrap(P); \ | ||||
assert(Q && "Invalid cast!"); \ | ||||
return Q; \ | ||||
} | ||||
DEFINE_ISA_CONVERSION_FUNCTIONS (Type, LLVMTypeRef | ||||
) | ||||
DEFINE_ISA_CONVERSION_FUNCTIONS (Value, LLVMValueRef | ||||
) | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef | ||||
) | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef | ||||
) | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef | ||||
) | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRe | ||||
f ) | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef | ||||
) | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef | ||||
) | ||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef | ||||
) | ||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassRegistry, LLVMPassRegistryRe | ||||
f ) | ||||
/* LLVMModuleProviderRef exists for historical reasons, but now just hold | ||||
s a | ||||
* Module. | ||||
*/ | ||||
inline Module *unwrap(LLVMModuleProviderRef MP) { | ||||
return reinterpret_cast<Module*>(MP); | ||||
} | ||||
#undef DEFINE_STDCXX_CONVERSION_FUNCTIONS | ||||
#undef DEFINE_ISA_CONVERSION_FUNCTIONS | ||||
#undef DEFINE_SIMPLE_CONVERSION_FUNCTIONS | ||||
/* Specialized opaque context conversions. | ||||
*/ | ||||
inline LLVMContext **unwrap(LLVMContextRef* Tys) { | ||||
return reinterpret_cast<LLVMContext**>(Tys); | ||||
} | ||||
inline LLVMContextRef *wrap(const LLVMContext **Tys) { | ||||
return reinterpret_cast<LLVMContextRef*>(const_cast<LLVMContext**>(Tys) | ||||
); | ||||
} | ||||
/* Specialized opaque type conversions. | ||||
*/ | ||||
inline Type **unwrap(LLVMTypeRef* Tys) { | ||||
return reinterpret_cast<Type**>(Tys); | ||||
} | ||||
inline LLVMTypeRef *wrap(Type **Tys) { | ||||
return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys)); | ||||
} | ||||
/* Specialized opaque value conversions. | ||||
*/ | ||||
inline Value **unwrap(LLVMValueRef *Vals) { | ||||
return reinterpret_cast<Value**>(Vals); | ||||
} | ||||
template<typename T> | ||||
inline T **unwrap(LLVMValueRef *Vals, unsigned Length) { | ||||
#ifdef DEBUG | ||||
for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I) | ||||
cast<T>(*I); | ||||
#endif | ||||
(void)Length; | ||||
return reinterpret_cast<T**>(Vals); | ||||
} | ||||
inline LLVMValueRef *wrap(const Value **Vals) { | ||||
return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals)); | ||||
} | ||||
} | } | |||
#endif /* !defined(__cplusplus) */ | #endif /* !defined(__cplusplus) */ | |||
#endif /* !defined(LLVM_C_CORE_H) */ | #endif /* !defined(LLVM_C_CORE_H) */ | |||
End of changes. 15 change blocks. | ||||
141 lines changed or deleted | 158 lines changed or added | |||
DAGDeltaAlgorithm.h | DAGDeltaAlgorithm.h | |||
---|---|---|---|---|
skipping to change at line 12 | skipping to change at line 12 | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_DAGDELTAALGORITHM_H | #ifndef LLVM_ADT_DAGDELTAALGORITHM_H | |||
#define LLVM_ADT_DAGDELTAALGORITHM_H | #define LLVM_ADT_DAGDELTAALGORITHM_H | |||
#include <vector> | ||||
#include <set> | #include <set> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
/// DAGDeltaAlgorithm - Implements a "delta debugging" algorithm for minimi zing | /// DAGDeltaAlgorithm - Implements a "delta debugging" algorithm for minimi zing | |||
/// directed acyclic graphs using a predicate function. | /// directed acyclic graphs using a predicate function. | |||
/// | /// | |||
/// The result of the algorithm is a subset of the input change set which i s | /// The result of the algorithm is a subset of the input change set which i s | |||
/// guaranteed to satisfy the predicate, assuming that the input set did. F or | /// guaranteed to satisfy the predicate, assuming that the input set did. F or | |||
/// well formed predicates, the result set is guaranteed to be such that | /// well formed predicates, the result set is guaranteed to be such that | |||
/// removing any single element not required by the dependencies on the oth er | /// removing any single element not required by the dependencies on the oth er | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
DFAPacketizer.h | DFAPacketizer.h | |||
---|---|---|---|---|
skipping to change at line 29 | skipping to change at line 29 | |||
// models the addition of an instruction to a packet. In the DFA constructe d | // models the addition of an instruction to a packet. In the DFA constructe d | |||
// by this class, if an instruction can be added to a packet, then a valid | // by this class, if an instruction can be added to a packet, then a valid | |||
// transition exists from the corresponding state. Invalid transitions | // transition exists from the corresponding state. Invalid transitions | |||
// indicate that the instruction cannot be added to the current packet. | // indicate that the instruction cannot be added to the current packet. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_DFAPACKETIZER_H | #ifndef LLVM_CODEGEN_DFAPACKETIZER_H | |||
#define LLVM_CODEGEN_DFAPACKETIZER_H | #define LLVM_CODEGEN_DFAPACKETIZER_H | |||
#include "llvm/CodeGen/MachineBasicBlock.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/CodeGen/MachineBasicBlock.h" | ||||
#include <map> | #include <map> | |||
namespace llvm { | namespace llvm { | |||
class MCInstrDesc; | class MCInstrDesc; | |||
class MachineInstr; | class MachineInstr; | |||
class MachineLoopInfo; | class MachineLoopInfo; | |||
class MachineDominatorTree; | class MachineDominatorTree; | |||
class InstrItineraryData; | class InstrItineraryData; | |||
class DefaultVLIWScheduler; | class DefaultVLIWScheduler; | |||
skipping to change at line 138 | skipping to change at line 138 | |||
ResourceTracker->reserveResources(MI); | ResourceTracker->reserveResources(MI); | |||
return MII; | return MII; | |||
} | } | |||
// endPacket - End the current packet. | // endPacket - End the current packet. | |||
void endPacket(MachineBasicBlock *MBB, MachineInstr *MI); | void endPacket(MachineBasicBlock *MBB, MachineInstr *MI); | |||
// initPacketizerState - perform initialization before packetizing | // initPacketizerState - perform initialization before packetizing | |||
// an instruction. This function is supposed to be overrided by | // an instruction. This function is supposed to be overrided by | |||
// the target dependent packetizer. | // the target dependent packetizer. | |||
virtual void initPacketizerState(void) { return; } | virtual void initPacketizerState() { return; } | |||
// ignorePseudoInstruction - Ignore bundling of pseudo instructions. | // ignorePseudoInstruction - Ignore bundling of pseudo instructions. | |||
virtual bool ignorePseudoInstruction(MachineInstr *I, | virtual bool ignorePseudoInstruction(MachineInstr *I, | |||
MachineBasicBlock *MBB) { | MachineBasicBlock *MBB) { | |||
return false; | return false; | |||
} | } | |||
// isSoloInstruction - return true if instruction MI can not be packetize d | // isSoloInstruction - return true if instruction MI can not be packetize d | |||
// with any other instruction, which means that MI itself is a packet. | // with any other instruction, which means that MI itself is a packet. | |||
virtual bool isSoloInstruction(MachineInstr *MI) { | virtual bool isSoloInstruction(MachineInstr *MI) { | |||
End of changes. 3 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
DIBuilder.h | DIBuilder.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines a DIBuilder that is useful for creating debugging | // This file defines a DIBuilder that is useful for creating debugging | |||
// information entries in LLVM IR form. | // information entries in LLVM IR form. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_DIBUILDER_H | #ifndef LLVM_DIBUILDER_H | |||
#define LLVM_ANALYSIS_DIBUILDER_H | #define LLVM_DIBUILDER_H | |||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/DataTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
class BasicBlock; | class BasicBlock; | |||
class Instruction; | class Instruction; | |||
class Function; | class Function; | |||
class Module; | class Module; | |||
class Value; | class Value; | |||
class LLVMContext; | class LLVMContext; | |||
class MDNode; | class MDNode; | |||
class StringRef; | class StringRef; | |||
class DIBasicType; | ||||
class DICompositeType; | ||||
class DIDerivedType; | ||||
class DIDescriptor; | class DIDescriptor; | |||
class DIFile; | class DIFile; | |||
class DIEnumerator; | class DIEnumerator; | |||
class DIType; | class DIType; | |||
class DIArray; | class DIArray; | |||
class DIGlobalVariable; | class DIGlobalVariable; | |||
class DIImportedModule; | ||||
class DINameSpace; | class DINameSpace; | |||
class DIVariable; | class DIVariable; | |||
class DISubrange; | class DISubrange; | |||
class DILexicalBlockFile; | class DILexicalBlockFile; | |||
class DILexicalBlock; | class DILexicalBlock; | |||
class DIScope; | ||||
class DISubprogram; | class DISubprogram; | |||
class DITemplateTypeParameter; | class DITemplateTypeParameter; | |||
class DITemplateValueParameter; | class DITemplateValueParameter; | |||
class DIObjCProperty; | class DIObjCProperty; | |||
class DIBuilder { | class DIBuilder { | |||
private: | private: | |||
Module &M; | Module &M; | |||
LLVMContext & VMContext; | LLVMContext & VMContext; | |||
MDNode *TheCU; | MDNode *TheCU; | |||
MDNode *TempEnumTypes; | MDNode *TempEnumTypes; | |||
MDNode *TempRetainTypes; | MDNode *TempRetainTypes; | |||
MDNode *TempSubprograms; | MDNode *TempSubprograms; | |||
MDNode *TempGVs; | MDNode *TempGVs; | |||
MDNode *TempImportedModules; | ||||
Function *DeclareFn; // llvm.dbg.declare | Function *DeclareFn; // llvm.dbg.declare | |||
Function *ValueFn; // llvm.dbg.value | Function *ValueFn; // llvm.dbg.value | |||
SmallVector<Value *, 4> AllEnumTypes; | SmallVector<Value *, 4> AllEnumTypes; | |||
SmallVector<Value *, 4> AllRetainTypes; | SmallVector<Value *, 4> AllRetainTypes; | |||
SmallVector<Value *, 4> AllSubprograms; | SmallVector<Value *, 4> AllSubprograms; | |||
SmallVector<Value *, 4> AllGVs; | SmallVector<Value *, 4> AllGVs; | |||
SmallVector<Value *, 4> AllImportedModules; | ||||
DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION; | DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION; | |||
void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION; | void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
explicit DIBuilder(Module &M); | explicit DIBuilder(Module &M); | |||
const MDNode *getCU() { return TheCU; } | const MDNode *getCU() { return TheCU; } | |||
enum ComplexAddrKind { OpPlus=1, OpDeref }; | enum ComplexAddrKind { OpPlus=1, OpDeref }; | |||
/// finalize - Construct any deferred debug info descriptors. | /// finalize - Construct any deferred debug info descriptors. | |||
skipping to change at line 91 | skipping to change at line 98 | |||
/// @param Dir Directory | /// @param Dir Directory | |||
/// @param Producer String identify producer of debugging information. | /// @param Producer String identify producer of debugging information. | |||
/// Usuall this is a compiler version string. | /// Usuall this is a compiler version string. | |||
/// @param isOptimized A boolean flag which indicates whether optimizat ion | /// @param isOptimized A boolean flag which indicates whether optimizat ion | |||
/// is ON or not. | /// is ON or not. | |||
/// @param Flags This string lists command line options. This string is | /// @param Flags This string lists command line options. This string is | |||
/// directly embedded in debug info output which may be used | /// directly embedded in debug info output which may be used | |||
/// by a tool analyzing generated debugging information . | /// by a tool analyzing generated debugging information . | |||
/// @param RV This indicates runtime version for languages like | /// @param RV This indicates runtime version for languages like | |||
/// Objective-C. | /// Objective-C. | |||
/// @param SplitName The name of the file that we'll split debug info o | ||||
ut | ||||
/// into. | ||||
void createCompileUnit(unsigned Lang, StringRef File, StringRef Dir, | void createCompileUnit(unsigned Lang, StringRef File, StringRef Dir, | |||
StringRef Producer, | StringRef Producer, bool isOptimized, | |||
bool isOptimized, StringRef Flags, unsigned RV); | StringRef Flags, unsigned RV, | |||
StringRef SplitName = StringRef()); | ||||
/// createFile - Create a file descriptor to hold debugging information | /// createFile - Create a file descriptor to hold debugging information | |||
/// for a file. | /// for a file. | |||
DIFile createFile(StringRef Filename, StringRef Directory); | DIFile createFile(StringRef Filename, StringRef Directory); | |||
/// createEnumerator - Create a single enumerator value. | /// createEnumerator - Create a single enumerator value. | |||
DIEnumerator createEnumerator(StringRef Name, uint64_t Val); | DIEnumerator createEnumerator(StringRef Name, uint64_t Val); | |||
/// createNullPtrType - Create C++0x nullptr type. | /// createNullPtrType - Create C++0x nullptr type. | |||
DIType createNullPtrType(StringRef Name); | DIType createNullPtrType(StringRef Name); | |||
/// createBasicType - Create debugging information entry for a basic | /// createBasicType - Create debugging information entry for a basic | |||
/// type. | /// type. | |||
/// @param Name Type name. | /// @param Name Type name. | |||
/// @param SizeInBits Size of the type. | /// @param SizeInBits Size of the type. | |||
/// @param AlignInBits Type alignment. | /// @param AlignInBits Type alignment. | |||
/// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float. | /// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float. | |||
DIType createBasicType(StringRef Name, uint64_t SizeInBits, | DIBasicType createBasicType(StringRef Name, uint64_t SizeInBits, | |||
uint64_t AlignInBits, unsigned Encoding); | uint64_t AlignInBits, unsigned Encoding); | |||
/// createQualifiedType - Create debugging information entry for a qual ified | /// createQualifiedType - Create debugging information entry for a qual ified | |||
/// type, e.g. 'const int'. | /// type, e.g. 'const int'. | |||
/// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_ty pe | /// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_ty pe | |||
/// @param FromTy Base Type. | /// @param FromTy Base Type. | |||
DIType createQualifiedType(unsigned Tag, DIType FromTy); | DIDerivedType createQualifiedType(unsigned Tag, DIType FromTy); | |||
/// createPointerType - Create debugging information entry for a pointe r. | /// createPointerType - Create debugging information entry for a pointe r. | |||
/// @param PointeeTy Type pointed by this pointer. | /// @param PointeeTy Type pointed by this pointer. | |||
/// @param SizeInBits Size. | /// @param SizeInBits Size. | |||
/// @param AlignInBits Alignment. (optional) | /// @param AlignInBits Alignment. (optional) | |||
/// @param Name Pointer type name. (optional) | /// @param Name Pointer type name. (optional) | |||
DIType createPointerType(DIType PointeeTy, uint64_t SizeInBits, | DIDerivedType | |||
uint64_t AlignInBits = 0, | createPointerType(DIType PointeeTy, uint64_t SizeInBits, | |||
StringRef Name = StringRef()); | uint64_t AlignInBits = 0, StringRef Name = StringRef( | |||
)); | ||||
/// \brief Create debugging information entry for a pointer to member. | ||||
/// @param PointeeTy Type pointed to by this pointer. | ||||
/// @param Class Type for which this pointer points to members of. | ||||
DIDerivedType createMemberPointerType(DIType PointeeTy, DIType Class); | ||||
/// createReferenceType - Create debugging information entry for a c++ | /// createReferenceType - Create debugging information entry for a c++ | |||
/// style reference or rvalue reference type. | /// style reference or rvalue reference type. | |||
DIType createReferenceType(unsigned Tag, DIType RTy); | DIDerivedType createReferenceType(unsigned Tag, DIType RTy); | |||
/// createTypedef - Create debugging information entry for a typedef. | /// createTypedef - Create debugging information entry for a typedef. | |||
/// @param Ty Original type. | /// @param Ty Original type. | |||
/// @param Name Typedef name. | /// @param Name Typedef name. | |||
/// @param File File where this type is defined. | /// @param File File where this type is defined. | |||
/// @param LineNo Line number. | /// @param LineNo Line number. | |||
/// @param Context The surrounding context for the typedef. | /// @param Context The surrounding context for the typedef. | |||
DIType createTypedef(DIType Ty, StringRef Name, DIFile File, | DIDerivedType createTypedef(DIType Ty, StringRef Name, DIFile File, | |||
unsigned LineNo, DIDescriptor Context); | unsigned LineNo, DIDescriptor Context); | |||
/// createFriend - Create debugging information entry for a 'friend'. | /// createFriend - Create debugging information entry for a 'friend'. | |||
DIType createFriend(DIType Ty, DIType FriendTy); | DIType createFriend(DIType Ty, DIType FriendTy); | |||
/// createInheritance - Create debugging information entry to establish | /// createInheritance - Create debugging information entry to establish | |||
/// inheritance relationship between two types. | /// inheritance relationship between two types. | |||
/// @param Ty Original type. | /// @param Ty Original type. | |||
/// @param BaseTy Base type. Ty is inherits from base. | /// @param BaseTy Base type. Ty is inherits from base. | |||
/// @param BaseOffset Base offset. | /// @param BaseOffset Base offset. | |||
/// @param Flags Flags to describe inheritance attribute, | /// @param Flags Flags to describe inheritance attribute, | |||
/// e.g. private | /// e.g. private | |||
DIType createInheritance(DIType Ty, DIType BaseTy, uint64_t BaseOffset, | DIDerivedType createInheritance(DIType Ty, DIType BaseTy, | |||
unsigned Flags); | uint64_t BaseOffset, unsigned Flags); | |||
/// createMemberType - Create debugging information entry for a member. | /// createMemberType - Create debugging information entry for a member. | |||
/// @param Scope Member scope. | /// @param Scope Member scope. | |||
/// @param Name Member name. | /// @param Name Member name. | |||
/// @param File File where this member is defined. | /// @param File File where this member is defined. | |||
/// @param LineNo Line number. | /// @param LineNo Line number. | |||
/// @param SizeInBits Member size. | /// @param SizeInBits Member size. | |||
/// @param AlignInBits Member alignment. | /// @param AlignInBits Member alignment. | |||
/// @param OffsetInBits Member offset. | /// @param OffsetInBits Member offset. | |||
/// @param Flags Flags to encode member attribute, e.g. private | /// @param Flags Flags to encode member attribute, e.g. private | |||
/// @param Ty Parent type. | /// @param Ty Parent type. | |||
DIType createMemberType(DIDescriptor Scope, StringRef Name, DIFile File | DIDerivedType | |||
, | createMemberType(DIDescriptor Scope, StringRef Name, DIFile File, | |||
unsigned LineNo, uint64_t SizeInBits, | unsigned LineNo, uint64_t SizeInBits, uint64_t AlignIn | |||
uint64_t AlignInBits, uint64_t OffsetInBits, | Bits, | |||
unsigned Flags, DIType Ty); | uint64_t OffsetInBits, unsigned Flags, DIType Ty); | |||
/// createStaticMemberType - Create debugging information entry for a | ||||
/// C++ static data member. | ||||
/// @param Scope Member scope. | ||||
/// @param Name Member name. | ||||
/// @param File File where this member is declared. | ||||
/// @param LineNo Line number. | ||||
/// @param Ty Type of the static member. | ||||
/// @param Flags Flags to encode member attribute, e.g. private. | ||||
/// @param Val Const initializer of the member. | ||||
DIType createStaticMemberType(DIDescriptor Scope, StringRef Name, | ||||
DIFile File, unsigned LineNo, DIType Ty, | ||||
unsigned Flags, llvm::Value *Val); | ||||
/// createObjCIVar - Create debugging information entry for Objective-C | /// createObjCIVar - Create debugging information entry for Objective-C | |||
/// instance variable. | /// instance variable. | |||
/// @param Name Member name. | /// @param Name Member name. | |||
/// @param File File where this member is defined. | /// @param File File where this member is defined. | |||
/// @param LineNo Line number. | /// @param LineNo Line number. | |||
/// @param SizeInBits Member size. | /// @param SizeInBits Member size. | |||
/// @param AlignInBits Member alignment. | /// @param AlignInBits Member alignment. | |||
/// @param OffsetInBits Member offset. | /// @param OffsetInBits Member offset. | |||
/// @param Flags Flags to encode member attribute, e.g. private | /// @param Flags Flags to encode member attribute, e.g. private | |||
skipping to change at line 244 | skipping to change at line 272 | |||
/// @param SizeInBits Member size. | /// @param SizeInBits Member size. | |||
/// @param AlignInBits Member alignment. | /// @param AlignInBits Member alignment. | |||
/// @param OffsetInBits Member offset. | /// @param OffsetInBits Member offset. | |||
/// @param Flags Flags to encode member attribute, e.g. private | /// @param Flags Flags to encode member attribute, e.g. private | |||
/// @param Elements class members. | /// @param Elements class members. | |||
/// @param VTableHolder Debug info of the base class that contains vtab le | /// @param VTableHolder Debug info of the base class that contains vtab le | |||
/// for this type. This is used in | /// for this type. This is used in | |||
/// DW_AT_containing_type. See DWARF documentation | /// DW_AT_containing_type. See DWARF documentation | |||
/// for more info. | /// for more info. | |||
/// @param TemplateParms Template type parameters. | /// @param TemplateParms Template type parameters. | |||
DIType createClassType(DIDescriptor Scope, StringRef Name, DIFile File, | DICompositeType createClassType(DIDescriptor Scope, StringRef Name, | |||
unsigned LineNumber, uint64_t SizeInBits, | DIFile File, unsigned LineNumber, | |||
uint64_t AlignInBits, uint64_t OffsetInBits, | uint64_t SizeInBits, uint64_t AlignInBi | |||
unsigned Flags, DIType DerivedFrom, | ts, | |||
DIArray Elements, MDNode *VTableHolder = 0, | uint64_t OffsetInBits, unsigned Flags, | |||
MDNode *TemplateParms = 0); | DIType DerivedFrom, DIArray Elements, | |||
MDNode *VTableHolder = 0, | ||||
MDNode *TemplateParms = 0); | ||||
/// createStructType - Create debugging information entry for a struct. | /// createStructType - Create debugging information entry for a struct. | |||
/// @param Scope Scope in which this struct is defined. | /// @param Scope Scope in which this struct is defined. | |||
/// @param Name Struct name. | /// @param Name Struct name. | |||
/// @param File File where this member is defined. | /// @param File File where this member is defined. | |||
/// @param LineNumber Line number. | /// @param LineNumber Line number. | |||
/// @param SizeInBits Member size. | /// @param SizeInBits Member size. | |||
/// @param AlignInBits Member alignment. | /// @param AlignInBits Member alignment. | |||
/// @param Flags Flags to encode member attribute, e.g. private | /// @param Flags Flags to encode member attribute, e.g. private | |||
/// @param Elements Struct elements. | /// @param Elements Struct elements. | |||
/// @param RunTimeLang Optional parameter, Objective-C runtime version . | /// @param RunTimeLang Optional parameter, Objective-C runtime version . | |||
DIType createStructType(DIDescriptor Scope, StringRef Name, DIFile File | DICompositeType createStructType(DIDescriptor Scope, StringRef Name, | |||
, | DIFile File, unsigned LineNumber, | |||
unsigned LineNumber, uint64_t SizeInBits, | uint64_t SizeInBits, uint64_t AlignInB | |||
uint64_t AlignInBits, unsigned Flags, | its, | |||
DIArray Elements, unsigned RunTimeLang = 0); | unsigned Flags, DIType DerivedFrom, | |||
DIArray Elements, unsigned RunTimeLang | ||||
= 0, | ||||
MDNode *VTableHolder = 0); | ||||
/// createUnionType - Create debugging information entry for an union. | /// createUnionType - Create debugging information entry for an union. | |||
/// @param Scope Scope in which this union is defined. | /// @param Scope Scope in which this union is defined. | |||
/// @param Name Union name. | /// @param Name Union name. | |||
/// @param File File where this member is defined. | /// @param File File where this member is defined. | |||
/// @param LineNumber Line number. | /// @param LineNumber Line number. | |||
/// @param SizeInBits Member size. | /// @param SizeInBits Member size. | |||
/// @param AlignInBits Member alignment. | /// @param AlignInBits Member alignment. | |||
/// @param Flags Flags to encode member attribute, e.g. private | /// @param Flags Flags to encode member attribute, e.g. private | |||
/// @param Elements Union elements. | /// @param Elements Union elements. | |||
/// @param RunTimeLang Optional parameter, Objective-C runtime version . | /// @param RunTimeLang Optional parameter, Objective-C runtime version . | |||
DIType createUnionType(DIDescriptor Scope, StringRef Name, DIFile File, | DICompositeType createUnionType( | |||
unsigned LineNumber, uint64_t SizeInBits, | DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumbe | |||
uint64_t AlignInBits, unsigned Flags, | r, | |||
DIArray Elements, unsigned RunTimeLang = 0); | uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, | |||
DIArray Elements, unsigned RunTimeLang = 0); | ||||
/// createTemplateTypeParameter - Create debugging information for temp late | /// createTemplateTypeParameter - Create debugging information for temp late | |||
/// type parameter. | /// type parameter. | |||
/// @param Scope Scope in which this type is defined. | /// @param Scope Scope in which this type is defined. | |||
/// @param Name Type parameter name. | /// @param Name Type parameter name. | |||
/// @param Ty Parameter type. | /// @param Ty Parameter type. | |||
/// @param File File where this type parameter is defined. | /// @param File File where this type parameter is defined. | |||
/// @param LineNo Line number. | /// @param LineNo Line number. | |||
/// @param ColumnNo Column Number. | /// @param ColumnNo Column Number. | |||
DITemplateTypeParameter | DITemplateTypeParameter | |||
skipping to change at line 314 | skipping to change at line 345 | |||
createTemplateValueParameter(DIDescriptor Scope, StringRef Name, DIType Ty, | createTemplateValueParameter(DIDescriptor Scope, StringRef Name, DIType Ty, | |||
uint64_t Value, | uint64_t Value, | |||
MDNode *File = 0, unsigned LineNo = 0, | MDNode *File = 0, unsigned LineNo = 0, | |||
unsigned ColumnNo = 0); | unsigned ColumnNo = 0); | |||
/// createArrayType - Create debugging information entry for an array. | /// createArrayType - Create debugging information entry for an array. | |||
/// @param Size Array size. | /// @param Size Array size. | |||
/// @param AlignInBits Alignment. | /// @param AlignInBits Alignment. | |||
/// @param Ty Element type. | /// @param Ty Element type. | |||
/// @param Subscripts Subscripts. | /// @param Subscripts Subscripts. | |||
DIType createArrayType(uint64_t Size, uint64_t AlignInBits, | DICompositeType createArrayType(uint64_t Size, uint64_t AlignInBits, | |||
DIType Ty, DIArray Subscripts); | DIType Ty, DIArray Subscripts); | |||
/// createVectorType - Create debugging information entry for a vector type. | /// createVectorType - Create debugging information entry for a vector type. | |||
/// @param Size Array size. | /// @param Size Array size. | |||
/// @param AlignInBits Alignment. | /// @param AlignInBits Alignment. | |||
/// @param Ty Element type. | /// @param Ty Element type. | |||
/// @param Subscripts Subscripts. | /// @param Subscripts Subscripts. | |||
DIType createVectorType(uint64_t Size, uint64_t AlignInBits, | DIType createVectorType(uint64_t Size, uint64_t AlignInBits, | |||
DIType Ty, DIArray Subscripts); | DIType Ty, DIArray Subscripts); | |||
/// createEnumerationType - Create debugging information entry for an | /// createEnumerationType - Create debugging information entry for an | |||
/// enumeration. | /// enumeration. | |||
/// @param Scope Scope in which this enumeration is defined. | /// @param Scope Scope in which this enumeration is defined. | |||
/// @param Name Union name. | /// @param Name Union name. | |||
/// @param File File where this member is defined. | /// @param File File where this member is defined. | |||
/// @param LineNumber Line number. | /// @param LineNumber Line number. | |||
/// @param SizeInBits Member size. | /// @param SizeInBits Member size. | |||
/// @param AlignInBits Member alignment. | /// @param AlignInBits Member alignment. | |||
/// @param Elements Enumeration elements. | /// @param Elements Enumeration elements. | |||
DIType createEnumerationType(DIDescriptor Scope, StringRef Name, | /// @param UnderlyingType Underlying type of a C++11/ObjC fixed enum. | |||
DIFile File, unsigned LineNumber, | DICompositeType createEnumerationType(DIDescriptor Scope, StringRef Nam | |||
uint64_t SizeInBits, uint64_t AlignInBits, | e, | |||
DIArray Elements, DIType ClassType); | DIFile File, unsigned LineNumber, | |||
uint64_t SizeInBits, | ||||
uint64_t AlignInBits, | ||||
DIArray Elements, | ||||
DIType UnderlyingType); | ||||
/// createSubroutineType - Create subroutine type. | /// createSubroutineType - Create subroutine type. | |||
/// @param File File in which this subroutine is defined. | /// @param File File in which this subroutine is defined. | |||
/// @param ParameterTypes An array of subroutine parameter types. This | /// @param ParameterTypes An array of subroutine parameter types. This | |||
/// includes return type at 0th index. | /// includes return type at 0th index. | |||
DIType createSubroutineType(DIFile File, DIArray ParameterTypes); | DICompositeType createSubroutineType(DIFile File, DIArray ParameterType s); | |||
/// createArtificialType - Create a new DIType with "artificial" flag s et. | /// createArtificialType - Create a new DIType with "artificial" flag s et. | |||
DIType createArtificialType(DIType Ty); | DIType createArtificialType(DIType Ty); | |||
/// createObjectPointerType - Create a new DIType with the "object poin ter" | /// createObjectPointerType - Create a new DIType with the "object poin ter" | |||
/// flag set. | /// flag set. | |||
DIType createObjectPointerType(DIType Ty); | DIType createObjectPointerType(DIType Ty); | |||
/// createTemporaryType - Create a temporary forward-declared type. | ||||
DIType createTemporaryType(); | ||||
DIType createTemporaryType(DIFile F); | ||||
/// createForwardDecl - Create a temporary forward-declared type. | /// createForwardDecl - Create a temporary forward-declared type. | |||
DIType createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Sco pe, | DIType createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Sco pe, | |||
DIFile F, unsigned Line, unsigned RuntimeLang = 0, | DIFile F, unsigned Line, unsigned RuntimeLang = 0, | |||
uint64_t SizeInBits = 0, uint64_t AlignInBits = 0); | uint64_t SizeInBits = 0, uint64_t AlignInBits = 0); | |||
/// retainType - Retain DIType in a module even if it is not referenced | /// retainType - Retain DIType in a module even if it is not referenced | |||
/// through debug info anchors. | /// through debug info anchors. | |||
void retainType(DIType T); | void retainType(DIType T); | |||
/// createUnspecifiedParameter - Create unspeicified type descriptor | /// createUnspecifiedParameter - Create unspeicified type descriptor | |||
/// for a subroutine type. | /// for a subroutine type. | |||
DIDescriptor createUnspecifiedParameter(); | DIDescriptor createUnspecifiedParameter(); | |||
/// getOrCreateArray - Get a DIArray, create one if required. | /// getOrCreateArray - Get a DIArray, create one if required. | |||
DIArray getOrCreateArray(ArrayRef<Value *> Elements); | DIArray getOrCreateArray(ArrayRef<Value *> Elements); | |||
/// getOrCreateSubrange - Create a descriptor for a value range. This | /// getOrCreateSubrange - Create a descriptor for a value range. This | |||
/// implicitly uniques the values returned. | /// implicitly uniques the values returned. | |||
DISubrange getOrCreateSubrange(int64_t Lo, int64_t Hi); | DISubrange getOrCreateSubrange(int64_t Lo, int64_t Count); | |||
/// createGlobalVariable - Create a new descriptor for the specified gl obal. | /// createGlobalVariable - Create a new descriptor for the specified gl obal. | |||
/// @param Name Name of the variable. | /// @param Name Name of the variable. | |||
/// @param File File where this variable is defined. | /// @param File File where this variable is defined. | |||
/// @param LineNo Line number. | /// @param LineNo Line number. | |||
/// @param Ty Variable Type. | /// @param Ty Variable Type. | |||
/// @param isLocalToUnit Boolean flag indicate whether this variable is | /// @param isLocalToUnit Boolean flag indicate whether this variable is | |||
/// externally visible or not. | /// externally visible or not. | |||
/// @param Val llvm::Value of the variable. | /// @param Val llvm::Value of the variable. | |||
DIGlobalVariable | DIGlobalVariable | |||
createGlobalVariable(StringRef Name, DIFile File, unsigned LineNo, | createGlobalVariable(StringRef Name, DIFile File, unsigned LineNo, | |||
DIType Ty, bool isLocalToUnit, llvm::Value *Val); | DIType Ty, bool isLocalToUnit, llvm::Value *Val); | |||
/// \brief Create a new descriptor for the specified global. | ||||
/// @param Name Name of the variable. | ||||
/// @param LinkageName Mangled variable name. | ||||
/// @param File File where this variable is defined. | ||||
/// @param LineNo Line number. | ||||
/// @param Ty Variable Type. | ||||
/// @param isLocalToUnit Boolean flag indicate whether this variable is | ||||
/// externally visible or not. | ||||
/// @param Val llvm::Value of the variable. | ||||
DIGlobalVariable | ||||
createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile File | ||||
, | ||||
unsigned LineNo, DIType Ty, bool isLocalToUnit, | ||||
llvm::Value *Val); | ||||
/// createStaticVariable - Create a new descriptor for the specified | /// createStaticVariable - Create a new descriptor for the specified | |||
/// variable. | /// variable. | |||
/// @param Context Variable scope. | /// @param Context Variable scope. | |||
/// @param Name Name of the variable. | /// @param Name Name of the variable. | |||
/// @param LinkageName Mangled name of the variable. | /// @param LinkageName Mangled name of the variable. | |||
/// @param File File where this variable is defined. | /// @param File File where this variable is defined. | |||
/// @param LineNo Line number. | /// @param LineNo Line number. | |||
/// @param Ty Variable Type. | /// @param Ty Variable Type. | |||
/// @param isLocalToUnit Boolean flag indicate whether this variable is | /// @param isLocalToUnit Boolean flag indicate whether this variable is | |||
/// externally visible or not. | /// externally visible or not. | |||
/// @param Val llvm::Value of the variable. | /// @param Val llvm::Value of the variable. | |||
/// @param Decl Reference to the corresponding declaration. | ||||
DIGlobalVariable | DIGlobalVariable | |||
createStaticVariable(DIDescriptor Context, StringRef Name, | createStaticVariable(DIDescriptor Context, StringRef Name, | |||
StringRef LinkageName, DIFile File, unsigned LineN o, | StringRef LinkageName, DIFile File, unsigned LineN o, | |||
DIType Ty, bool isLocalToUnit, llvm::Value *Val); | DIType Ty, bool isLocalToUnit, llvm::Value *Val, | |||
MDNode *Decl = NULL); | ||||
/// createLocalVariable - Create a new descriptor for the specified | /// createLocalVariable - Create a new descriptor for the specified | |||
/// local variable. | /// local variable. | |||
/// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or | /// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or | |||
/// DW_TAG_arg_variable. | /// DW_TAG_arg_variable. | |||
/// @param Scope Variable scope. | /// @param Scope Variable scope. | |||
/// @param Name Variable name. | /// @param Name Variable name. | |||
/// @param File File where this variable is defined. | /// @param File File where this variable is defined. | |||
/// @param LineNo Line number. | /// @param LineNo Line number. | |||
/// @param Ty Variable Type | /// @param Ty Variable Type | |||
skipping to change at line 527 | skipping to change at line 573 | |||
/// createLexicalBlock - This creates a descriptor for a lexical block | /// createLexicalBlock - This creates a descriptor for a lexical block | |||
/// with the specified parent context. | /// with the specified parent context. | |||
/// @param Scope Parent lexical scope. | /// @param Scope Parent lexical scope. | |||
/// @param File Source file | /// @param File Source file | |||
/// @param Line Line number | /// @param Line Line number | |||
/// @param Col Column number | /// @param Col Column number | |||
DILexicalBlock createLexicalBlock(DIDescriptor Scope, DIFile File, | DILexicalBlock createLexicalBlock(DIDescriptor Scope, DIFile File, | |||
unsigned Line, unsigned Col); | unsigned Line, unsigned Col); | |||
/// \brief Create a descriptor for an imported module. | ||||
/// @param Context The scope this module is imported into | ||||
/// @param NS The namespace being imported here | ||||
/// @param Line Line number | ||||
DIImportedModule createImportedModule(DIScope Context, DINameSpace NS, | ||||
unsigned Line); | ||||
/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. | /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. | |||
/// @param Storage llvm::Value of the variable | /// @param Storage llvm::Value of the variable | |||
/// @param VarInfo Variable's debug info descriptor. | /// @param VarInfo Variable's debug info descriptor. | |||
/// @param InsertAtEnd Location for the new intrinsic. | /// @param InsertAtEnd Location for the new intrinsic. | |||
Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo, | Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo, | |||
BasicBlock *InsertAtEnd); | BasicBlock *InsertAtEnd); | |||
/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. | /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. | |||
/// @param Storage llvm::Value of the variable | /// @param Storage llvm::Value of the variable | |||
/// @param VarInfo Variable's debug info descriptor. | /// @param VarInfo Variable's debug info descriptor. | |||
End of changes. 29 change blocks. | ||||
56 lines changed or deleted | 116 lines changed or added | |||
DIContext.h | DIContext.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file defines DIContext, an abstract data structure that holds | // This file defines DIContext, an abstract data structure that holds | |||
// debug information data. | // debug information data. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_DEBUGINFO_DICONTEXT_H | #ifndef LLVM_DEBUGINFO_DICONTEXT_H | |||
#define LLVM_DEBUGINFO_DICONTEXT_H | #define LLVM_DEBUGINFO_DICONTEXT_H | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/SmallString.h" | #include "llvm/ADT/SmallString.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Object/ObjectFile.h" | ||||
#include "llvm/Object/RelocVisitor.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
class raw_ostream; | class raw_ostream; | |||
/// DILineInfo - a format-neutral container for source line information. | /// DILineInfo - a format-neutral container for source line information. | |||
class DILineInfo { | class DILineInfo { | |||
SmallString<16> FileName; | SmallString<16> FileName; | |||
SmallString<16> FunctionName; | SmallString<16> FunctionName; | |||
skipping to change at line 59 | skipping to change at line 61 | |||
bool operator==(const DILineInfo &RHS) const { | bool operator==(const DILineInfo &RHS) const { | |||
return Line == RHS.Line && Column == RHS.Column && | return Line == RHS.Line && Column == RHS.Column && | |||
FileName.equals(RHS.FileName) && | FileName.equals(RHS.FileName) && | |||
FunctionName.equals(RHS.FunctionName); | FunctionName.equals(RHS.FunctionName); | |||
} | } | |||
bool operator!=(const DILineInfo &RHS) const { | bool operator!=(const DILineInfo &RHS) const { | |||
return !(*this == RHS); | return !(*this == RHS); | |||
} | } | |||
}; | }; | |||
typedef SmallVector<std::pair<uint64_t, DILineInfo>, 16> DILineInfoTable; | ||||
/// DIInliningInfo - a format-neutral container for inlined code descriptio n. | /// DIInliningInfo - a format-neutral container for inlined code descriptio n. | |||
class DIInliningInfo { | class DIInliningInfo { | |||
SmallVector<DILineInfo, 4> Frames; | SmallVector<DILineInfo, 4> Frames; | |||
public: | public: | |||
DIInliningInfo() {} | DIInliningInfo() {} | |||
DILineInfo getFrame(unsigned Index) const { | DILineInfo getFrame(unsigned Index) const { | |||
assert(Index < Frames.size()); | assert(Index < Frames.size()); | |||
return Frames[Index]; | return Frames[Index]; | |||
} | } | |||
uint32_t getNumberOfFrames() const { | uint32_t getNumberOfFrames() const { | |||
skipping to change at line 93 | skipping to change at line 97 | |||
AbsoluteFilePath = 1 << 1, | AbsoluteFilePath = 1 << 1, | |||
FunctionName = 1 << 2 | FunctionName = 1 << 2 | |||
}; | }; | |||
// Use file/line info by default. | // Use file/line info by default. | |||
DILineInfoSpecifier(uint32_t flags = FileLineInfo) : Flags(flags) {} | DILineInfoSpecifier(uint32_t flags = FileLineInfo) : Flags(flags) {} | |||
bool needs(Specification spec) const { | bool needs(Specification spec) const { | |||
return (Flags & spec) > 0; | return (Flags & spec) > 0; | |||
} | } | |||
}; | }; | |||
/// Selects which debug sections get dumped. | ||||
enum DIDumpType { | ||||
DIDT_Null, | ||||
DIDT_All, | ||||
DIDT_Abbrev, | ||||
DIDT_AbbrevDwo, | ||||
DIDT_Aranges, | ||||
DIDT_Frames, | ||||
DIDT_Info, | ||||
DIDT_InfoDwo, | ||||
DIDT_Line, | ||||
DIDT_Ranges, | ||||
DIDT_Pubnames, | ||||
DIDT_Str, | ||||
DIDT_StrDwo, | ||||
DIDT_StrOffsetsDwo | ||||
}; | ||||
// In place of applying the relocations to the data we've read from disk we use | // In place of applying the relocations to the data we've read from disk we use | |||
// a separate mapping table to the side and checking that at locations in t he | // a separate mapping table to the side and checking that at locations in t he | |||
// dwarf where we expect relocated values. This adds a bit of complexity to the | // dwarf where we expect relocated values. This adds a bit of complexity to the | |||
// dwarf parsing/extraction at the benefit of not allocating memory for the | // dwarf parsing/extraction at the benefit of not allocating memory for the | |||
// entire size of the debug info sections. | // entire size of the debug info sections. | |||
typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap; | typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap; | |||
class DIContext { | class DIContext { | |||
public: | public: | |||
virtual ~DIContext(); | virtual ~DIContext(); | |||
/// getDWARFContext - get a context for binary DWARF data. | /// getDWARFContext - get a context for binary DWARF data. | |||
static DIContext *getDWARFContext(bool isLittleEndian, | static DIContext *getDWARFContext(object::ObjectFile *); | |||
StringRef infoSection, | ||||
StringRef abbrevSection, | ||||
StringRef aRangeSection = StringRef(), | ||||
StringRef lineSection = StringRef(), | ||||
StringRef stringSection = StringRef(), | ||||
StringRef rangeSection = StringRef(), | ||||
const RelocAddrMap &Map = RelocAddrMap( | ||||
)); | ||||
virtual void dump(raw_ostream &OS) = 0; | virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) = 0; | |||
virtual DILineInfo getLineInfoForAddress(uint64_t Address, | virtual DILineInfo getLineInfoForAddress(uint64_t Address, | |||
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; | DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; | |||
virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address, | ||||
uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) | ||||
= 0; | ||||
virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address, | virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address, | |||
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; | DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 8 change blocks. | ||||
11 lines changed or deleted | 28 lines changed or added | |||
DOTGraphTraits.h | DOTGraphTraits.h | |||
---|---|---|---|---|
skipping to change at line 82 | skipping to change at line 82 | |||
return ""; | return ""; | |||
} | } | |||
/// hasNodeAddressLabel - If this method returns true, the address of the node | /// hasNodeAddressLabel - If this method returns true, the address of the node | |||
/// is added to the label of the node. | /// is added to the label of the node. | |||
template<typename GraphType> | template<typename GraphType> | |||
static bool hasNodeAddressLabel(const void *, const GraphType &) { | static bool hasNodeAddressLabel(const void *, const GraphType &) { | |||
return false; | return false; | |||
} | } | |||
template<typename GraphType> | ||||
static std::string getNodeDescription(const void *, const GraphType &) { | ||||
return ""; | ||||
} | ||||
/// If you want to specify custom node attributes, this is the place to d o so | /// If you want to specify custom node attributes, this is the place to d o so | |||
/// | /// | |||
template<typename GraphType> | template<typename GraphType> | |||
static std::string getNodeAttributes(const void *, | static std::string getNodeAttributes(const void *, | |||
const GraphType &) { | const GraphType &) { | |||
return ""; | return ""; | |||
} | } | |||
/// If you want to override the dot attributes printed for a particular e dge, | /// If you want to override the dot attributes printed for a particular e dge, | |||
/// override this method. | /// override this method. | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 5 lines changed or added | |||
DOTGraphTraitsPass.h | DOTGraphTraitsPass.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// Templates to create dotty viewer and printer passes for GraphTraits grap hs. | // Templates to create dotty viewer and printer passes for GraphTraits grap hs. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H | #ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H | |||
#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H | #define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/Analysis/CFGPrinter.h" | #include "llvm/Analysis/CFGPrinter.h" | |||
#include "llvm/Pass.h" | ||||
namespace llvm { | namespace llvm { | |||
template <class Analysis, bool Simple> | ||||
struct DOTGraphTraitsViewer : public FunctionPass { | ||||
std::string Name; | ||||
DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) | template <class Analysis, bool Simple> | |||
{ | class DOTGraphTraitsViewer : public FunctionPass { | |||
Name = GraphName; | public: | |||
} | DOTGraphTraitsViewer(StringRef GraphName, char &ID) | |||
: FunctionPass(ID), Name(GraphName) {} | ||||
virtual bool runOnFunction(Function &F) { | virtual bool runOnFunction(Function &F) { | |||
Analysis *Graph; | Analysis *Graph = &getAnalysis<Analysis>(); | |||
std::string Title, GraphName; | std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); | |||
Graph = &getAnalysis<Analysis>(); | std::string Title = GraphName + " for '" + F.getName().str() + "' funct | |||
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); | ion"; | |||
Title = GraphName + " for '" + F.getName().str() + "' function"; | ||||
ViewGraph(Graph, Name, Simple, Title); | ViewGraph(Graph, Name, Simple, Title); | |||
return false; | return false; | |||
} | } | |||
virtual void getAnalysisUsage(AnalysisUsage &AU) const { | virtual void getAnalysisUsage(AnalysisUsage &AU) const { | |||
AU.setPreservesAll(); | AU.setPreservesAll(); | |||
AU.addRequired<Analysis>(); | AU.addRequired<Analysis>(); | |||
} | } | |||
private: | ||||
std::string Name; | ||||
}; | }; | |||
template <class Analysis, bool Simple> | template <class Analysis, bool Simple> | |||
struct DOTGraphTraitsPrinter : public FunctionPass { | class DOTGraphTraitsPrinter : public FunctionPass { | |||
public: | ||||
DOTGraphTraitsPrinter(StringRef GraphName, char &ID) | ||||
: FunctionPass(ID), Name(GraphName) {} | ||||
virtual bool runOnFunction(Function &F) { | ||||
Analysis *Graph = &getAnalysis<Analysis>(); | ||||
std::string Filename = Name + "." + F.getName().str() + ".dot"; | ||||
std::string ErrorInfo; | ||||
errs() << "Writing '" << Filename << "'..."; | ||||
raw_fd_ostream File(Filename.c_str(), ErrorInfo); | ||||
std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); | ||||
std::string Title = GraphName + " for '" + F.getName().str() + "' funct | ||||
ion"; | ||||
if (ErrorInfo.empty()) | ||||
WriteGraph(File, Graph, Simple, Title); | ||||
else | ||||
errs() << " error opening file for writing!"; | ||||
errs() << "\n"; | ||||
return false; | ||||
} | ||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const { | ||||
AU.setPreservesAll(); | ||||
AU.addRequired<Analysis>(); | ||||
} | ||||
private: | ||||
std::string Name; | std::string Name; | |||
}; | ||||
template <class Analysis, bool Simple> | ||||
class DOTGraphTraitsModuleViewer : public ModulePass { | ||||
public: | ||||
DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID) | ||||
: ModulePass(ID), Name(GraphName) {} | ||||
virtual bool runOnModule(Module &M) { | ||||
Analysis *Graph = &getAnalysis<Analysis>(); | ||||
std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph); | ||||
ViewGraph(Graph, Name, Simple, Title); | ||||
DOTGraphTraitsPrinter(std::string GraphName, char &ID) | return false; | |||
: FunctionPass(ID) { | ||||
Name = GraphName; | ||||
} | } | |||
virtual bool runOnFunction(Function &F) { | virtual void getAnalysisUsage(AnalysisUsage &AU) const { | |||
Analysis *Graph; | AU.setPreservesAll(); | |||
std::string Filename = Name + "." + F.getName().str() + ".dot"; | AU.addRequired<Analysis>(); | |||
errs() << "Writing '" << Filename << "'..."; | } | |||
private: | ||||
std::string Name; | ||||
}; | ||||
template <class Analysis, bool Simple> | ||||
class DOTGraphTraitsModulePrinter : public ModulePass { | ||||
public: | ||||
DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID) | ||||
: ModulePass(ID), Name(GraphName) {} | ||||
virtual bool runOnModule(Module &M) { | ||||
Analysis *Graph = &getAnalysis<Analysis>(); | ||||
std::string Filename = Name + ".dot"; | ||||
std::string ErrorInfo; | std::string ErrorInfo; | |||
raw_fd_ostream File(Filename.c_str(), ErrorInfo); | ||||
Graph = &getAnalysis<Analysis>(); | ||||
std::string Title, GraphName; | errs() << "Writing '" << Filename << "'..."; | |||
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); | ||||
Title = GraphName + " for '" + F.getName().str() + "' function"; | raw_fd_ostream File(Filename.c_str(), ErrorInfo); | |||
std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph); | ||||
if (ErrorInfo.empty()) | if (ErrorInfo.empty()) | |||
WriteGraph(File, Graph, Simple, Title); | WriteGraph(File, Graph, Simple, Title); | |||
else | else | |||
errs() << " error opening file for writing!"; | errs() << " error opening file for writing!"; | |||
errs() << "\n"; | errs() << "\n"; | |||
return false; | return false; | |||
} | } | |||
virtual void getAnalysisUsage(AnalysisUsage &AU) const { | virtual void getAnalysisUsage(AnalysisUsage &AU) const { | |||
AU.setPreservesAll(); | AU.setPreservesAll(); | |||
AU.addRequired<Analysis>(); | AU.addRequired<Analysis>(); | |||
} | } | |||
private: | ||||
std::string Name; | ||||
}; | }; | |||
} | ||||
} // end namespace llvm | ||||
#endif | #endif | |||
End of changes. 18 change blocks. | ||||
29 lines changed or deleted | 89 lines changed or added | |||
DataExtractor.h | DataExtractor.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
#define LLVM_SUPPORT_DATAEXTRACTOR_H | #define LLVM_SUPPORT_DATAEXTRACTOR_H | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
class DataExtractor { | class DataExtractor { | |||
StringRef Data; | StringRef Data; | |||
uint8_t IsLittleEndian; | uint8_t IsLittleEndian; | |||
uint8_t PointerSize; | uint8_t AddressSize; | |||
public: | public: | |||
/// Construct with a buffer that is owned by the caller. | /// Construct with a buffer that is owned by the caller. | |||
/// | /// | |||
/// This constructor allows us to use data that is owned by the | /// This constructor allows us to use data that is owned by the | |||
/// caller. The data must stay around as long as this object is | /// caller. The data must stay around as long as this object is | |||
/// valid. | /// valid. | |||
DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t PointerSize) | DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize) | |||
: Data(Data), IsLittleEndian(IsLittleEndian), PointerSize(PointerSize) | : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) | |||
{} | {} | |||
/// getData - Get the data pointed to by this extractor. | /// \brief Get the data pointed to by this extractor. | |||
StringRef getData() const { return Data; } | StringRef getData() const { return Data; } | |||
/// isLittleEndian - Get the endianess for this extractor. | /// \brief Get the endianess for this extractor. | |||
bool isLittleEndian() const { return IsLittleEndian; } | bool isLittleEndian() const { return IsLittleEndian; } | |||
/// getAddressSize - Get the address size for this extractor. | /// \brief Get the address size for this extractor. | |||
uint8_t getAddressSize() const { return PointerSize; } | uint8_t getAddressSize() const { return AddressSize; } | |||
/// \brief Set the address size for this extractor. | ||||
void setAddressSize(uint8_t Size) { AddressSize = Size; } | ||||
/// Extract a C string from \a *offset_ptr. | /// Extract a C string from \a *offset_ptr. | |||
/// | /// | |||
/// Returns a pointer to a C String from the data at the offset | /// Returns a pointer to a C String from the data at the offset | |||
/// pointed to by \a offset_ptr. A variable length NULL terminated C | /// pointed to by \a offset_ptr. A variable length NULL terminated C | |||
/// string will be extracted and the \a offset_ptr will be | /// string will be extracted and the \a offset_ptr will be | |||
/// updated with the offset of the byte that follows the NULL | /// updated with the offset of the byte that follows the NULL | |||
/// terminator byte. | /// terminator byte. | |||
/// | /// | |||
/// @param[in,out] offset_ptr | /// @param[in,out] offset_ptr | |||
skipping to change at line 116 | skipping to change at line 118 | |||
/// @return | /// @return | |||
/// The sign extended signed integer value that was extracted, | /// The sign extended signed integer value that was extracted, | |||
/// or zero on failure. | /// or zero on failure. | |||
int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const; | int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const; | |||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | |||
/// Extract an pointer from \a *offset_ptr. | /// Extract an pointer from \a *offset_ptr. | |||
/// | /// | |||
/// Extract a single pointer from the data and update the offset | /// Extract a single pointer from the data and update the offset | |||
/// pointed to by \a offset_ptr. The size of the extracted pointer | /// pointed to by \a offset_ptr. The size of the extracted pointer | |||
/// comes from the \a m_addr_size member variable and should be | /// is \a getAddressSize(), so the address size has to be | |||
/// set correctly prior to extracting any pointer values. | /// set correctly prior to extracting any pointer values. | |||
/// | /// | |||
/// @param[in,out] offset_ptr | /// @param[in,out] offset_ptr | |||
/// A pointer to an offset within the data that will be advanced | /// A pointer to an offset within the data that will be advanced | |||
/// by the appropriate number of bytes if the value is extracted | /// by the appropriate number of bytes if the value is extracted | |||
/// correctly. If the offset is out of bounds or there are not | /// correctly. If the offset is out of bounds or there are not | |||
/// enough bytes to extract this value, the offset will be left | /// enough bytes to extract this value, the offset will be left | |||
/// unmodified. | /// unmodified. | |||
/// | /// | |||
/// @return | /// @return | |||
/// The extracted pointer value as a 64 integer. | /// The extracted pointer value as a 64 integer. | |||
uint64_t getAddress(uint32_t *offset_ptr) const { | uint64_t getAddress(uint32_t *offset_ptr) const { | |||
return getUnsigned(offset_ptr, PointerSize); | return getUnsigned(offset_ptr, AddressSize); | |||
} | } | |||
/// Extract a uint8_t value from \a *offset_ptr. | /// Extract a uint8_t value from \a *offset_ptr. | |||
/// | /// | |||
/// Extract a single uint8_t from the binary data at the offset | /// Extract a single uint8_t from the binary data at the offset | |||
/// pointed to by \a offset_ptr, and advance the offset on success. | /// pointed to by \a offset_ptr, and advance the offset on success. | |||
/// | /// | |||
/// @param[in,out] offset_ptr | /// @param[in,out] offset_ptr | |||
/// A pointer to an offset within the data that will be advanced | /// A pointer to an offset within the data that will be advanced | |||
/// by the appropriate number of bytes if the value is extracted | /// by the appropriate number of bytes if the value is extracted | |||
End of changes. 7 change blocks. | ||||
10 lines changed or deleted | 12 lines changed or added | |||
DataFlow.h | DataFlow.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines specializations of GraphTraits that allows Use-Def and | // This file defines specializations of GraphTraits that allows Use-Def and | |||
// Def-Use relations to be treated as proper graphs for generic algorithms. | // Def-Use relations to be treated as proper graphs for generic algorithms. | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_DATAFLOW_H | #ifndef LLVM_SUPPORT_DATAFLOW_H | |||
#define LLVM_SUPPORT_DATAFLOW_H | #define LLVM_SUPPORT_DATAFLOW_H | |||
#include "llvm/User.h" | ||||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/IR/User.h" | ||||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Provide specializations of GraphTraits to be able to treat def-use/use-d ef | // Provide specializations of GraphTraits to be able to treat def-use/use-d ef | |||
// chains as graphs | // chains as graphs | |||
template <> struct GraphTraits<const Value*> { | template <> struct GraphTraits<const Value*> { | |||
typedef const Value NodeType; | typedef const Value NodeType; | |||
typedef Value::const_use_iterator ChildIteratorType; | typedef Value::const_use_iterator ChildIteratorType; | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
DataLayout.h | DataLayout.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file defines layout properties related to datatype size/offset/alig nment | // This file defines layout properties related to datatype size/offset/alig nment | |||
// information. It uses lazy annotations to cache information about how | // information. It uses lazy annotations to cache information about how | |||
// structure types are laid out and used. | // structure types are laid out and used. | |||
// | // | |||
// This structure should be created once, filled in if the defaults are not | // This structure should be created once, filled in if the defaults are not | |||
// correct and then passed around by const&. None of the members functions | // correct and then passed around by const&. None of the members functions | |||
// require modification to the object. | // require modification to the object. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_DATALAYOUT_H | #ifndef LLVM_IR_DATALAYOUT_H | |||
#define LLVM_DATALAYOUT_H | #define LLVM_IR_DATALAYOUT_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/IR/DerivedTypes.h" | ||||
#include "llvm/IR/Type.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
class Value; | class Value; | |||
class Type; | class Type; | |||
class IntegerType; | class IntegerType; | |||
class StructType; | class StructType; | |||
class StructLayout; | class StructLayout; | |||
class GlobalVariable; | class GlobalVariable; | |||
class LLVMContext; | class LLVMContext; | |||
template<typename T> | template<typename T> | |||
class ArrayRef; | class ArrayRef; | |||
/// Enum used to categorize the alignment types stored by LayoutAlignElem | /// Enum used to categorize the alignment types stored by LayoutAlignElem | |||
enum AlignTypeEnum { | enum AlignTypeEnum { | |||
INVALID_ALIGN = 0, ///< An invalid alignment | ||||
INTEGER_ALIGN = 'i', ///< Integer type alignment | INTEGER_ALIGN = 'i', ///< Integer type alignment | |||
VECTOR_ALIGN = 'v', ///< Vector type alignment | VECTOR_ALIGN = 'v', ///< Vector type alignment | |||
FLOAT_ALIGN = 'f', ///< Floating point type alignment | FLOAT_ALIGN = 'f', ///< Floating point type alignment | |||
AGGREGATE_ALIGN = 'a', ///< Aggregate alignment | AGGREGATE_ALIGN = 'a', ///< Aggregate alignment | |||
STACK_ALIGN = 's' ///< Stack objects alignment | STACK_ALIGN = 's' ///< Stack objects alignment | |||
}; | }; | |||
/// Layout alignment element. | /// Layout alignment element. | |||
/// | /// | |||
/// Stores the alignment data associated with a given alignment type (integ er, | /// Stores the alignment data associated with a given alignment type (integ er, | |||
skipping to change at line 101 | skipping to change at line 104 | |||
/// is required to generate the right target data for the target being code gen'd | /// is required to generate the right target data for the target being code gen'd | |||
/// to. If some measure of portability is desired, an empty string may be | /// to. If some measure of portability is desired, an empty string may be | |||
/// specified in the module. | /// specified in the module. | |||
class DataLayout : public ImmutablePass { | class DataLayout : public ImmutablePass { | |||
private: | private: | |||
bool LittleEndian; ///< Defaults to false | bool LittleEndian; ///< Defaults to false | |||
unsigned StackNaturalAlign; ///< Stack natural alignment | unsigned StackNaturalAlign; ///< Stack natural alignment | |||
SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers. | SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers. | |||
/// Alignments- Where the primitive type alignment data is stored. | /// Alignments - Where the primitive type alignment data is stored. | |||
/// | /// | |||
/// @sa init(). | /// @sa init(). | |||
/// @note Could support multiple size pointer alignments, e.g., 32-bit | /// @note Could support multiple size pointer alignments, e.g., 32-bit | |||
/// pointers vs. 64-bit pointers by extending LayoutAlignment, but for no w, | /// pointers vs. 64-bit pointers by extending LayoutAlignment, but for no w, | |||
/// we don't. | /// we don't. | |||
SmallVector<LayoutAlignElem, 16> Alignments; | SmallVector<LayoutAlignElem, 16> Alignments; | |||
DenseMap<unsigned, PointerAlignElem> Pointers; | DenseMap<unsigned, PointerAlignElem> Pointers; | |||
/// InvalidAlignmentElem - This member is a signal that a requested align ment | /// InvalidAlignmentElem - This member is a signal that a requested align ment | |||
/// type and bit width were not found in the SmallVector. | /// type and bit width were not found in the SmallVector. | |||
skipping to change at line 150 | skipping to change at line 153 | |||
} | } | |||
/// Valid pointer predicate. | /// Valid pointer predicate. | |||
/// | /// | |||
/// Predicate that tests a PointerAlignElem reference returned by get() a gainst | /// Predicate that tests a PointerAlignElem reference returned by get() a gainst | |||
/// InvalidPointerElem. | /// InvalidPointerElem. | |||
bool validPointer(const PointerAlignElem &align) const { | bool validPointer(const PointerAlignElem &align) const { | |||
return &align != &InvalidPointerElem; | return &align != &InvalidPointerElem; | |||
} | } | |||
/// Initialise a DataLayout object with default values, ensure that the | /// Parses a target data specification string. Assert if the string is | |||
/// target data pass is registered. | /// malformed. | |||
void init(); | void parseSpecifier(StringRef LayoutDescription); | |||
public: | public: | |||
/// Default ctor. | /// Default ctor. | |||
/// | /// | |||
/// @note This has to exist, because this is a pass, but it should never be | /// @note This has to exist, because this is a pass, but it should never be | |||
/// used. | /// used. | |||
DataLayout(); | DataLayout(); | |||
/// Constructs a DataLayout from a specification string. See init(). | /// Constructs a DataLayout from a specification string. See init(). | |||
explicit DataLayout(StringRef LayoutDescription) | explicit DataLayout(StringRef LayoutDescription) | |||
: ImmutablePass(ID) { | : ImmutablePass(ID) { | |||
std::string errMsg = parseSpecifier(LayoutDescription, this); | init(LayoutDescription); | |||
assert(errMsg == "" && "Invalid target data layout string."); | ||||
(void)errMsg; | ||||
} | } | |||
/// Parses a target data specification string. Returns an error message | ||||
/// if the string is malformed, or the empty string on success. Optionall | ||||
y | ||||
/// initialises a DataLayout object if passed a non-null pointer. | ||||
static std::string parseSpecifier(StringRef LayoutDescription, | ||||
DataLayout* td = 0); | ||||
/// Initialize target data from properties stored in the module. | /// Initialize target data from properties stored in the module. | |||
explicit DataLayout(const Module *M); | explicit DataLayout(const Module *M); | |||
DataLayout(const DataLayout &TD) : | DataLayout(const DataLayout &DL) : | |||
ImmutablePass(ID), | ImmutablePass(ID), | |||
LittleEndian(TD.isLittleEndian()), | LittleEndian(DL.isLittleEndian()), | |||
LegalIntWidths(TD.LegalIntWidths), | StackNaturalAlign(DL.StackNaturalAlign), | |||
Alignments(TD.Alignments), | LegalIntWidths(DL.LegalIntWidths), | |||
Pointers(TD.Pointers), | Alignments(DL.Alignments), | |||
Pointers(DL.Pointers), | ||||
LayoutMap(0) | LayoutMap(0) | |||
{ } | { } | |||
~DataLayout(); // Not virtual, do not subclass this class | ~DataLayout(); // Not virtual, do not subclass this class | |||
/// DataLayout is an immutable pass, but holds state. This allows the pa | ||||
ss | ||||
/// manager to clear its mutable state. | ||||
bool doFinalization(Module &M); | ||||
/// Parse a data layout string (with fallback to default values). Ensure | ||||
that | ||||
/// the data layout pass is registered. | ||||
void init(StringRef LayoutDescription); | ||||
/// Layout endianness... | /// Layout endianness... | |||
bool isLittleEndian() const { return LittleEndian; } | bool isLittleEndian() const { return LittleEndian; } | |||
bool isBigEndian() const { return !LittleEndian; } | bool isBigEndian() const { return !LittleEndian; } | |||
/// getStringRepresentation - Return the string representation of the | /// getStringRepresentation - Return the string representation of the | |||
/// DataLayout. This representation is in the same format accepted by th e | /// DataLayout. This representation is in the same format accepted by th e | |||
/// string constructor above. | /// string constructor above. | |||
std::string getStringRepresentation() const; | std::string getStringRepresentation() const; | |||
/// isLegalInteger - This function returns true if the specified type is | /// isLegalInteger - This function returns true if the specified type is | |||
skipping to change at line 287 | skipping to change at line 291 | |||
/// i128 128 128 128 | /// i128 128 128 128 | |||
/// Float 32 32 32 | /// Float 32 32 32 | |||
/// Double 64 64 64 | /// Double 64 64 64 | |||
/// X86_FP80 80 80 96 | /// X86_FP80 80 80 96 | |||
/// | /// | |||
/// [*] The alloc size depends on the alignment, and thus on the target. | /// [*] The alloc size depends on the alignment, and thus on the target. | |||
/// These values are for x86-32 linux. | /// These values are for x86-32 linux. | |||
/// getTypeSizeInBits - Return the number of bits necessary to hold the | /// getTypeSizeInBits - Return the number of bits necessary to hold the | |||
/// specified type. For example, returns 36 for i36 and 80 for x86_fp80. | /// specified type. For example, returns 36 for i36 and 80 for x86_fp80. | |||
uint64_t getTypeSizeInBits(Type* Ty) const; | /// The type passed must have a size (Type::isSized() must return true). | |||
uint64_t getTypeSizeInBits(Type *Ty) const; | ||||
/// getTypeStoreSize - Return the maximum number of bytes that may be | /// getTypeStoreSize - Return the maximum number of bytes that may be | |||
/// overwritten by storing the specified type. For example, returns 5 | /// overwritten by storing the specified type. For example, returns 5 | |||
/// for i36 and 10 for x86_fp80. | /// for i36 and 10 for x86_fp80. | |||
uint64_t getTypeStoreSize(Type *Ty) const { | uint64_t getTypeStoreSize(Type *Ty) const { | |||
return (getTypeSizeInBits(Ty)+7)/8; | return (getTypeSizeInBits(Ty)+7)/8; | |||
} | } | |||
/// getTypeStoreSizeInBits - Return the maximum number of bits that may b e | /// getTypeStoreSizeInBits - Return the maximum number of bits that may b e | |||
/// overwritten by storing the specified type; always a multiple of 8. F or | /// overwritten by storing the specified type; always a multiple of 8. F or | |||
/// example, returns 40 for i36 and 80 for x86_fp80. | /// example, returns 40 for i36 and 80 for x86_fp80. | |||
uint64_t getTypeStoreSizeInBits(Type *Ty) const { | uint64_t getTypeStoreSizeInBits(Type *Ty) const { | |||
return 8*getTypeStoreSize(Ty); | return 8*getTypeStoreSize(Ty); | |||
} | } | |||
/// getTypeAllocSize - Return the offset in bytes between successive obje cts | /// getTypeAllocSize - Return the offset in bytes between successive obje cts | |||
/// of the specified type, including alignment padding. This is the amou nt | /// of the specified type, including alignment padding. This is the amou nt | |||
/// that alloca reserves for this type. For example, returns 12 or 16 fo r | /// that alloca reserves for this type. For example, returns 12 or 16 fo r | |||
/// x86_fp80, depending on alignment. | /// x86_fp80, depending on alignment. | |||
uint64_t getTypeAllocSize(Type* Ty) const { | uint64_t getTypeAllocSize(Type *Ty) const { | |||
// Round up to the next alignment boundary. | // Round up to the next alignment boundary. | |||
return RoundUpAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty)); | return RoundUpAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty)); | |||
} | } | |||
/// getTypeAllocSizeInBits - Return the offset in bits between successive | /// getTypeAllocSizeInBits - Return the offset in bits between successive | |||
/// objects of the specified type, including alignment padding; always a | /// objects of the specified type, including alignment padding; always a | |||
/// multiple of 8. This is the amount that alloca reserves for this type . | /// multiple of 8. This is the amount that alloca reserves for this type . | |||
/// For example, returns 96 or 128 for x86_fp80, depending on alignment. | /// For example, returns 96 or 128 for x86_fp80, depending on alignment. | |||
uint64_t getTypeAllocSizeInBits(Type* Ty) const { | uint64_t getTypeAllocSizeInBits(Type *Ty) const { | |||
return 8*getTypeAllocSize(Ty); | return 8*getTypeAllocSize(Ty); | |||
} | } | |||
/// getABITypeAlignment - Return the minimum ABI-required alignment for t he | /// getABITypeAlignment - Return the minimum ABI-required alignment for t he | |||
/// specified type. | /// specified type. | |||
unsigned getABITypeAlignment(Type *Ty) const; | unsigned getABITypeAlignment(Type *Ty) const; | |||
/// getABIIntegerTypeAlignment - Return the minimum ABI-required alignmen t for | /// getABIIntegerTypeAlignment - Return the minimum ABI-required alignmen t for | |||
/// an integer type of the specified bitwidth. | /// an integer type of the specified bitwidth. | |||
unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const; | unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const; | |||
skipping to change at line 338 | skipping to change at line 343 | |||
/// getCallFrameTypeAlignment - Return the minimum ABI-required alignment | /// getCallFrameTypeAlignment - Return the minimum ABI-required alignment | |||
/// for the specified type when it is part of a call frame. | /// for the specified type when it is part of a call frame. | |||
unsigned getCallFrameTypeAlignment(Type *Ty) const; | unsigned getCallFrameTypeAlignment(Type *Ty) const; | |||
/// getPrefTypeAlignment - Return the preferred stack/global alignment fo r | /// getPrefTypeAlignment - Return the preferred stack/global alignment fo r | |||
/// the specified type. This is always at least as good as the ABI align ment. | /// the specified type. This is always at least as good as the ABI align ment. | |||
unsigned getPrefTypeAlignment(Type *Ty) const; | unsigned getPrefTypeAlignment(Type *Ty) const; | |||
/// getPreferredTypeAlignmentShift - Return the preferred alignment for t he | /// getPreferredTypeAlignmentShift - Return the preferred alignment for t he | |||
/// specified type, returned as log2 of the value (a shift amount). | /// specified type, returned as log2 of the value (a shift amount). | |||
/// | ||||
unsigned getPreferredTypeAlignmentShift(Type *Ty) const; | unsigned getPreferredTypeAlignmentShift(Type *Ty) const; | |||
/// getIntPtrType - Return an integer type with size at least as big as t hat | /// getIntPtrType - Return an integer type with size at least as big as t hat | |||
/// of a pointer in the given address space. | /// of a pointer in the given address space. | |||
IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) con st; | IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) con st; | |||
/// getIntPtrType - Return an integer (vector of integer) type with size at | /// getIntPtrType - Return an integer (vector of integer) type with size at | |||
/// least as big as that of a pointer of the given pointer (vector of poi nter) | /// least as big as that of a pointer of the given pointer (vector of poi nter) | |||
/// type. | /// type. | |||
Type *getIntPtrType(Type *) const; | Type *getIntPtrType(Type *) const; | |||
/// getSmallestLegalIntType - Return the smallest integer type with size | ||||
at | ||||
/// least as big as Width bits. | ||||
Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const; | ||||
/// getIndexedOffset - return the offset from the beginning of the type f or | /// getIndexedOffset - return the offset from the beginning of the type f or | |||
/// the specified indices. This is used to implement getelementptr. | /// the specified indices. This is used to implement getelementptr. | |||
/// | ||||
uint64_t getIndexedOffset(Type *Ty, ArrayRef<Value *> Indices) const; | uint64_t getIndexedOffset(Type *Ty, ArrayRef<Value *> Indices) const; | |||
/// getStructLayout - Return a StructLayout object, indicating the alignm ent | /// getStructLayout - Return a StructLayout object, indicating the alignm ent | |||
/// of the struct, its size, and the offsets of its fields. Note that th is | /// of the struct, its size, and the offsets of its fields. Note that th is | |||
/// information is lazily cached. | /// information is lazily cached. | |||
const StructLayout *getStructLayout(StructType *Ty) const; | const StructLayout *getStructLayout(StructType *Ty) const; | |||
/// getPreferredAlignment - Return the preferred alignment of the specifi ed | /// getPreferredAlignment - Return the preferred alignment of the specifi ed | |||
/// global. This includes an explicitly requested alignment (if the glob al | /// global. This includes an explicitly requested alignment (if the glob al | |||
/// has one). | /// has one). | |||
skipping to change at line 421 | skipping to change at line 428 | |||
assert(Idx < NumElements && "Invalid element idx!"); | assert(Idx < NumElements && "Invalid element idx!"); | |||
return MemberOffsets[Idx]; | return MemberOffsets[Idx]; | |||
} | } | |||
uint64_t getElementOffsetInBits(unsigned Idx) const { | uint64_t getElementOffsetInBits(unsigned Idx) const { | |||
return getElementOffset(Idx)*8; | return getElementOffset(Idx)*8; | |||
} | } | |||
private: | private: | |||
friend class DataLayout; // Only DataLayout can create this class | friend class DataLayout; // Only DataLayout can create this class | |||
StructLayout(StructType *ST, const DataLayout &TD); | StructLayout(StructType *ST, const DataLayout &DL); | |||
}; | }; | |||
// The implementation of this method is provided inline as it is particular | ||||
ly | ||||
// well suited to constant folding when called on a specific Type subclass. | ||||
inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const { | ||||
assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!" | ||||
); | ||||
switch (Ty->getTypeID()) { | ||||
case Type::LabelTyID: | ||||
return getPointerSizeInBits(0); | ||||
case Type::PointerTyID: | ||||
return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace()); | ||||
case Type::ArrayTyID: { | ||||
ArrayType *ATy = cast<ArrayType>(Ty); | ||||
return ATy->getNumElements() * | ||||
getTypeAllocSizeInBits(ATy->getElementType()); | ||||
} | ||||
case Type::StructTyID: | ||||
// Get the layout annotation... which is lazily created on demand. | ||||
return getStructLayout(cast<StructType>(Ty))->getSizeInBits(); | ||||
case Type::IntegerTyID: | ||||
return cast<IntegerType>(Ty)->getBitWidth(); | ||||
case Type::HalfTyID: | ||||
return 16; | ||||
case Type::FloatTyID: | ||||
return 32; | ||||
case Type::DoubleTyID: | ||||
case Type::X86_MMXTyID: | ||||
return 64; | ||||
case Type::PPC_FP128TyID: | ||||
case Type::FP128TyID: | ||||
return 128; | ||||
// In memory objects this is always aligned to a higher boundary, but | ||||
// only 80 bits contain information. | ||||
case Type::X86_FP80TyID: | ||||
return 80; | ||||
case Type::VectorTyID: { | ||||
VectorType *VTy = cast<VectorType>(Ty); | ||||
return VTy->getNumElements() * getTypeSizeInBits(VTy->getElementType()) | ||||
; | ||||
} | ||||
default: | ||||
llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type"); | ||||
} | ||||
} | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 19 change blocks. | ||||
29 lines changed or deleted | 83 lines changed or added | |||
DataStream.h | DataStream.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This header defines DataStreamer, which fetches bytes of data from | // This header defines DataStreamer, which fetches bytes of data from | |||
// a stream source. It provides support for streaming (lazy reading) of | // a stream source. It provides support for streaming (lazy reading) of | |||
// data, e.g. bitcode | // data, e.g. bitcode | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_DATASTREAM_H_ | #ifndef LLVM_SUPPORT_DATASTREAM_H | |||
#define LLVM_SUPPORT_DATASTREAM_H_ | #define LLVM_SUPPORT_DATASTREAM_H | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class DataStreamer { | class DataStreamer { | |||
public: | public: | |||
/// Fetch bytes [start-end) from the stream, and write them to the | /// Fetch bytes [start-end) from the stream, and write them to the | |||
/// buffer pointed to by buf. Returns the number of bytes actually writte n. | /// buffer pointed to by buf. Returns the number of bytes actually writte n. | |||
virtual size_t GetBytes(unsigned char *buf, size_t len) = 0; | virtual size_t GetBytes(unsigned char *buf, size_t len) = 0; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
DebugInfo.h | DebugInfo.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines a bunch of datatypes that are useful for creating and | // This file defines a bunch of datatypes that are useful for creating and | |||
// walking debug info in LLVM IR form. They essentially provide wrappers ar ound | // walking debug info in LLVM IR form. They essentially provide wrappers ar ound | |||
// the information in the global variables that's needed when constructing the | // the information in the global variables that's needed when constructing the | |||
// DWARF information. | // DWARF information. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_DEBUGINFO_H | #ifndef LLVM_DEBUGINFO_H | |||
#define LLVM_ANALYSIS_DEBUGINFO_H | #define LLVM_DEBUGINFO_H | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/Dwarf.h" | #include "llvm/Support/Dwarf.h" | |||
namespace llvm { | namespace llvm { | |||
class BasicBlock; | class BasicBlock; | |||
class Constant; | class Constant; | |||
class Function; | class Function; | |||
class GlobalVariable; | class GlobalVariable; | |||
class Module; | class Module; | |||
class Type; | class Type; | |||
skipping to change at line 64 | skipping to change at line 64 | |||
FlagPrivate = 1 << 0, | FlagPrivate = 1 << 0, | |||
FlagProtected = 1 << 1, | FlagProtected = 1 << 1, | |||
FlagFwdDecl = 1 << 2, | FlagFwdDecl = 1 << 2, | |||
FlagAppleBlock = 1 << 3, | FlagAppleBlock = 1 << 3, | |||
FlagBlockByrefStruct = 1 << 4, | FlagBlockByrefStruct = 1 << 4, | |||
FlagVirtual = 1 << 5, | FlagVirtual = 1 << 5, | |||
FlagArtificial = 1 << 6, | FlagArtificial = 1 << 6, | |||
FlagExplicit = 1 << 7, | FlagExplicit = 1 << 7, | |||
FlagPrototyped = 1 << 8, | FlagPrototyped = 1 << 8, | |||
FlagObjcClassComplete = 1 << 9, | FlagObjcClassComplete = 1 << 9, | |||
FlagObjectPointer = 1 << 10 | FlagObjectPointer = 1 << 10, | |||
FlagVector = 1 << 11, | ||||
FlagStaticMember = 1 << 12 | ||||
}; | }; | |||
protected: | protected: | |||
const MDNode *DbgNode; | const MDNode *DbgNode; | |||
StringRef getStringField(unsigned Elt) const; | StringRef getStringField(unsigned Elt) const; | |||
unsigned getUnsignedField(unsigned Elt) const { | unsigned getUnsignedField(unsigned Elt) const { | |||
return (unsigned)getUInt64Field(Elt); | return (unsigned)getUInt64Field(Elt); | |||
} | } | |||
uint64_t getUInt64Field(unsigned Elt) const; | uint64_t getUInt64Field(unsigned Elt) const; | |||
int64_t getInt64Field(unsigned Elt) const; | ||||
DIDescriptor getDescriptorField(unsigned Elt) const; | DIDescriptor getDescriptorField(unsigned Elt) const; | |||
template <typename DescTy> | template <typename DescTy> | |||
DescTy getFieldAs(unsigned Elt) const { | DescTy getFieldAs(unsigned Elt) const { | |||
return DescTy(getDescriptorField(Elt)); | return DescTy(getDescriptorField(Elt)); | |||
} | } | |||
GlobalVariable *getGlobalVariableField(unsigned Elt) const; | GlobalVariable *getGlobalVariableField(unsigned Elt) const; | |||
Constant *getConstantField(unsigned Elt) const; | Constant *getConstantField(unsigned Elt) const; | |||
Function *getFunctionField(unsigned Elt) const; | Function *getFunctionField(unsigned Elt) const; | |||
skipping to change at line 96 | skipping to change at line 99 | |||
public: | public: | |||
explicit DIDescriptor() : DbgNode(0) {} | explicit DIDescriptor() : DbgNode(0) {} | |||
explicit DIDescriptor(const MDNode *N) : DbgNode(N) {} | explicit DIDescriptor(const MDNode *N) : DbgNode(N) {} | |||
explicit DIDescriptor(const DIFile F); | explicit DIDescriptor(const DIFile F); | |||
explicit DIDescriptor(const DISubprogram F); | explicit DIDescriptor(const DISubprogram F); | |||
explicit DIDescriptor(const DILexicalBlockFile F); | explicit DIDescriptor(const DILexicalBlockFile F); | |||
explicit DIDescriptor(const DILexicalBlock F); | explicit DIDescriptor(const DILexicalBlock F); | |||
explicit DIDescriptor(const DIVariable F); | explicit DIDescriptor(const DIVariable F); | |||
explicit DIDescriptor(const DIType F); | explicit DIDescriptor(const DIType F); | |||
bool Verify() const { return DbgNode != 0; } | bool Verify() const; | |||
operator MDNode *() const { return const_cast<MDNode*>(DbgNode); } | operator MDNode *() const { return const_cast<MDNode*>(DbgNode); } | |||
MDNode *operator ->() const { return const_cast<MDNode*>(DbgNode); } | MDNode *operator ->() const { return const_cast<MDNode*>(DbgNode); } | |||
unsigned getVersion() const { | ||||
return getUnsignedField(0) & LLVMDebugVersionMask; | ||||
} | ||||
unsigned getTag() const { | unsigned getTag() const { | |||
return getUnsignedField(0) & ~LLVMDebugVersionMask; | return getUnsignedField(0) & ~LLVMDebugVersionMask; | |||
} | } | |||
bool isDerivedType() const; | bool isDerivedType() const; | |||
bool isCompositeType() const; | bool isCompositeType() const; | |||
bool isBasicType() const; | bool isBasicType() const; | |||
bool isVariable() const; | bool isVariable() const; | |||
bool isSubprogram() const; | bool isSubprogram() const; | |||
bool isGlobalVariable() const; | bool isGlobalVariable() const; | |||
skipping to change at line 129 | skipping to change at line 128 | |||
bool isLexicalBlockFile() const; | bool isLexicalBlockFile() const; | |||
bool isLexicalBlock() const; | bool isLexicalBlock() const; | |||
bool isSubrange() const; | bool isSubrange() const; | |||
bool isEnumerator() const; | bool isEnumerator() const; | |||
bool isType() const; | bool isType() const; | |||
bool isGlobal() const; | bool isGlobal() const; | |||
bool isUnspecifiedParameter() const; | bool isUnspecifiedParameter() const; | |||
bool isTemplateTypeParameter() const; | bool isTemplateTypeParameter() const; | |||
bool isTemplateValueParameter() const; | bool isTemplateValueParameter() const; | |||
bool isObjCProperty() const; | bool isObjCProperty() const; | |||
bool isImportedModule() const; | ||||
/// print - print descriptor. | /// print - print descriptor. | |||
void print(raw_ostream &OS) const; | void print(raw_ostream &OS) const; | |||
/// dump - print descriptor to dbgs() with a newline. | /// dump - print descriptor to dbgs() with a newline. | |||
void dump() const; | void dump() const; | |||
}; | }; | |||
/// DISubrange - This is used to represent ranges, for array bounds. | /// DISubrange - This is used to represent ranges, for array bounds. | |||
class DISubrange : public DIDescriptor { | class DISubrange : public DIDescriptor { | |||
friend class DIDescriptor; | friend class DIDescriptor; | |||
void printInternal(raw_ostream &OS) const; | void printInternal(raw_ostream &OS) const; | |||
public: | public: | |||
explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {} | explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {} | |||
uint64_t getLo() const { return getUInt64Field(1); } | int64_t getLo() const { return getInt64Field(1); } | |||
uint64_t getHi() const { return getUInt64Field(2); } | int64_t getCount() const { return getInt64Field(2); } | |||
bool Verify() const; | ||||
}; | }; | |||
/// DIArray - This descriptor holds an array of descriptors. | /// DIArray - This descriptor holds an array of descriptors. | |||
class DIArray : public DIDescriptor { | class DIArray : public DIDescriptor { | |||
public: | public: | |||
explicit DIArray(const MDNode *N = 0) | explicit DIArray(const MDNode *N = 0) | |||
: DIDescriptor(N) {} | : DIDescriptor(N) {} | |||
unsigned getNumElements() const; | unsigned getNumElements() const; | |||
DIDescriptor getElement(unsigned Idx) const { | DIDescriptor getElement(unsigned Idx) const { | |||
skipping to change at line 172 | skipping to change at line 173 | |||
protected: | protected: | |||
friend class DIDescriptor; | friend class DIDescriptor; | |||
void printInternal(raw_ostream &OS) const; | void printInternal(raw_ostream &OS) const; | |||
public: | public: | |||
explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {} | explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {} | |||
StringRef getFilename() const; | StringRef getFilename() const; | |||
StringRef getDirectory() 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. | /// DICompileUnit - A wrapper for a compile unit. | |||
class DICompileUnit : public DIScope { | class DICompileUnit : public DIScope { | |||
friend class DIDescriptor; | friend class DIDescriptor; | |||
void printInternal(raw_ostream &OS) const; | void printInternal(raw_ostream &OS) const; | |||
public: | public: | |||
explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {} | explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {} | |||
unsigned getLanguage() const { return getUnsignedField(2); } | unsigned getLanguage() const { return getUnsignedField(2); } | |||
StringRef getFilename() const { return getStringField(3); } | StringRef getProducer() const { return getStringField(3); } | |||
StringRef getDirectory() const { return getStringField(4); } | ||||
StringRef getProducer() const { return getStringField(5); } | bool isOptimized() const { return getUnsignedField(4) != 0; } | |||
StringRef getFlags() const { return getStringField(5); } | ||||
/// isMain - Each input file is encoded as a separate compile unit in L | unsigned getRunTimeVersion() const { return getUnsignedField(6); } | |||
LVM | ||||
/// debugging information output. However, many target specific tool ch | ||||
ains | ||||
/// prefer to encode only one compile unit in an object file. In this | ||||
/// situation, the LLVM code generator will include debugging informat | ||||
ion | ||||
/// entities in the compile unit that is marked as main compile unit. T | ||||
he | ||||
/// code generator accepts maximum one main compile unit per module. If | ||||
a | ||||
/// module does not contain any main compile unit then the code generat | ||||
or | ||||
/// will emit multiple compile units in the output object file. | ||||
bool isMain() const { return getUnsignedField(6) != 0; } | ||||
bool isOptimized() const { return getUnsignedField(7) != 0; } | ||||
StringRef getFlags() const { return getStringField(8); } | ||||
unsigned getRunTimeVersion() const { return getUnsignedField(9); } | ||||
DIArray getEnumTypes() const; | DIArray getEnumTypes() const; | |||
DIArray getRetainedTypes() const; | DIArray getRetainedTypes() const; | |||
DIArray getSubprograms() const; | DIArray getSubprograms() const; | |||
DIArray getGlobalVariables() const; | DIArray getGlobalVariables() const; | |||
DIArray getImportedModules() const; | ||||
StringRef getSplitDebugFilename() const { return getStringField(12); } | ||||
/// Verify - Verify that a compile unit is well formed. | /// Verify - Verify that a compile unit is well formed. | |||
bool Verify() const; | bool Verify() const; | |||
}; | }; | |||
/// DIFile - This is a wrapper for a file. | ||||
class DIFile : public DIScope { | ||||
friend class DIDescriptor; | ||||
void printInternal(raw_ostream &OS) const {} // FIXME: Output something | ||||
? | ||||
public: | ||||
explicit DIFile(const MDNode *N = 0) : DIScope(N) { | ||||
if (DbgNode && !isFile()) | ||||
DbgNode = 0; | ||||
} | ||||
StringRef getFilename() const { return getStringField(1); } | ||||
StringRef getDirectory() const { return getStringField(2); } | ||||
DICompileUnit getCompileUnit() const{ | ||||
assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!" | ||||
); | ||||
return getFieldAs<DICompileUnit>(3); | ||||
} | ||||
}; | ||||
/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X, Y}'). | /// 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 | /// FIXME: it seems strange that this doesn't have either a reference to the | |||
/// type/precision or a file/line pair for location info. | /// type/precision or a file/line pair for location info. | |||
class DIEnumerator : public DIDescriptor { | class DIEnumerator : public DIDescriptor { | |||
friend class DIDescriptor; | friend class DIDescriptor; | |||
void printInternal(raw_ostream &OS) const; | void printInternal(raw_ostream &OS) const; | |||
public: | public: | |||
explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {} | explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {} | |||
StringRef getName() const { return getStringField(1); } | StringRef getName() const { return getStringField(1); } | |||
uint64_t getEnumValue() const { return getUInt64Field(2); } | uint64_t getEnumValue() const { return getUInt64Field(2); } | |||
bool Verify() const; | ||||
}; | }; | |||
/// DIType - This is a wrapper for a type. | /// DIType - This is a wrapper for a type. | |||
/// FIXME: Types should be factored much better so that CV qualifiers and | /// FIXME: Types should be factored much better so that CV qualifiers and | |||
/// others do not require a huge and empty descriptor full of zeros. | /// others do not require a huge and empty descriptor full of zeros. | |||
class DIType : public DIScope { | class DIType : public DIScope { | |||
protected: | protected: | |||
friend class DIDescriptor; | friend class DIDescriptor; | |||
void printInternal(raw_ostream &OS) const; | void printInternal(raw_ostream &OS) const; | |||
// This ctor is used when the Tag has already been validated by a deriv ed | // This ctor is used when the Tag has already been validated by a deriv ed | |||
// ctor. | // ctor. | |||
DIType(const MDNode *N, bool, bool) : DIScope(N) {} | DIType(const MDNode *N, bool, bool) : DIScope(N) {} | |||
public: | public: | |||
/// Verify - Verify that a type descriptor is well formed. | /// Verify - Verify that a type descriptor is well formed. | |||
bool Verify() const; | bool Verify() const; | |||
explicit DIType(const MDNode *N); | explicit DIType(const MDNode *N); | |||
explicit DIType() {} | explicit DIType() {} | |||
DIScope getContext() const { return getFieldAs<DIScope>(1); } | DIScope getContext() const { return getFieldAs<DIScope>(2); } | |||
StringRef getName() const { return getStringField(2); } | StringRef getName() const { return getStringField(3); } | |||
DICompileUnit getCompileUnit() const{ | ||||
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit | ||||
!"); | ||||
if (getVersion() == llvm::LLVMDebugVersion7) | ||||
return getFieldAs<DICompileUnit>(3); | ||||
return getFieldAs<DIFile>(3).getCompileUnit(); | ||||
} | ||||
DIFile getFile() const { return getFieldAs<DIFile>(3); } | ||||
unsigned getLineNumber() const { return getUnsignedField(4); } | unsigned getLineNumber() const { return getUnsignedField(4); } | |||
uint64_t getSizeInBits() const { return getUInt64Field(5); } | uint64_t getSizeInBits() const { return getUInt64Field(5); } | |||
uint64_t getAlignInBits() const { return getUInt64Field(6); } | uint64_t getAlignInBits() const { return getUInt64Field(6); } | |||
// FIXME: Offset is only used for DW_TAG_member nodes. Making every ty pe | // FIXME: Offset is only used for DW_TAG_member nodes. Making every ty pe | |||
// carry this is just plain insane. | // carry this is just plain insane. | |||
uint64_t getOffsetInBits() const { return getUInt64Field(7); } | uint64_t getOffsetInBits() const { return getUInt64Field(7); } | |||
unsigned getFlags() const { return getUnsignedField(8); } | unsigned getFlags() const { return getUnsignedField(8); } | |||
bool isPrivate() const { | bool isPrivate() const { | |||
return (getFlags() & FlagPrivate) != 0; | return (getFlags() & FlagPrivate) != 0; | |||
} | } | |||
skipping to change at line 298 | skipping to change at line 278 | |||
} | } | |||
bool isArtificial() const { | bool isArtificial() const { | |||
return (getFlags() & FlagArtificial) != 0; | return (getFlags() & FlagArtificial) != 0; | |||
} | } | |||
bool isObjectPointer() const { | bool isObjectPointer() const { | |||
return (getFlags() & FlagObjectPointer) != 0; | return (getFlags() & FlagObjectPointer) != 0; | |||
} | } | |||
bool isObjcClassComplete() const { | bool isObjcClassComplete() const { | |||
return (getFlags() & FlagObjcClassComplete) != 0; | return (getFlags() & FlagObjcClassComplete) != 0; | |||
} | } | |||
bool isValid() const { | bool isVector() const { | |||
return DbgNode && (isBasicType() || isDerivedType() || isCompositeTyp | return (getFlags() & FlagVector) != 0; | |||
e()); | ||||
} | } | |||
StringRef getDirectory() const { | bool isStaticMember() const { | |||
if (getVersion() == llvm::LLVMDebugVersion7) | return (getFlags() & FlagStaticMember) != 0; | |||
return getCompileUnit().getDirectory(); | ||||
return getFieldAs<DIFile>(3).getDirectory(); | ||||
} | } | |||
StringRef getFilename() const { | bool isValid() const { | |||
if (getVersion() == llvm::LLVMDebugVersion7) | return DbgNode && (isBasicType() || isDerivedType() || isCompositeTyp | |||
return getCompileUnit().getFilename(); | e()); | |||
return getFieldAs<DIFile>(3).getFilename(); | ||||
} | } | |||
/// isUnsignedDIType - Return true if type encoding is unsigned. | /// isUnsignedDIType - Return true if type encoding is unsigned. | |||
bool isUnsignedDIType(); | bool isUnsignedDIType(); | |||
/// replaceAllUsesWith - Replace all uses of debug info referenced by | /// replaceAllUsesWith - Replace all uses of debug info referenced by | |||
/// this descriptor. | /// this descriptor. | |||
void replaceAllUsesWith(DIDescriptor &D); | void replaceAllUsesWith(DIDescriptor &D); | |||
void replaceAllUsesWith(MDNode *D); | void replaceAllUsesWith(MDNode *D); | |||
}; | }; | |||
skipping to change at line 335 | skipping to change at line 309 | |||
public: | public: | |||
explicit DIBasicType(const MDNode *N = 0) : DIType(N) {} | explicit DIBasicType(const MDNode *N = 0) : DIType(N) {} | |||
unsigned getEncoding() const { return getUnsignedField(9); } | unsigned getEncoding() const { return getUnsignedField(9); } | |||
/// Verify - Verify that a basic type descriptor is well formed. | /// Verify - Verify that a basic type descriptor is well formed. | |||
bool Verify() const; | bool Verify() const; | |||
}; | }; | |||
/// DIDerivedType - A simple derived type, like a const qualified type, | /// DIDerivedType - A simple derived type, like a const qualified type, | |||
/// a typedef, a pointer or reference, etc. | /// a typedef, a pointer or reference, et cetera. Or, a data member of | |||
/// a class/struct/union. | ||||
class DIDerivedType : public DIType { | class DIDerivedType : public DIType { | |||
friend class DIDescriptor; | friend class DIDescriptor; | |||
void printInternal(raw_ostream &OS) const; | void printInternal(raw_ostream &OS) const; | |||
protected: | protected: | |||
explicit DIDerivedType(const MDNode *N, bool, bool) | explicit DIDerivedType(const MDNode *N, bool, bool) | |||
: DIType(N, true, true) {} | : DIType(N, true, true) {} | |||
public: | public: | |||
explicit DIDerivedType(const MDNode *N = 0) | explicit DIDerivedType(const MDNode *N = 0) | |||
: DIType(N, true, true) {} | : DIType(N, true, true) {} | |||
DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); } | DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); } | |||
/// getOriginalTypeSize - If this type is derived from a base type then | /// getOriginalTypeSize - If this type is derived from a base type then | |||
/// return base type size. | /// return base type size. | |||
uint64_t getOriginalTypeSize() const; | uint64_t getOriginalTypeSize() const; | |||
/// getObjCProperty - Return property node, if this ivar is | /// getObjCProperty - Return property node, if this ivar is | |||
/// associated with one. | /// associated with one. | |||
MDNode *getObjCProperty() const; | MDNode *getObjCProperty() const; | |||
StringRef getObjCPropertyName() const { | DIType getClassType() const { | |||
if (getVersion() > LLVMDebugVersion11) | assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); | |||
return StringRef(); | return getFieldAs<DIType>(10); | |||
return getStringField(10); | ||||
} | ||||
StringRef getObjCPropertyGetterName() const { | ||||
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); | ||||
return getStringField(11); | ||||
} | ||||
StringRef getObjCPropertySetterName() const { | ||||
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); | ||||
return getStringField(12); | ||||
} | ||||
bool isReadOnlyObjCProperty() { | ||||
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); | ||||
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != | ||||
0; | ||||
} | ||||
bool isReadWriteObjCProperty() { | ||||
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); | ||||
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != | ||||
0; | ||||
} | ||||
bool isAssignObjCProperty() { | ||||
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); | ||||
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0; | ||||
} | ||||
bool isRetainObjCProperty() { | ||||
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); | ||||
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0; | ||||
} | } | |||
bool isCopyObjCProperty() { | ||||
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); | Constant *getConstant() const { | |||
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0; | assert((getTag() == dwarf::DW_TAG_member) && isStaticMember()); | |||
} | return getConstantField(10); | |||
bool isNonAtomicObjCProperty() { | ||||
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); | ||||
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != | ||||
0; | ||||
} | } | |||
/// Verify - Verify that a derived type descriptor is well formed. | /// Verify - Verify that a derived type descriptor is well formed. | |||
bool Verify() const; | bool Verify() const; | |||
}; | }; | |||
/// DICompositeType - This descriptor holds a type that can refer to mult iple | /// DICompositeType - This descriptor holds a type that can refer to mult iple | |||
/// other types, like a function or struct. | /// other types, like a function or struct. | |||
/// FIXME: Why is this a DIDerivedType?? | /// DICompositeType is derived from DIDerivedType because some | |||
/// composite types (such as enums) can be derived from basic types | ||||
// FIXME: Make this derive from DIType directly & just store the | ||||
// base type in a single DIType field. | ||||
class DICompositeType : public DIDerivedType { | class DICompositeType : public DIDerivedType { | |||
friend class DIDescriptor; | friend class DIDescriptor; | |||
void printInternal(raw_ostream &OS) const; | void printInternal(raw_ostream &OS) const; | |||
public: | public: | |||
explicit DICompositeType(const MDNode *N = 0) | explicit DICompositeType(const MDNode *N = 0) | |||
: DIDerivedType(N, true, true) { | : DIDerivedType(N, true, true) { | |||
if (N && !isCompositeType()) | if (N && !isCompositeType()) | |||
DbgNode = 0; | DbgNode = 0; | |||
} | } | |||
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); } | DIArray getTypeArray() const { return getFieldAs<DIArray>(10); } | |||
void setTypeArray(DIArray Elements, DIArray TParams = DIArray()); | ||||
unsigned getRunTimeLang() const { return getUnsignedField(11); } | unsigned getRunTimeLang() const { return getUnsignedField(11); } | |||
DICompositeType getContainingType() const { | DICompositeType getContainingType() const { | |||
return getFieldAs<DICompositeType>(12); | return getFieldAs<DICompositeType>(12); | |||
} | } | |||
void setContainingType(DICompositeType ContainingType); | ||||
DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); } | DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); } | |||
/// Verify - Verify that a composite type descriptor is well formed. | /// Verify - Verify that a composite type descriptor is well formed. | |||
bool Verify() const; | bool Verify() const; | |||
}; | }; | |||
/// DITemplateTypeParameter - This is a wrapper for template type paramet er. | /// DITemplateTypeParameter - This is a wrapper for template type paramet er. | |||
class DITemplateTypeParameter : public DIDescriptor { | class DITemplateTypeParameter : public DIDescriptor { | |||
public: | public: | |||
explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {} | explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {} | |||
skipping to change at line 438 | skipping to change at line 390 | |||
StringRef getName() const { return getStringField(2); } | StringRef getName() const { return getStringField(2); } | |||
DIType getType() const { return getFieldAs<DIType>(3); } | DIType getType() const { return getFieldAs<DIType>(3); } | |||
StringRef getFilename() const { | StringRef getFilename() const { | |||
return getFieldAs<DIFile>(4).getFilename(); | return getFieldAs<DIFile>(4).getFilename(); | |||
} | } | |||
StringRef getDirectory() const { | StringRef getDirectory() const { | |||
return getFieldAs<DIFile>(4).getDirectory(); | return getFieldAs<DIFile>(4).getDirectory(); | |||
} | } | |||
unsigned getLineNumber() const { return getUnsignedField(5); } | unsigned getLineNumber() const { return getUnsignedField(5); } | |||
unsigned getColumnNumber() const { return getUnsignedField(6); } | unsigned getColumnNumber() const { return getUnsignedField(6); } | |||
bool Verify() const; | ||||
}; | }; | |||
/// DITemplateValueParameter - This is a wrapper for template value param eter. | /// DITemplateValueParameter - This is a wrapper for template value param eter. | |||
class DITemplateValueParameter : public DIDescriptor { | class DITemplateValueParameter : public DIDescriptor { | |||
public: | public: | |||
explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N ) {} | explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N ) {} | |||
DIScope getContext() const { return getFieldAs<DIScope>(1); } | DIScope getContext() const { return getFieldAs<DIScope>(1); } | |||
StringRef getName() const { return getStringField(2); } | StringRef getName() const { return getStringField(2); } | |||
DIType getType() const { return getFieldAs<DIType>(3); } | DIType getType() const { return getFieldAs<DIType>(3); } | |||
uint64_t getValue() const { return getUInt64Field(4); } | uint64_t getValue() const { return getUInt64Field(4); } | |||
StringRef getFilename() const { | StringRef getFilename() const { | |||
return getFieldAs<DIFile>(5).getFilename(); | return getFieldAs<DIFile>(5).getFilename(); | |||
} | } | |||
StringRef getDirectory() const { | StringRef getDirectory() const { | |||
return getFieldAs<DIFile>(5).getDirectory(); | return getFieldAs<DIFile>(5).getDirectory(); | |||
} | } | |||
unsigned getLineNumber() const { return getUnsignedField(6); } | unsigned getLineNumber() const { return getUnsignedField(6); } | |||
unsigned getColumnNumber() const { return getUnsignedField(7); } | unsigned getColumnNumber() const { return getUnsignedField(7); } | |||
bool Verify() const; | ||||
}; | }; | |||
/// DISubprogram - This is a wrapper for a subprogram (e.g. a function). | /// DISubprogram - This is a wrapper for a subprogram (e.g. a function). | |||
class DISubprogram : public DIScope { | class DISubprogram : public DIScope { | |||
friend class DIDescriptor; | friend class DIDescriptor; | |||
void printInternal(raw_ostream &OS) const; | void printInternal(raw_ostream &OS) const; | |||
public: | public: | |||
explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {} | explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {} | |||
DIScope getContext() const { return getFieldAs<DIScope>(2); } | DIScope getContext() const { return getFieldAs<DIScope>(2); } | |||
StringRef getName() const { return getStringField(3); } | StringRef getName() const { return getStringField(3); } | |||
StringRef getDisplayName() const { return getStringField(4); } | StringRef getDisplayName() const { return getStringField(4); } | |||
StringRef getLinkageName() const { return getStringField(5); } | StringRef getLinkageName() const { return getStringField(5); } | |||
DICompileUnit getCompileUnit() const{ | unsigned getLineNumber() const { return getUnsignedField(6); } | |||
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit | DICompositeType getType() const { return getFieldAs<DICompositeType>(7) | |||
!"); | ; } | |||
if (getVersion() == llvm::LLVMDebugVersion7) | ||||
return getFieldAs<DICompileUnit>(6); | ||||
return getFieldAs<DIFile>(6).getCompileUnit(); | ||||
} | ||||
unsigned getLineNumber() const { return getUnsignedField(7); } | ||||
DICompositeType getType() const { return getFieldAs<DICompositeType>(8) | ||||
; } | ||||
/// getReturnTypeName - Subprogram return types are encoded either as | /// getReturnTypeName - Subprogram return types are encoded either as | |||
/// DIType or as DICompositeType. | /// DIType or as DICompositeType. | |||
StringRef getReturnTypeName() const { | StringRef getReturnTypeName() const { | |||
DICompositeType DCT(getFieldAs<DICompositeType>(8)); | DICompositeType DCT(getFieldAs<DICompositeType>(7)); | |||
if (DCT.Verify()) { | if (DCT.Verify()) { | |||
DIArray A = DCT.getTypeArray(); | DIArray A = DCT.getTypeArray(); | |||
DIType T(A.getElement(0)); | DIType T(A.getElement(0)); | |||
return T.getName(); | return T.getName(); | |||
} | } | |||
DIType T(getFieldAs<DIType>(8)); | DIType T(getFieldAs<DIType>(7)); | |||
return T.getName(); | return T.getName(); | |||
} | } | |||
/// isLocalToUnit - Return true if this subprogram is local to the curr ent | /// isLocalToUnit - Return true if this subprogram is local to the curr ent | |||
/// compile unit, like 'static' in C. | /// compile unit, like 'static' in C. | |||
unsigned isLocalToUnit() const { return getUnsignedField(9); } | unsigned isLocalToUnit() const { return getUnsignedField(8); } | |||
unsigned isDefinition() const { return getUnsignedField(10); } | unsigned isDefinition() const { return getUnsignedField(9); } | |||
unsigned getVirtuality() const { return getUnsignedField(11); } | unsigned getVirtuality() const { return getUnsignedField(10); } | |||
unsigned getVirtualIndex() const { return getUnsignedField(12); } | unsigned getVirtualIndex() const { return getUnsignedField(11); } | |||
DICompositeType getContainingType() const { | DICompositeType getContainingType() const { | |||
return getFieldAs<DICompositeType>(13); | return getFieldAs<DICompositeType>(12); | |||
} | ||||
unsigned getFlags() const { | ||||
return getUnsignedField(13); | ||||
} | } | |||
unsigned isArtificial() const { | unsigned isArtificial() const { | |||
if (getVersion() <= llvm::LLVMDebugVersion8) | return (getUnsignedField(13) & FlagArtificial) != 0; | |||
return getUnsignedField(14); | ||||
return (getUnsignedField(14) & FlagArtificial) != 0; | ||||
} | } | |||
/// isPrivate - Return true if this subprogram has "private" | /// isPrivate - Return true if this subprogram has "private" | |||
/// access specifier. | /// access specifier. | |||
bool isPrivate() const { | bool isPrivate() const { | |||
if (getVersion() <= llvm::LLVMDebugVersion8) | return (getUnsignedField(13) & FlagPrivate) != 0; | |||
return false; | ||||
return (getUnsignedField(14) & FlagPrivate) != 0; | ||||
} | } | |||
/// isProtected - Return true if this subprogram has "protected" | /// isProtected - Return true if this subprogram has "protected" | |||
/// access specifier. | /// access specifier. | |||
bool isProtected() const { | bool isProtected() const { | |||
if (getVersion() <= llvm::LLVMDebugVersion8) | return (getUnsignedField(13) & FlagProtected) != 0; | |||
return false; | ||||
return (getUnsignedField(14) & FlagProtected) != 0; | ||||
} | } | |||
/// isExplicit - Return true if this subprogram is marked as explicit. | /// isExplicit - Return true if this subprogram is marked as explicit. | |||
bool isExplicit() const { | bool isExplicit() const { | |||
if (getVersion() <= llvm::LLVMDebugVersion8) | return (getUnsignedField(13) & FlagExplicit) != 0; | |||
return false; | ||||
return (getUnsignedField(14) & FlagExplicit) != 0; | ||||
} | } | |||
/// isPrototyped - Return true if this subprogram is prototyped. | /// isPrototyped - Return true if this subprogram is prototyped. | |||
bool isPrototyped() const { | bool isPrototyped() const { | |||
if (getVersion() <= llvm::LLVMDebugVersion8) | return (getUnsignedField(13) & FlagPrototyped) != 0; | |||
return false; | ||||
return (getUnsignedField(14) & FlagPrototyped) != 0; | ||||
} | } | |||
unsigned isOptimized() const; | unsigned isOptimized() const; | |||
StringRef getFilename() const { | ||||
if (getVersion() == llvm::LLVMDebugVersion7) | ||||
return getCompileUnit().getFilename(); | ||||
return getFieldAs<DIFile>(6).getFilename(); | ||||
} | ||||
StringRef getDirectory() const { | ||||
if (getVersion() == llvm::LLVMDebugVersion7) | ||||
return getCompileUnit().getFilename(); | ||||
return getFieldAs<DIFile>(6).getDirectory(); | ||||
} | ||||
/// getScopeLineNumber - Get the beginning of the scope of the | /// getScopeLineNumber - Get the beginning of the scope of the | |||
/// function, not necessarily where the name of the program | /// function, not necessarily where the name of the program | |||
/// starts. | /// starts. | |||
unsigned getScopeLineNumber() const { return getUnsignedField(20); } | unsigned getScopeLineNumber() const { return getUnsignedField(19); } | |||
/// Verify - Verify that a subprogram descriptor is well formed. | /// Verify - Verify that a subprogram descriptor is well formed. | |||
bool Verify() const; | bool Verify() const; | |||
/// describes - Return true if this subprogram provides debugging | /// describes - Return true if this subprogram provides debugging | |||
/// information for the function F. | /// information for the function F. | |||
bool describes(const Function *F); | bool describes(const Function *F); | |||
Function *getFunction() const { return getFunctionField(16); } | Function *getFunction() const { return getFunctionField(15); } | |||
void replaceFunction(Function *F) { replaceFunctionField(16, F); } | void replaceFunction(Function *F) { replaceFunctionField(15, F); } | |||
DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); } | DIArray getTemplateParams() const { return getFieldAs<DIArray>(16); } | |||
DISubprogram getFunctionDeclaration() const { | DISubprogram getFunctionDeclaration() const { | |||
return getFieldAs<DISubprogram>(18); | return getFieldAs<DISubprogram>(17); | |||
} | } | |||
MDNode *getVariablesNodes() const; | MDNode *getVariablesNodes() const; | |||
DIArray getVariables() const; | DIArray getVariables() const; | |||
}; | }; | |||
/// DIGlobalVariable - This is a wrapper for a global variable. | /// DIGlobalVariable - This is a wrapper for a global variable. | |||
class DIGlobalVariable : public DIDescriptor { | class DIGlobalVariable : public DIDescriptor { | |||
friend class DIDescriptor; | friend class DIDescriptor; | |||
void printInternal(raw_ostream &OS) const; | void printInternal(raw_ostream &OS) const; | |||
public: | public: | |||
explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {} | explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {} | |||
DIScope getContext() const { return getFieldAs<DIScope>(2); } | DIScope getContext() const { return getFieldAs<DIScope>(2); } | |||
StringRef getName() const { return getStringField(3); } | StringRef getName() const { return getStringField(3); } | |||
StringRef getDisplayName() const { return getStringField(4); } | StringRef getDisplayName() const { return getStringField(4); } | |||
StringRef getLinkageName() const { return getStringField(5); } | StringRef getLinkageName() const { return getStringField(5); } | |||
DICompileUnit getCompileUnit() const{ | ||||
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit | ||||
!"); | ||||
if (getVersion() == llvm::LLVMDebugVersion7) | ||||
return getFieldAs<DICompileUnit>(6); | ||||
DIFile F = getFieldAs<DIFile>(6); | ||||
return F.getCompileUnit(); | ||||
} | ||||
StringRef getFilename() const { | StringRef getFilename() const { | |||
if (getVersion() <= llvm::LLVMDebugVersion10) | ||||
return getContext().getFilename(); | ||||
return getFieldAs<DIFile>(6).getFilename(); | return getFieldAs<DIFile>(6).getFilename(); | |||
} | } | |||
StringRef getDirectory() const { | StringRef getDirectory() const { | |||
if (getVersion() <= llvm::LLVMDebugVersion10) | ||||
return getContext().getDirectory(); | ||||
return getFieldAs<DIFile>(6).getDirectory(); | return getFieldAs<DIFile>(6).getDirectory(); | |||
} | } | |||
unsigned getLineNumber() const { return getUnsignedField(7); } | unsigned getLineNumber() const { return getUnsignedField(7); } | |||
DIType getType() const { return getFieldAs<DIType>(8); } | DIType getType() const { return getFieldAs<DIType>(8); } | |||
unsigned isLocalToUnit() const { return getUnsignedField(9); } | unsigned isLocalToUnit() const { return getUnsignedField(9); } | |||
unsigned isDefinition() const { return getUnsignedField(10); } | unsigned isDefinition() const { return getUnsignedField(10); } | |||
GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } | GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } | |||
Constant *getConstant() const { return getConstantField(11); } | Constant *getConstant() const { return getConstantField(11); } | |||
DIDerivedType getStaticDataMemberDeclaration() const { | ||||
return getFieldAs<DIDerivedType>(12); | ||||
} | ||||
/// Verify - Verify that a global variable descriptor is well formed. | /// Verify - Verify that a global variable descriptor is well formed. | |||
bool Verify() const; | bool Verify() const; | |||
}; | }; | |||
/// DIVariable - This is a wrapper for a variable (e.g. parameter, local, | /// DIVariable - This is a wrapper for a variable (e.g. parameter, local, | |||
/// global etc). | /// global etc). | |||
class DIVariable : public DIDescriptor { | class DIVariable : public DIDescriptor { | |||
friend class DIDescriptor; | friend class DIDescriptor; | |||
void printInternal(raw_ostream &OS) const; | void printInternal(raw_ostream &OS) const; | |||
public: | public: | |||
explicit DIVariable(const MDNode *N = 0) | explicit DIVariable(const MDNode *N = 0) | |||
: DIDescriptor(N) {} | : DIDescriptor(N) {} | |||
DIScope getContext() const { return getFieldAs<DIScope>(1); } | DIScope getContext() const { return getFieldAs<DIScope>(1); } | |||
StringRef getName() const { return getStringField(2); } | StringRef getName() const { return getStringField(2); } | |||
DICompileUnit getCompileUnit() const { | DIFile getFile() const { return getFieldAs<DIFile>(3); } | |||
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit | ||||
!"); | ||||
if (getVersion() == llvm::LLVMDebugVersion7) | ||||
return getFieldAs<DICompileUnit>(3); | ||||
DIFile F = getFieldAs<DIFile>(3); | ||||
return F.getCompileUnit(); | ||||
} | ||||
unsigned getLineNumber() const { | unsigned getLineNumber() const { | |||
return (getUnsignedField(4) << 8) >> 8; | return (getUnsignedField(4) << 8) >> 8; | |||
} | } | |||
unsigned getArgNumber() const { | unsigned getArgNumber() const { | |||
unsigned L = getUnsignedField(4); | unsigned L = getUnsignedField(4); | |||
return L >> 24; | return L >> 24; | |||
} | } | |||
DIType getType() const { return getFieldAs<DIType>(5); } | DIType getType() const { return getFieldAs<DIType>(5); } | |||
/// isArtificial - Return true if this variable is marked as "artificia l". | /// isArtificial - Return true if this variable is marked as "artificia l". | |||
bool isArtificial() const { | bool isArtificial() const { | |||
if (getVersion() <= llvm::LLVMDebugVersion8) | ||||
return false; | ||||
return (getUnsignedField(6) & FlagArtificial) != 0; | return (getUnsignedField(6) & FlagArtificial) != 0; | |||
} | } | |||
bool isObjectPointer() const { | bool isObjectPointer() const { | |||
return (getUnsignedField(6) & FlagObjectPointer) != 0; | return (getUnsignedField(6) & FlagObjectPointer) != 0; | |||
} | } | |||
/// getInlinedAt - If this variable is inlined then return inline locat ion. | /// getInlinedAt - If this variable is inlined then return inline locat ion. | |||
MDNode *getInlinedAt() const; | MDNode *getInlinedAt() const; | |||
skipping to change at line 671 | skipping to change at line 580 | |||
bool Verify() const; | bool Verify() const; | |||
/// HasComplexAddr - Return true if the variable has a complex address. | /// HasComplexAddr - Return true if the variable has a complex address. | |||
bool hasComplexAddress() const { | bool hasComplexAddress() const { | |||
return getNumAddrElements() > 0; | return getNumAddrElements() > 0; | |||
} | } | |||
unsigned getNumAddrElements() const; | unsigned getNumAddrElements() const; | |||
uint64_t getAddrElement(unsigned Idx) const { | uint64_t getAddrElement(unsigned Idx) const { | |||
if (getVersion() <= llvm::LLVMDebugVersion8) | ||||
return getUInt64Field(Idx+6); | ||||
if (getVersion() == llvm::LLVMDebugVersion9) | ||||
return getUInt64Field(Idx+7); | ||||
return getUInt64Field(Idx+8); | return getUInt64Field(Idx+8); | |||
} | } | |||
/// isBlockByrefVariable - Return true if the variable was declared as | /// isBlockByrefVariable - Return true if the variable was declared as | |||
/// a "__block" variable (Apple Blocks). | /// a "__block" variable (Apple Blocks). | |||
bool isBlockByrefVariable() const { | bool isBlockByrefVariable() const { | |||
return getType().isBlockByrefStruct(); | return getType().isBlockByrefStruct(); | |||
} | } | |||
/// isInlinedFnArgument - Return trule if this variable provides debugg ing | /// isInlinedFnArgument - Return true if this variable provides debuggi ng | |||
/// information for an inlined function arguments. | /// information for an inlined function arguments. | |||
bool isInlinedFnArgument(const Function *CurFn); | bool isInlinedFnArgument(const Function *CurFn); | |||
void printExtendedName(raw_ostream &OS) const; | void printExtendedName(raw_ostream &OS) const; | |||
}; | }; | |||
/// DILexicalBlock - This is a wrapper for a lexical block. | /// DILexicalBlock - This is a wrapper for a lexical block. | |||
class DILexicalBlock : public DIScope { | class DILexicalBlock : public DIScope { | |||
public: | public: | |||
explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {} | explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {} | |||
DIScope getContext() const { return getFieldAs<DIScope>(1); | DIScope getContext() const { return getFieldAs<DIScope>(2); | |||
} | } | |||
unsigned getLineNumber() const { return getUnsignedField(2); | unsigned getLineNumber() const { return getUnsignedField(3); | |||
} | } | |||
unsigned getColumnNumber() const { return getUnsignedField(3); | unsigned getColumnNumber() const { return getUnsignedField(4); | |||
} | } | |||
StringRef getDirectory() const { | bool Verify() const; | |||
StringRef dir = getFieldAs<DIFile>(4).getDirectory(); | ||||
return !dir.empty() ? dir : getContext().getDirectory(); | ||||
} | ||||
StringRef getFilename() const { | ||||
StringRef filename = getFieldAs<DIFile>(4).getFilename(); | ||||
return !filename.empty() ? filename : getContext().getFilename(); | ||||
} | ||||
}; | }; | |||
/// DILexicalBlockFile - This is a wrapper for a lexical block with | /// DILexicalBlockFile - This is a wrapper for a lexical block with | |||
/// a filename change. | /// a filename change. | |||
class DILexicalBlockFile : public DIScope { | class DILexicalBlockFile : public DIScope { | |||
public: | public: | |||
explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {} | explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {} | |||
DIScope getContext() const { return getScope().getContext(); } | DIScope getContext() const { if (getScope().isSubprogram()) return getS cope(); return getScope().getContext(); } | |||
unsigned getLineNumber() const { return getScope().getLineNumber(); } | unsigned getLineNumber() const { return getScope().getLineNumber(); } | |||
unsigned getColumnNumber() const { return getScope().getColumnNumber(); } | unsigned getColumnNumber() const { return getScope().getColumnNumber(); } | |||
StringRef getDirectory() const { | DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); | |||
StringRef dir = getFieldAs<DIFile>(2).getDirectory(); | } | |||
return !dir.empty() ? dir : getContext().getDirectory(); | bool Verify() const; | |||
} | ||||
StringRef getFilename() const { | ||||
StringRef filename = getFieldAs<DIFile>(2).getFilename(); | ||||
assert(!filename.empty() && "Why'd you create this then?"); | ||||
return filename; | ||||
} | ||||
DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); | ||||
} | ||||
}; | }; | |||
/// DINameSpace - A wrapper for a C++ style name space. | /// DINameSpace - A wrapper for a C++ style name space. | |||
class DINameSpace : public DIScope { | class DINameSpace : public DIScope { | |||
friend class DIDescriptor; | ||||
void printInternal(raw_ostream &OS) const; | ||||
public: | public: | |||
explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {} | explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {} | |||
DIScope getContext() const { return getFieldAs<DIScope>(1); } | DIScope getContext() const { return getFieldAs<DIScope>(2); } | |||
StringRef getName() const { return getStringField(2); } | StringRef getName() const { return getStringField(3); } | |||
StringRef getDirectory() const { | ||||
return getFieldAs<DIFile>(3).getDirectory(); | ||||
} | ||||
StringRef getFilename() const { | ||||
return getFieldAs<DIFile>(3).getFilename(); | ||||
} | ||||
DICompileUnit getCompileUnit() const{ | ||||
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit | ||||
!"); | ||||
if (getVersion() == llvm::LLVMDebugVersion7) | ||||
return getFieldAs<DICompileUnit>(3); | ||||
return getFieldAs<DIFile>(3).getCompileUnit(); | ||||
} | ||||
unsigned getLineNumber() const { return getUnsignedField(4); } | unsigned getLineNumber() const { return getUnsignedField(4); } | |||
bool Verify() const; | bool Verify() const; | |||
}; | }; | |||
/// DILocation - This object holds location information. This object | /// DILocation - This object holds location information. This object | |||
/// is not associated with any DWARF tag. | /// is not associated with any DWARF tag. | |||
class DILocation : public DIDescriptor { | class DILocation : public DIDescriptor { | |||
public: | public: | |||
explicit DILocation(const MDNode *N) : DIDescriptor(N) { } | explicit DILocation(const MDNode *N) : DIDescriptor(N) { } | |||
skipping to change at line 807 | skipping to change at line 686 | |||
bool isNonAtomicObjCProperty() { | bool isNonAtomicObjCProperty() { | |||
return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; | return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; | |||
} | } | |||
DIType getType() const { return getFieldAs<DIType>(7); } | DIType getType() const { return getFieldAs<DIType>(7); } | |||
/// Verify - Verify that a derived type descriptor is well formed. | /// Verify - Verify that a derived type descriptor is well formed. | |||
bool Verify() const; | bool Verify() const; | |||
}; | }; | |||
/// \brief An imported module (C++ using directive or similar). | ||||
class DIImportedModule : public DIDescriptor { | ||||
friend class DIDescriptor; | ||||
void printInternal(raw_ostream &OS) const; | ||||
public: | ||||
explicit DIImportedModule(const MDNode *N) : DIDescriptor(N) { } | ||||
DIScope getContext() const { return getFieldAs<DIScope>(1); } | ||||
DINameSpace getNameSpace() const { return getFieldAs<DINameSpace>(2); } | ||||
unsigned getLineNumber() const { return getUnsignedField(3); } | ||||
bool Verify() const; | ||||
}; | ||||
/// getDISubprogram - Find subprogram that is enclosing this scope. | /// getDISubprogram - Find subprogram that is enclosing this scope. | |||
DISubprogram getDISubprogram(const MDNode *Scope); | DISubprogram getDISubprogram(const MDNode *Scope); | |||
/// getDICompositeType - Find underlying composite type. | /// getDICompositeType - Find underlying composite type. | |||
DICompositeType getDICompositeType(DIType T); | DICompositeType getDICompositeType(DIType T); | |||
/// isSubprogramContext - Return true if Context is either a subprogram | /// isSubprogramContext - Return true if Context is either a subprogram | |||
/// or another context nested inside a subprogram. | /// or another context nested inside a subprogram. | |||
bool isSubprogramContext(const MDNode *Context); | bool isSubprogramContext(const MDNode *Context); | |||
skipping to change at line 839 | skipping to change at line 730 | |||
DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, | DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, | |||
LLVMContext &VMContext); | LLVMContext &VMContext); | |||
/// cleanseInlinedVariable - Remove inlined scope from the variable. | /// cleanseInlinedVariable - Remove inlined scope from the variable. | |||
DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); | DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); | |||
class DebugInfoFinder { | class DebugInfoFinder { | |||
public: | public: | |||
/// processModule - Process entire module and collect debug info | /// processModule - Process entire module and collect debug info | |||
/// anchors. | /// anchors. | |||
void processModule(Module &M); | void processModule(const Module &M); | |||
private: | private: | |||
/// processType - Process DIType. | /// processType - Process DIType. | |||
void processType(DIType DT); | void processType(DIType DT); | |||
/// processLexicalBlock - Process DILexicalBlock. | /// processLexicalBlock - Process DILexicalBlock. | |||
void processLexicalBlock(DILexicalBlock LB); | void processLexicalBlock(DILexicalBlock LB); | |||
/// processSubprogram - Process DISubprogram. | /// processSubprogram - Process DISubprogram. | |||
void processSubprogram(DISubprogram SP); | void processSubprogram(DISubprogram SP); | |||
/// processDeclare - Process DbgDeclareInst. | /// processDeclare - Process DbgDeclareInst. | |||
void processDeclare(DbgDeclareInst *DDI); | void processDeclare(const DbgDeclareInst *DDI); | |||
/// processLocation - Process DILocation. | /// processLocation - Process DILocation. | |||
void processLocation(DILocation Loc); | void processLocation(DILocation Loc); | |||
/// addCompileUnit - Add compile unit into CUs. | /// addCompileUnit - Add compile unit into CUs. | |||
bool addCompileUnit(DICompileUnit CU); | bool addCompileUnit(DICompileUnit CU); | |||
/// addGlobalVariable - Add global variable into GVs. | /// addGlobalVariable - Add global variable into GVs. | |||
bool addGlobalVariable(DIGlobalVariable DIG); | bool addGlobalVariable(DIGlobalVariable DIG); | |||
End of changes. 57 change blocks. | ||||
243 lines changed or deleted | 118 lines changed or added | |||
DebugLoc.h | DebugLoc.h | |||
---|---|---|---|---|
skipping to change at line 111 | skipping to change at line 111 | |||
template <> | template <> | |||
struct DenseMapInfo<DebugLoc> { | struct DenseMapInfo<DebugLoc> { | |||
static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); } | static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); } | |||
static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); } | static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); } | |||
static unsigned getHashValue(const DebugLoc &Key); | static unsigned getHashValue(const DebugLoc &Key); | |||
static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; } | static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; } | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif /* LLVM_DEBUGLOC_H */ | #endif /* LLVM_SUPPORT_DEBUGLOC_H */ | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 0 lines changed or added | |||
DeltaAlgorithm.h | DeltaAlgorithm.h | |||
---|---|---|---|---|
skipping to change at line 12 | skipping to change at line 12 | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_DELTAALGORITHM_H | #ifndef LLVM_ADT_DELTAALGORITHM_H | |||
#define LLVM_ADT_DELTAALGORITHM_H | #define LLVM_ADT_DELTAALGORITHM_H | |||
#include <vector> | ||||
#include <set> | #include <set> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
/// DeltaAlgorithm - Implements the delta debugging algorithm (A. Zeller '9 9) | /// DeltaAlgorithm - Implements the delta debugging algorithm (A. Zeller '9 9) | |||
/// for minimizing arbitrary sets using a predicate function. | /// for minimizing arbitrary sets using a predicate function. | |||
/// | /// | |||
/// The result of the algorithm is a subset of the input change set which i s | /// The result of the algorithm is a subset of the input change set which i s | |||
/// guaranteed to satisfy the predicate, assuming that the input set did. F or | /// guaranteed to satisfy the predicate, assuming that the input set did. F or | |||
/// well formed predicates, the result set is guaranteed to be such that | /// well formed predicates, the result set is guaranteed to be such that | |||
/// removing any single element would falsify the predicate. | /// removing any single element would falsify the predicate. | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
DenseMap.h | DenseMap.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the DenseMap class. | // This file defines the DenseMap class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_DENSEMAP_H | #ifndef LLVM_ADT_DENSEMAP_H | |||
#define LLVM_ADT_DENSEMAP_H | #define LLVM_ADT_DENSEMAP_H | |||
#include "llvm/Support/Compiler.h" | #include "llvm/ADT/DenseMapInfo.h" | |||
#include "llvm/Support/AlignOf.h" | #include "llvm/Support/AlignOf.h" | |||
#include "llvm/Support/Compiler.h" | ||||
#include "llvm/Support/MathExtras.h" | #include "llvm/Support/MathExtras.h" | |||
#include "llvm/Support/PointerLikeTypeTraits.h" | #include "llvm/Support/PointerLikeTypeTraits.h" | |||
#include "llvm/Support/type_traits.h" | #include "llvm/Support/type_traits.h" | |||
#include "llvm/ADT/DenseMapInfo.h" | ||||
#include <algorithm> | #include <algorithm> | |||
#include <iterator> | ||||
#include <new> | ||||
#include <utility> | ||||
#include <cassert> | #include <cassert> | |||
#include <climits> | #include <climits> | |||
#include <cstddef> | #include <cstddef> | |||
#include <cstring> | #include <cstring> | |||
#include <iterator> | ||||
#include <new> | ||||
#include <utility> | ||||
namespace llvm { | namespace llvm { | |||
template<typename KeyT, typename ValueT, | template<typename KeyT, typename ValueT, | |||
typename KeyInfoT = DenseMapInfo<KeyT>, | typename KeyInfoT = DenseMapInfo<KeyT>, | |||
bool IsConst = false> | bool IsConst = false> | |||
class DenseMapIterator; | class DenseMapIterator; | |||
template<typename DerivedT, | template<typename DerivedT, | |||
typename KeyT, typename ValueT, typename KeyInfoT> | typename KeyT, typename ValueT, typename KeyInfoT> | |||
skipping to change at line 162 | skipping to change at line 162 | |||
BucketT *TheBucket; | BucketT *TheBucket; | |||
if (LookupBucketFor(KV.first, TheBucket)) | if (LookupBucketFor(KV.first, TheBucket)) | |||
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), | return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), | |||
false); // Already in map. | false); // Already in map. | |||
// Otherwise, insert the new element. | // Otherwise, insert the new element. | |||
TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket); | TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket); | |||
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true) ; | return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true) ; | |||
} | } | |||
#if LLVM_HAS_RVALUE_REFERENCES | ||||
// Inserts key,value pair into the map if the key isn't already in the ma | ||||
p. | ||||
// If the key is already in the map, it returns false and doesn't update | ||||
the | ||||
// value. | ||||
std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) { | ||||
BucketT *TheBucket; | ||||
if (LookupBucketFor(KV.first, TheBucket)) | ||||
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), | ||||
false); // Already in map. | ||||
// Otherwise, insert the new element. | ||||
TheBucket = InsertIntoBucket(std::move(KV.first), | ||||
std::move(KV.second), | ||||
TheBucket); | ||||
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true) | ||||
; | ||||
} | ||||
#endif | ||||
/// insert - Range insertion of pairs. | /// insert - Range insertion of pairs. | |||
template<typename InputIt> | template<typename InputIt> | |||
void insert(InputIt I, InputIt E) { | void insert(InputIt I, InputIt E) { | |||
for (; I != E; ++I) | for (; I != E; ++I) | |||
insert(*I); | insert(*I); | |||
} | } | |||
bool erase(const KeyT &Val) { | bool erase(const KeyT &Val) { | |||
BucketT *TheBucket; | BucketT *TheBucket; | |||
if (!LookupBucketFor(Val, TheBucket)) | if (!LookupBucketFor(Val, TheBucket)) | |||
skipping to change at line 200 | skipping to change at line 218 | |||
if (LookupBucketFor(Key, TheBucket)) | if (LookupBucketFor(Key, TheBucket)) | |||
return *TheBucket; | return *TheBucket; | |||
return *InsertIntoBucket(Key, ValueT(), TheBucket); | return *InsertIntoBucket(Key, ValueT(), TheBucket); | |||
} | } | |||
ValueT &operator[](const KeyT &Key) { | ValueT &operator[](const KeyT &Key) { | |||
return FindAndConstruct(Key).second; | return FindAndConstruct(Key).second; | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
value_type& FindAndConstruct(KeyT &&Key) { | value_type& FindAndConstruct(KeyT &&Key) { | |||
BucketT *TheBucket; | BucketT *TheBucket; | |||
if (LookupBucketFor(Key, TheBucket)) | if (LookupBucketFor(Key, TheBucket)) | |||
return *TheBucket; | return *TheBucket; | |||
return *InsertIntoBucket(Key, ValueT(), TheBucket); | return *InsertIntoBucket(Key, ValueT(), TheBucket); | |||
} | } | |||
ValueT &operator[](KeyT &&Key) { | ValueT &operator[](KeyT &&Key) { | |||
return FindAndConstruct(Key).second; | return FindAndConstruct(Key).second; | |||
skipping to change at line 384 | skipping to change at line 402 | |||
BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value, | BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value, | |||
BucketT *TheBucket) { | BucketT *TheBucket) { | |||
TheBucket = InsertIntoBucketImpl(Key, TheBucket); | TheBucket = InsertIntoBucketImpl(Key, TheBucket); | |||
TheBucket->first = Key; | TheBucket->first = Key; | |||
new (&TheBucket->second) ValueT(Value); | new (&TheBucket->second) ValueT(Value); | |||
return TheBucket; | return TheBucket; | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value, | BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value, | |||
BucketT *TheBucket) { | BucketT *TheBucket) { | |||
TheBucket = InsertIntoBucketImpl(Key, TheBucket); | TheBucket = InsertIntoBucketImpl(Key, TheBucket); | |||
TheBucket->first = Key; | TheBucket->first = Key; | |||
new (&TheBucket->second) ValueT(std::move(Value)); | new (&TheBucket->second) ValueT(std::move(Value)); | |||
return TheBucket; | return TheBucket; | |||
} | } | |||
BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, BucketT *TheBucket) { | BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, BucketT *TheBucket) { | |||
skipping to change at line 431 | skipping to change at line 449 | |||
this->grow(NumBuckets * 2); | this->grow(NumBuckets * 2); | |||
LookupBucketFor(Key, TheBucket); | LookupBucketFor(Key, TheBucket); | |||
} | } | |||
assert(TheBucket); | assert(TheBucket); | |||
// Only update the state after we've grown our bucket space appropriate ly | // Only update the state after we've grown our bucket space appropriate ly | |||
// so that when growing buckets we have self-consistent entry count. | // so that when growing buckets we have self-consistent entry count. | |||
incrementNumEntries(); | incrementNumEntries(); | |||
// If we are writing over a tombstone, remember this. | // If we are writing over a tombstone, remember this. | |||
if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey())) | const KeyT EmptyKey = getEmptyKey(); | |||
if (!KeyInfoT::isEqual(TheBucket->first, EmptyKey)) | ||||
decrementNumTombstones(); | decrementNumTombstones(); | |||
return TheBucket; | return TheBucket; | |||
} | } | |||
/// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in | /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in | |||
/// FoundBucket. If the bucket contains the key and a value, this return s | /// FoundBucket. If the bucket contains the key and a value, this return s | |||
/// true, otherwise it returns a bucket with an empty marker or tombstone and | /// true, otherwise it returns a bucket with an empty marker or tombstone and | |||
/// returns false. | /// returns false. | |||
template<typename LookupKeyT> | template<typename LookupKeyT> | |||
skipping to change at line 475 | skipping to change at line 494 | |||
if (KeyInfoT::isEqual(Val, ThisBucket->first)) { | if (KeyInfoT::isEqual(Val, ThisBucket->first)) { | |||
FoundBucket = ThisBucket; | FoundBucket = ThisBucket; | |||
return true; | return true; | |||
} | } | |||
// If we found an empty bucket, the key doesn't exist in the set. | // If we found an empty bucket, the key doesn't exist in the set. | |||
// Insert it and return the default value. | // Insert it and return the default value. | |||
if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) { | if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) { | |||
// If we've already seen a tombstone while probing, fill it in inst ead | // If we've already seen a tombstone while probing, fill it in inst ead | |||
// of the empty bucket we eventually probed to. | // of the empty bucket we eventually probed to. | |||
if (FoundTombstone) ThisBucket = FoundTombstone; | ||||
FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket; | FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket; | |||
return false; | return false; | |||
} | } | |||
// If this is a tombstone, remember it. If Val ends up not in the ma p, we | // If this is a tombstone, remember it. If Val ends up not in the ma p, we | |||
// prefer to return it than something that would require more probing . | // prefer to return it than something that would require more probing . | |||
if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombs tone) | if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombs tone) | |||
FoundTombstone = ThisBucket; // Remember the first tombstone found . | FoundTombstone = ThisBucket; // Remember the first tombstone found . | |||
// Otherwise, it's a hash collision or a tombstone, continue quadrati c | // Otherwise, it's a hash collision or a tombstone, continue quadrati c | |||
skipping to change at line 532 | skipping to change at line 550 | |||
BucketT *Buckets; | BucketT *Buckets; | |||
unsigned NumEntries; | unsigned NumEntries; | |||
unsigned NumTombstones; | unsigned NumTombstones; | |||
unsigned NumBuckets; | unsigned NumBuckets; | |||
public: | public: | |||
explicit DenseMap(unsigned NumInitBuckets = 0) { | explicit DenseMap(unsigned NumInitBuckets = 0) { | |||
init(NumInitBuckets); | init(NumInitBuckets); | |||
} | } | |||
DenseMap(const DenseMap &other) { | DenseMap(const DenseMap &other) : BaseT() { | |||
init(0); | init(0); | |||
copyFrom(other); | copyFrom(other); | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
DenseMap(DenseMap &&other) { | DenseMap(DenseMap &&other) : BaseT() { | |||
init(0); | init(0); | |||
swap(other); | swap(other); | |||
} | } | |||
#endif | #endif | |||
template<typename InputIt> | template<typename InputIt> | |||
DenseMap(const InputIt &I, const InputIt &E) { | DenseMap(const InputIt &I, const InputIt &E) { | |||
init(NextPowerOf2(std::distance(I, E))); | init(NextPowerOf2(std::distance(I, E))); | |||
this->insert(I, E); | this->insert(I, E); | |||
} | } | |||
skipping to change at line 567 | skipping to change at line 585 | |||
std::swap(NumEntries, RHS.NumEntries); | std::swap(NumEntries, RHS.NumEntries); | |||
std::swap(NumTombstones, RHS.NumTombstones); | std::swap(NumTombstones, RHS.NumTombstones); | |||
std::swap(NumBuckets, RHS.NumBuckets); | std::swap(NumBuckets, RHS.NumBuckets); | |||
} | } | |||
DenseMap& operator=(const DenseMap& other) { | DenseMap& operator=(const DenseMap& other) { | |||
copyFrom(other); | copyFrom(other); | |||
return *this; | return *this; | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
DenseMap& operator=(DenseMap &&other) { | DenseMap& operator=(DenseMap &&other) { | |||
this->destroyAll(); | this->destroyAll(); | |||
operator delete(Buckets); | operator delete(Buckets); | |||
init(0); | init(0); | |||
swap(other); | swap(other); | |||
return *this; | return *this; | |||
} | } | |||
#endif | #endif | |||
void copyFrom(const DenseMap& other) { | void copyFrom(const DenseMap& other) { | |||
skipping to change at line 601 | skipping to change at line 619 | |||
} else { | } else { | |||
NumEntries = 0; | NumEntries = 0; | |||
NumTombstones = 0; | NumTombstones = 0; | |||
} | } | |||
} | } | |||
void grow(unsigned AtLeast) { | void grow(unsigned AtLeast) { | |||
unsigned OldNumBuckets = NumBuckets; | unsigned OldNumBuckets = NumBuckets; | |||
BucketT *OldBuckets = Buckets; | BucketT *OldBuckets = Buckets; | |||
allocateBuckets(std::max<unsigned>(64, NextPowerOf2(AtLeast-1))); | allocateBuckets(std::max<unsigned>(64, static_cast<unsigned>(NextPowerO f2(AtLeast-1)))); | |||
assert(Buckets); | assert(Buckets); | |||
if (!OldBuckets) { | if (!OldBuckets) { | |||
this->BaseT::initEmpty(); | this->BaseT::initEmpty(); | |||
return; | return; | |||
} | } | |||
this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets); | this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets); | |||
// Free the old table. | // Free the old table. | |||
operator delete(OldBuckets); | operator delete(OldBuckets); | |||
skipping to change at line 701 | skipping to change at line 719 | |||
public: | public: | |||
explicit SmallDenseMap(unsigned NumInitBuckets = 0) { | explicit SmallDenseMap(unsigned NumInitBuckets = 0) { | |||
init(NumInitBuckets); | init(NumInitBuckets); | |||
} | } | |||
SmallDenseMap(const SmallDenseMap &other) { | SmallDenseMap(const SmallDenseMap &other) { | |||
init(0); | init(0); | |||
copyFrom(other); | copyFrom(other); | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
SmallDenseMap(SmallDenseMap &&other) { | SmallDenseMap(SmallDenseMap &&other) { | |||
init(0); | init(0); | |||
swap(other); | swap(other); | |||
} | } | |||
#endif | #endif | |||
template<typename InputIt> | template<typename InputIt> | |||
SmallDenseMap(const InputIt &I, const InputIt &E) { | SmallDenseMap(const InputIt &I, const InputIt &E) { | |||
init(NextPowerOf2(std::distance(I, E))); | init(NextPowerOf2(std::distance(I, E))); | |||
this->insert(I, E); | this->insert(I, E); | |||
skipping to change at line 796 | skipping to change at line 814 | |||
// the TmpRep into its new home. | // the TmpRep into its new home. | |||
SmallSide.Small = false; | SmallSide.Small = false; | |||
new (SmallSide.getLargeRep()) LargeRep(llvm_move(TmpRep)); | new (SmallSide.getLargeRep()) LargeRep(llvm_move(TmpRep)); | |||
} | } | |||
SmallDenseMap& operator=(const SmallDenseMap& other) { | SmallDenseMap& operator=(const SmallDenseMap& other) { | |||
copyFrom(other); | copyFrom(other); | |||
return *this; | return *this; | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
SmallDenseMap& operator=(SmallDenseMap &&other) { | SmallDenseMap& operator=(SmallDenseMap &&other) { | |||
this->destroyAll(); | this->destroyAll(); | |||
deallocateBuckets(); | deallocateBuckets(); | |||
init(0); | init(0); | |||
swap(other); | swap(other); | |||
return *this; | return *this; | |||
} | } | |||
#endif | #endif | |||
void copyFrom(const SmallDenseMap& other) { | void copyFrom(const SmallDenseMap& other) { | |||
End of changes. 16 change blocks. | ||||
16 lines changed or deleted | 37 lines changed or added | |||
DenseSet.h | DenseSet.h | |||
---|---|---|---|---|
skipping to change at line 35 | skipping to change at line 35 | |||
template<typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT> > | template<typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT> > | |||
class DenseSet { | class DenseSet { | |||
typedef DenseMap<ValueT, char, ValueInfoT> MapTy; | typedef DenseMap<ValueT, char, ValueInfoT> MapTy; | |||
MapTy TheMap; | MapTy TheMap; | |||
public: | public: | |||
DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {} | DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {} | |||
explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) { } | explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) { } | |||
bool empty() const { return TheMap.empty(); } | bool empty() const { return TheMap.empty(); } | |||
unsigned size() const { return TheMap.size(); } | unsigned size() const { return TheMap.size(); } | |||
size_t getMemorySize() const { return TheMap.getMemorySize(); } | ||||
/// Grow the denseset so that it has at least Size buckets. Does not shri | /// Grow the DenseSet so that it has at least Size buckets. Will not shri | |||
nk | nk | |||
/// the Size of the set. | ||||
void resize(size_t Size) { TheMap.resize(Size); } | void resize(size_t Size) { TheMap.resize(Size); } | |||
void clear() { | void clear() { | |||
TheMap.clear(); | TheMap.clear(); | |||
} | } | |||
bool count(const ValueT &V) const { | bool count(const ValueT &V) const { | |||
return TheMap.count(V); | return TheMap.count(V); | |||
} | } | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 4 lines changed or added | |||
DependenceAnalysis.h | DependenceAnalysis.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// accesses. Currently, it is an implementation of the approach described i n | // accesses. Currently, it is an implementation of the approach described i n | |||
// | // | |||
// Practical Dependence Testing | // Practical Dependence Testing | |||
// Goff, Kennedy, Tseng | // Goff, Kennedy, Tseng | |||
// PLDI 1991 | // PLDI 1991 | |||
// | // | |||
// There's a single entry point that analyzes the dependence between a pair | // There's a single entry point that analyzes the dependence between a pair | |||
// of memory references in a function, returning either NULL, for no depend ence, | // of memory references in a function, returning either NULL, for no depend ence, | |||
// or a more-or-less detailed description of the dependence between them. | // or a more-or-less detailed description of the dependence between them. | |||
// | // | |||
// This pass exists to support the DependenceGraph pass. There are two sepa | ||||
rate | ||||
// passes because there's a useful separation of concerns. A dependence exi | ||||
sts | ||||
// if two conditions are met: | ||||
// | ||||
// 1) Two instructions reference the same memory location, and | ||||
// 2) There is a flow of control leading from one instruction to the oth | ||||
er. | ||||
// | ||||
// DependenceAnalysis attacks the first condition; DependenceGraph will att | ||||
ack | ||||
// the second (it's not yet ready). | ||||
// | ||||
// Please note that this is work in progress and the interface is subject t o | // Please note that this is work in progress and the interface is subject t o | |||
// change. | // change. | |||
// | // | |||
// Plausible changes: | // Plausible changes: | |||
// Return a set of more precise dependences instead of just one dependen ce | // Return a set of more precise dependences instead of just one dependen ce | |||
// summarizing all. | // summarizing all. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H | #ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H | |||
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H | #define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H | |||
#include "llvm/Instructions.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/ADT/SmallBitVector.h" | #include "llvm/ADT/SmallBitVector.h" | |||
#include "llvm/IR/Instructions.h" | ||||
#include "llvm/Pass.h" | ||||
namespace llvm { | namespace llvm { | |||
class AliasAnalysis; | class AliasAnalysis; | |||
class Loop; | class Loop; | |||
class LoopInfo; | class LoopInfo; | |||
class ScalarEvolution; | class ScalarEvolution; | |||
class SCEV; | class SCEV; | |||
class SCEVConstant; | class SCEVConstant; | |||
class raw_ostream; | class raw_ostream; | |||
/// Dependence - This class represents a dependence between two memory | /// Dependence - This class represents a dependence between two memory | |||
/// memory references in a function. It contains minimal information and | /// memory references in a function. It contains minimal information and | |||
/// is used in the very common situation where the compiler is unable to | /// is used in the very common situation where the compiler is unable to | |||
/// determine anything beyond the existence of a dependence; that is, it | /// determine anything beyond the existence of a dependence; that is, it | |||
/// represents a confused dependence (see also FullDependence). In most | /// represents a confused dependence (see also FullDependence). In most | |||
/// cases (for output, flow, and anti dependences), the dependence implie s | /// cases (for output, flow, and anti dependences), the dependence implie s | |||
/// an ordering, where the source must precede the destination; in contra st, | /// an ordering, where the source must precede the destination; in contra st, | |||
/// input dependences are unordered. | /// input dependences are unordered. | |||
class Dependence { | class Dependence { | |||
public: | public: | |||
Dependence(const Instruction *Source, | Dependence(Instruction *Source, | |||
const Instruction *Destination) : | Instruction *Destination) : | |||
Src(Source), Dst(Destination) {} | Src(Source), Dst(Destination) {} | |||
virtual ~Dependence() {} | virtual ~Dependence() {} | |||
/// Dependence::DVEntry - Each level in the distance/direction vector | /// Dependence::DVEntry - Each level in the distance/direction vector | |||
/// has a direction (or perhaps a union of several directions), and | /// has a direction (or perhaps a union of several directions), and | |||
/// perhaps a distance. | /// perhaps a distance. | |||
struct DVEntry { | struct DVEntry { | |||
enum { NONE = 0, | enum { NONE = 0, | |||
LT = 1, | LT = 1, | |||
EQ = 2, | EQ = 2, | |||
skipping to change at line 85 | skipping to change at line 95 | |||
bool PeelFirst : 1; // Peeling the first iteration will break depende nce. | bool PeelFirst : 1; // Peeling the first iteration will break depende nce. | |||
bool PeelLast : 1; // Peeling the last iteration will break the depe ndence. | bool PeelLast : 1; // Peeling the last iteration will break the depe ndence. | |||
bool Splitable : 1; // Splitting the loop will break dependence. | bool Splitable : 1; // Splitting the loop will break dependence. | |||
const SCEV *Distance; // NULL implies no distance available. | const SCEV *Distance; // NULL implies no distance available. | |||
DVEntry() : Direction(ALL), Scalar(true), PeelFirst(false), | DVEntry() : Direction(ALL), Scalar(true), PeelFirst(false), | |||
PeelLast(false), Splitable(false), Distance(NULL) { } | PeelLast(false), Splitable(false), Distance(NULL) { } | |||
}; | }; | |||
/// getSrc - Returns the source instruction for this dependence. | /// getSrc - Returns the source instruction for this dependence. | |||
/// | /// | |||
const Instruction *getSrc() const { return Src; } | Instruction *getSrc() const { return Src; } | |||
/// getDst - Returns the destination instruction for this dependence. | /// getDst - Returns the destination instruction for this dependence. | |||
/// | /// | |||
const Instruction *getDst() const { return Dst; } | Instruction *getDst() const { return Dst; } | |||
/// isInput - Returns true if this is an input dependence. | /// isInput - Returns true if this is an input dependence. | |||
/// | /// | |||
bool isInput() const; | bool isInput() const; | |||
/// isOutput - Returns true if this is an output dependence. | /// isOutput - Returns true if this is an output dependence. | |||
/// | /// | |||
bool isOutput() const; | bool isOutput() const; | |||
/// isFlow - Returns true if this is a flow (aka true) dependence. | /// isFlow - Returns true if this is a flow (aka true) dependence. | |||
skipping to change at line 161 | skipping to change at line 171 | |||
/// isScalar - Returns true if a particular level is scalar; that is, | /// isScalar - Returns true if a particular level is scalar; that is, | |||
/// if no subscript in the source or destination mention the induction | /// if no subscript in the source or destination mention the induction | |||
/// variable associated with the loop at this level. | /// variable associated with the loop at this level. | |||
virtual bool isScalar(unsigned Level) const; | virtual bool isScalar(unsigned Level) const; | |||
/// dump - For debugging purposes, dumps a dependence to OS. | /// dump - For debugging purposes, dumps a dependence to OS. | |||
/// | /// | |||
void dump(raw_ostream &OS) const; | void dump(raw_ostream &OS) const; | |||
private: | private: | |||
const Instruction *Src, *Dst; | Instruction *Src, *Dst; | |||
friend class DependenceAnalysis; | friend class DependenceAnalysis; | |||
}; | }; | |||
/// FullDependence - This class represents a dependence between two memor y | /// FullDependence - This class represents a dependence between two memor y | |||
/// references in a function. It contains detailed information about the | /// references in a function. It contains detailed information about the | |||
/// dependence (direction vectors, etc) and is used when the compiler is | /// dependence (direction vectors, etc.) and is used when the compiler is | |||
/// able to accurately analyze the interaction of the references; that is , | /// able to accurately analyze the interaction of the references; that is , | |||
/// it is not a confused dependence (see Dependence). In most cases | /// it is not a confused dependence (see Dependence). In most cases | |||
/// (for output, flow, and anti dependences), the dependence implies an | /// (for output, flow, and anti dependences), the dependence implies an | |||
/// ordering, where the source must precede the destination; in contrast, | /// ordering, where the source must precede the destination; in contrast, | |||
/// input dependences are unordered. | /// input dependences are unordered. | |||
class FullDependence : public Dependence { | class FullDependence : public Dependence { | |||
public: | public: | |||
FullDependence(const Instruction *Src, | FullDependence(Instruction *Src, | |||
const Instruction *Dst, | Instruction *Dst, | |||
bool LoopIndependent, | bool LoopIndependent, | |||
unsigned Levels); | unsigned Levels); | |||
~FullDependence() { | ~FullDependence() { | |||
delete DV; | delete[] DV; | |||
} | } | |||
/// isLoopIndependent - Returns true if this is a loop-independent | /// isLoopIndependent - Returns true if this is a loop-independent | |||
/// dependence. | /// dependence. | |||
bool isLoopIndependent() const { return LoopIndependent; } | bool isLoopIndependent() const { return LoopIndependent; } | |||
/// isConfused - Returns true if this dependence is confused | /// isConfused - Returns true if this dependence is confused | |||
/// (the compiler understands nothing and makes worst-case | /// (the compiler understands nothing and makes worst-case | |||
/// assumptions). | /// assumptions). | |||
bool isConfused() const { return false; } | bool isConfused() const { return false; } | |||
skipping to change at line 235 | skipping to change at line 245 | |||
unsigned short Levels; | unsigned short Levels; | |||
bool LoopIndependent; | bool LoopIndependent; | |||
bool Consistent; // Init to true, then refine. | bool Consistent; // Init to true, then refine. | |||
DVEntry *DV; | DVEntry *DV; | |||
friend class DependenceAnalysis; | friend class DependenceAnalysis; | |||
}; | }; | |||
/// DependenceAnalysis - This class is the main dependence-analysis drive r. | /// DependenceAnalysis - This class is the main dependence-analysis drive r. | |||
/// | /// | |||
class DependenceAnalysis : public FunctionPass { | class DependenceAnalysis : public FunctionPass { | |||
void operator=(const DependenceAnalysis &); // do not implement | void operator=(const DependenceAnalysis &) LLVM_DELETED_FUNCTION; | |||
DependenceAnalysis(const DependenceAnalysis &); // do not implement | DependenceAnalysis(const DependenceAnalysis &) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
/// depends - Tests for a dependence between the Src and Dst instructio ns. | /// depends - Tests for a dependence between the Src and Dst instructio ns. | |||
/// Returns NULL if no dependence; otherwise, returns a Dependence (or a | /// Returns NULL if no dependence; otherwise, returns a Dependence (or a | |||
/// FullDependence) with as much information as can be gleaned. | /// FullDependence) with as much information as can be gleaned. | |||
/// The flag PossiblyLoopIndependent should be set by the caller | /// The flag PossiblyLoopIndependent should be set by the caller | |||
/// if it appears that control flow can reach from Src to Dst | /// if it appears that control flow can reach from Src to Dst | |||
/// without traversing a loop back edge. | /// without traversing a loop back edge. | |||
Dependence *depends(const Instruction *Src, | Dependence *depends(Instruction *Src, | |||
const Instruction *Dst, | Instruction *Dst, | |||
bool PossiblyLoopIndependent); | bool PossiblyLoopIndependent); | |||
/// getSplitIteration - Give a dependence that's splitable at some | /// getSplitIteration - Give a dependence that's splittable at some | |||
/// particular level, return the iteration that should be used to split | /// particular level, return the iteration that should be used to split | |||
/// the loop. | /// the loop. | |||
/// | /// | |||
/// Generally, the dependence analyzer will be used to build | /// Generally, the dependence analyzer will be used to build | |||
/// a dependence graph for a function (basically a map from instruction s | /// a dependence graph for a function (basically a map from instruction s | |||
/// to dependences). Looking for cycles in the graph shows us loops | /// to dependences). Looking for cycles in the graph shows us loops | |||
/// that cannot be trivially vectorized/parallelized. | /// that cannot be trivially vectorized/parallelized. | |||
/// | /// | |||
/// We can try to improve the situation by examining all the dependence s | /// We can try to improve the situation by examining all the dependence s | |||
/// that make up the cycle, looking for ones we can break. | /// that make up the cycle, looking for ones we can break. | |||
End of changes. 13 change blocks. | ||||
16 lines changed or deleted | 30 lines changed or added | |||
DepthFirstIterator.h | DepthFirstIterator.h | |||
---|---|---|---|---|
skipping to change at line 37 | skipping to change at line 37 | |||
// This iterator stores the 'visited' set in an external set, which all ows | // This iterator stores the 'visited' set in an external set, which all ows | |||
// it to be more efficient, and allows external clients to use the set for | // it to be more efficient, and allows external clients to use the set for | |||
// other purposes. | // other purposes. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_DEPTHFIRSTITERATOR_H | #ifndef LLVM_ADT_DEPTHFIRSTITERATOR_H | |||
#define LLVM_ADT_DEPTHFIRSTITERATOR_H | #define LLVM_ADT_DEPTHFIRSTITERATOR_H | |||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | ||||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | ||||
#include <set> | #include <set> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
// df_iterator_storage - A private class which is used to figure out where to | // df_iterator_storage - A private class which is used to figure out where to | |||
// store the visited set. | // store the visited set. | |||
template<class SetType, bool External> // Non-external set | template<class SetType, bool External> // Non-external set | |||
class df_iterator_storage { | class df_iterator_storage { | |||
public: | public: | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
DerivedTypes.h | DerivedTypes.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the declarations of classes that represent "derived | // This file contains the declarations of classes that represent "derived | |||
// types". These are things like "arrays of x" or "structure of x, y, z" o r | // types". These are things like "arrays of x" or "structure of x, y, z" o r | |||
// "function returning x taking (y,z) as parameters", etc... | // "function returning x taking (y,z) as parameters", etc... | |||
// | // | |||
// The implementations of these classes live in the Type.cpp file. | // The implementations of these classes live in the Type.cpp file. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_DERIVED_TYPES_H | #ifndef LLVM_IR_DERIVEDTYPES_H | |||
#define LLVM_DERIVED_TYPES_H | #define LLVM_IR_DERIVEDTYPES_H | |||
#include "llvm/Type.h" | #include "llvm/IR/Type.h" | |||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/DataTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
class Value; | class Value; | |||
class APInt; | class APInt; | |||
class LLVMContext; | class LLVMContext; | |||
template<typename T> class ArrayRef; | template<typename T> class ArrayRef; | |||
class StringRef; | class StringRef; | |||
/// Class to represent integer types. Note that this class is also used to | /// Class to represent integer types. Note that this class is also used to | |||
skipping to change at line 87 | skipping to change at line 87 | |||
/// @returns a bit mask with ones set for all the bits of this type. | /// @returns a bit mask with ones set for all the bits of this type. | |||
/// @brief Get a bit mask for this type. | /// @brief Get a bit mask for this type. | |||
APInt getMask() const; | APInt getMask() const; | |||
/// This method determines if the width of this IntegerType is a power-of -2 | /// This method determines if the width of this IntegerType is a power-of -2 | |||
/// in terms of 8 bit bytes. | /// in terms of 8 bit bytes. | |||
/// @returns true if this is a power-of-2 byte width. | /// @returns true if this is a power-of-2 byte width. | |||
/// @brief Is this a power-of-2 byte-width IntegerType ? | /// @brief Is this a power-of-2 byte-width IntegerType ? | |||
bool isPowerOf2ByteWidth() const; | bool isPowerOf2ByteWidth() const; | |||
// Methods for support type inquiry through isa, cast, and dyn_cast. | /// Methods for support type inquiry through isa, cast, and dyn_cast. | |||
static inline bool classof(const Type *T) { | static inline bool classof(const Type *T) { | |||
return T->getTypeID() == IntegerTyID; | return T->getTypeID() == IntegerTyID; | |||
} | } | |||
}; | }; | |||
/// FunctionType - Class to represent function types | /// FunctionType - Class to represent function types | |||
/// | /// | |||
class FunctionType : public Type { | class FunctionType : public Type { | |||
FunctionType(const FunctionType &) LLVM_DELETED_FUNCTION; | FunctionType(const FunctionType &) LLVM_DELETED_FUNCTION; | |||
const FunctionType &operator=(const FunctionType &) LLVM_DELETED_FUNCTION ; | const FunctionType &operator=(const FunctionType &) LLVM_DELETED_FUNCTION ; | |||
skipping to change at line 119 | skipping to change at line 119 | |||
static FunctionType *get(Type *Result, bool isVarArg); | static FunctionType *get(Type *Result, bool isVarArg); | |||
/// isValidReturnType - Return true if the specified type is valid as a r eturn | /// isValidReturnType - Return true if the specified type is valid as a r eturn | |||
/// type. | /// type. | |||
static bool isValidReturnType(Type *RetTy); | static bool isValidReturnType(Type *RetTy); | |||
/// isValidArgumentType - Return true if the specified type is valid as a n | /// isValidArgumentType - Return true if the specified type is valid as a n | |||
/// argument type. | /// argument type. | |||
static bool isValidArgumentType(Type *ArgTy); | static bool isValidArgumentType(Type *ArgTy); | |||
bool isVarArg() const { return getSubclassData(); } | bool isVarArg() const { return getSubclassData()!=0; } | |||
Type *getReturnType() const { return ContainedTys[0]; } | Type *getReturnType() const { return ContainedTys[0]; } | |||
typedef Type::subtype_iterator param_iterator; | typedef Type::subtype_iterator param_iterator; | |||
param_iterator param_begin() const { return ContainedTys + 1; } | param_iterator param_begin() const { return ContainedTys + 1; } | |||
param_iterator param_end() const { return &ContainedTys[NumContainedTys]; } | param_iterator param_end() const { return &ContainedTys[NumContainedTys]; } | |||
// Parameter type accessors. | /// Parameter type accessors. | |||
Type *getParamType(unsigned i) const { return ContainedTys[i+1]; } | Type *getParamType(unsigned i) const { return ContainedTys[i+1]; } | |||
/// getNumParams - Return the number of fixed parameters this function ty pe | /// getNumParams - Return the number of fixed parameters this function ty pe | |||
/// requires. This does not consider varargs. | /// requires. This does not consider varargs. | |||
/// | /// | |||
unsigned getNumParams() const { return NumContainedTys - 1; } | unsigned getNumParams() const { return NumContainedTys - 1; } | |||
// Methods for support type inquiry through isa, cast, and dyn_cast. | /// Methods for support type inquiry through isa, cast, and dyn_cast. | |||
static inline bool classof(const Type *T) { | static inline bool classof(const Type *T) { | |||
return T->getTypeID() == FunctionTyID; | return T->getTypeID() == FunctionTyID; | |||
} | } | |||
}; | }; | |||
/// CompositeType - Common super class of ArrayType, StructType, PointerTyp e | /// CompositeType - Common super class of ArrayType, StructType, PointerTyp e | |||
/// and VectorType. | /// and VectorType. | |||
class CompositeType : public Type { | class CompositeType : public Type { | |||
protected: | protected: | |||
explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) { } | explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) { } | |||
public: | public: | |||
/// getTypeAtIndex - Given an index value into the type, return the type of | /// getTypeAtIndex - Given an index value into the type, return the type of | |||
/// the element. | /// the element. | |||
/// | /// | |||
Type *getTypeAtIndex(const Value *V); | Type *getTypeAtIndex(const Value *V); | |||
Type *getTypeAtIndex(unsigned Idx); | Type *getTypeAtIndex(unsigned Idx); | |||
bool indexValid(const Value *V) const; | bool indexValid(const Value *V) const; | |||
bool indexValid(unsigned Idx) const; | bool indexValid(unsigned Idx) const; | |||
// Methods for support type inquiry through isa, cast, and dyn_cast. | /// Methods for support type inquiry through isa, cast, and dyn_cast. | |||
static inline bool classof(const Type *T) { | static inline bool classof(const Type *T) { | |||
return T->getTypeID() == ArrayTyID || | return T->getTypeID() == ArrayTyID || | |||
T->getTypeID() == StructTyID || | T->getTypeID() == StructTyID || | |||
T->getTypeID() == PointerTyID || | T->getTypeID() == PointerTyID || | |||
T->getTypeID() == VectorTyID; | T->getTypeID() == VectorTyID; | |||
} | } | |||
}; | }; | |||
/// StructType - Class to represent struct types. There are two different kinds | /// StructType - Class to represent struct types. There are two different kinds | |||
/// of struct types: Literal structs and Identified structs. | /// of struct types: Literal structs and Identified structs. | |||
skipping to change at line 190 | skipping to change at line 190 | |||
/// other (if the struct is packed) or (if not packed) with padding between the | /// other (if the struct is packed) or (if not packed) with padding between the | |||
/// elements as defined by DataLayout (which is required to match what the code | /// elements as defined by DataLayout (which is required to match what the code | |||
/// generator for a target expects). | /// generator for a target expects). | |||
/// | /// | |||
class StructType : public CompositeType { | class StructType : public CompositeType { | |||
StructType(const StructType &) LLVM_DELETED_FUNCTION; | StructType(const StructType &) LLVM_DELETED_FUNCTION; | |||
const StructType &operator=(const StructType &) LLVM_DELETED_FUNCTION; | const StructType &operator=(const StructType &) LLVM_DELETED_FUNCTION; | |||
StructType(LLVMContext &C) | StructType(LLVMContext &C) | |||
: CompositeType(C, StructTyID), SymbolTableEntry(0) {} | : CompositeType(C, StructTyID), SymbolTableEntry(0) {} | |||
enum { | enum { | |||
// This is the contents of the SubClassData field. | /// This is the contents of the SubClassData field. | |||
SCDB_HasBody = 1, | SCDB_HasBody = 1, | |||
SCDB_Packed = 2, | SCDB_Packed = 2, | |||
SCDB_IsLiteral = 4, | SCDB_IsLiteral = 4, | |||
SCDB_IsSized = 8 | SCDB_IsSized = 8 | |||
}; | }; | |||
/// SymbolTableEntry - For a named struct that actually has a name, this is a | /// SymbolTableEntry - For a named struct that actually has a name, this is a | |||
/// pointer to the symbol table entry (maintained by LLVMContext) for the | /// pointer to the symbol table entry (maintained by LLVMContext) for the | |||
/// struct. This is null if the type is an literal struct or if it is | /// struct. This is null if the type is an literal struct or if it is | |||
/// a identified type that has an empty name. | /// a identified type that has an empty name. | |||
skipping to change at line 281 | skipping to change at line 281 | |||
// Iterator access to the elements. | // Iterator access to the elements. | |||
typedef Type::subtype_iterator element_iterator; | typedef Type::subtype_iterator element_iterator; | |||
element_iterator element_begin() const { return ContainedTys; } | element_iterator element_begin() const { return ContainedTys; } | |||
element_iterator element_end() const { return &ContainedTys[NumContainedT ys];} | element_iterator element_end() const { return &ContainedTys[NumContainedT ys];} | |||
/// isLayoutIdentical - Return true if this is layout identical to the | /// isLayoutIdentical - Return true if this is layout identical to the | |||
/// specified struct. | /// specified struct. | |||
bool isLayoutIdentical(StructType *Other) const; | bool isLayoutIdentical(StructType *Other) const; | |||
// Random access to the elements | /// Random access to the elements | |||
unsigned getNumElements() const { return NumContainedTys; } | unsigned getNumElements() const { return NumContainedTys; } | |||
Type *getElementType(unsigned N) const { | Type *getElementType(unsigned N) const { | |||
assert(N < NumContainedTys && "Element number out of range!"); | assert(N < NumContainedTys && "Element number out of range!"); | |||
return ContainedTys[N]; | return ContainedTys[N]; | |||
} | } | |||
// Methods for support type inquiry through isa, cast, and dyn_cast. | /// Methods for support type inquiry through isa, cast, and dyn_cast. | |||
static inline bool classof(const Type *T) { | static inline bool classof(const Type *T) { | |||
return T->getTypeID() == StructTyID; | return T->getTypeID() == StructTyID; | |||
} | } | |||
}; | }; | |||
/// SequentialType - This is the superclass of the array, pointer and vecto r | /// SequentialType - This is the superclass of the array, pointer and vecto r | |||
/// type classes. All of these represent "arrays" in memory. The array ty pe | /// type classes. All of these represent "arrays" in memory. The array ty pe | |||
/// represents a specifically sized array, pointer types are unsized/unknow n | /// represents a specifically sized array, pointer types are unsized/unknow n | |||
/// size arrays, vector types represent specifically sized arrays that | /// size arrays, vector types represent specifically sized arrays that | |||
/// allow for use of SIMD instructions. SequentialType holds the common | /// allow for use of SIMD instructions. SequentialType holds the common | |||
skipping to change at line 317 | skipping to change at line 317 | |||
protected: | protected: | |||
SequentialType(TypeID TID, Type *ElType) | SequentialType(TypeID TID, Type *ElType) | |||
: CompositeType(ElType->getContext(), TID), ContainedType(ElType) { | : CompositeType(ElType->getContext(), TID), ContainedType(ElType) { | |||
ContainedTys = &ContainedType; | ContainedTys = &ContainedType; | |||
NumContainedTys = 1; | NumContainedTys = 1; | |||
} | } | |||
public: | public: | |||
Type *getElementType() const { return ContainedTys[0]; } | Type *getElementType() const { return ContainedTys[0]; } | |||
// Methods for support type inquiry through isa, cast, and dyn_cast. | /// Methods for support type inquiry through isa, cast, and dyn_cast. | |||
static inline bool classof(const Type *T) { | static inline bool classof(const Type *T) { | |||
return T->getTypeID() == ArrayTyID || | return T->getTypeID() == ArrayTyID || | |||
T->getTypeID() == PointerTyID || | T->getTypeID() == PointerTyID || | |||
T->getTypeID() == VectorTyID; | T->getTypeID() == VectorTyID; | |||
} | } | |||
}; | }; | |||
/// ArrayType - Class to represent array types. | /// ArrayType - Class to represent array types. | |||
/// | /// | |||
class ArrayType : public SequentialType { | class ArrayType : public SequentialType { | |||
skipping to change at line 345 | skipping to change at line 345 | |||
/// ArrayType | /// ArrayType | |||
/// | /// | |||
static ArrayType *get(Type *ElementType, uint64_t NumElements); | static ArrayType *get(Type *ElementType, uint64_t NumElements); | |||
/// isValidElementType - Return true if the specified type is valid as a | /// isValidElementType - Return true if the specified type is valid as a | |||
/// element type. | /// element type. | |||
static bool isValidElementType(Type *ElemTy); | static bool isValidElementType(Type *ElemTy); | |||
uint64_t getNumElements() const { return NumElements; } | uint64_t getNumElements() const { return NumElements; } | |||
// Methods for support type inquiry through isa, cast, and dyn_cast. | /// Methods for support type inquiry through isa, cast, and dyn_cast. | |||
static inline bool classof(const Type *T) { | static inline bool classof(const Type *T) { | |||
return T->getTypeID() == ArrayTyID; | return T->getTypeID() == ArrayTyID; | |||
} | } | |||
}; | }; | |||
/// VectorType - Class to represent vector types. | /// VectorType - Class to represent vector types. | |||
/// | /// | |||
class VectorType : public SequentialType { | class VectorType : public SequentialType { | |||
unsigned NumElements; | unsigned NumElements; | |||
skipping to change at line 411 | skipping to change at line 411 | |||
/// @brief Return the number of elements in the Vector type. | /// @brief Return the number of elements in the Vector type. | |||
unsigned getNumElements() const { return NumElements; } | unsigned getNumElements() const { return NumElements; } | |||
/// @brief Return the number of bits in the Vector type. | /// @brief Return the number of bits in the Vector type. | |||
/// Returns zero when the vector is a vector of pointers. | /// Returns zero when the vector is a vector of pointers. | |||
unsigned getBitWidth() const { | unsigned getBitWidth() const { | |||
return NumElements * getElementType()->getPrimitiveSizeInBits(); | return NumElements * getElementType()->getPrimitiveSizeInBits(); | |||
} | } | |||
// Methods for support type inquiry through isa, cast, and dyn_cast. | /// Methods for support type inquiry through isa, cast, and dyn_cast. | |||
static inline bool classof(const Type *T) { | static inline bool classof(const Type *T) { | |||
return T->getTypeID() == VectorTyID; | return T->getTypeID() == VectorTyID; | |||
} | } | |||
}; | }; | |||
/// PointerType - Class to represent pointers. | /// PointerType - Class to represent pointers. | |||
/// | /// | |||
class PointerType : public SequentialType { | class PointerType : public SequentialType { | |||
PointerType(const PointerType &) LLVM_DELETED_FUNCTION; | PointerType(const PointerType &) LLVM_DELETED_FUNCTION; | |||
const PointerType &operator=(const PointerType &) LLVM_DELETED_FUNCTION; | const PointerType &operator=(const PointerType &) LLVM_DELETED_FUNCTION; | |||
skipping to change at line 441 | skipping to change at line 441 | |||
return PointerType::get(ElementType, 0); | return PointerType::get(ElementType, 0); | |||
} | } | |||
/// isValidElementType - Return true if the specified type is valid as a | /// isValidElementType - Return true if the specified type is valid as a | |||
/// element type. | /// element type. | |||
static bool isValidElementType(Type *ElemTy); | static bool isValidElementType(Type *ElemTy); | |||
/// @brief Return the address space of the Pointer type. | /// @brief Return the address space of the Pointer type. | |||
inline unsigned getAddressSpace() const { return getSubclassData(); } | inline unsigned getAddressSpace() const { return getSubclassData(); } | |||
// Implement support type inquiry through isa, cast, and dyn_cast. | /// Implement support type inquiry through isa, cast, and dyn_cast. | |||
static inline bool classof(const Type *T) { | static inline bool classof(const Type *T) { | |||
return T->getTypeID() == PointerTyID; | return T->getTypeID() == PointerTyID; | |||
} | } | |||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 15 change blocks. | ||||
16 lines changed or deleted | 16 lines changed or added | |||
Disassembler.h | Disassembler.h | |||
---|---|---|---|---|
skipping to change at line 142 | skipping to change at line 142 | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
extern "C" { | extern "C" { | |||
#endif /* !defined(__cplusplus) */ | #endif /* !defined(__cplusplus) */ | |||
/** | /** | |||
* Create a disassembler for the TripleName. Symbolic disassembly is suppo rted | * Create a disassembler for the TripleName. Symbolic disassembly is suppo rted | |||
* by passing a block of information in the DisInfo parameter and specifyin g the | * by passing a block of information in the DisInfo parameter and specifyin g the | |||
* TagType and callback functions as described above. These can all be pas sed | * TagType and callback functions as described above. These can all be pas sed | |||
* as NULL. If successful, this returns a disassembler context. If not, i t | * as NULL. If successful, this returns a disassembler context. If not, i t | |||
* returns NULL. | * returns NULL. This function is equivalent to calling LLVMCreateDisasmCPU | |||
() | ||||
* with an empty CPU name. | ||||
*/ | */ | |||
LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo , | LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo , | |||
int TagType, LLVMOpInfoCallback GetOp Info, | int TagType, LLVMOpInfoCallback GetOp Info, | |||
LLVMSymbolLookupCallback SymbolLookUp ); | LLVMSymbolLookupCallback SymbolLookUp ); | |||
/** | /** | |||
* Create a disassembler for the TripleName and a specific CPU. Symbolic | ||||
* disassembly is supported by passing a block of information in the DisInf | ||||
o | ||||
* parameter and specifying the TagType and callback functions as described | ||||
* above. These can all be passed * as NULL. If successful, this returns | ||||
a | ||||
* disassembler context. If not, it returns NULL. | ||||
*/ | ||||
LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CP | ||||
U, | ||||
void *DisInfo, int TagType, | ||||
LLVMOpInfoCallback GetOpInfo, | ||||
LLVMSymbolLookupCallback SymbolLoo | ||||
kUp); | ||||
/** | ||||
* Set the disassembler's options. Returns 1 if it can set the Options and 0 | * Set the disassembler's options. Returns 1 if it can set the Options and 0 | |||
* otherwise. | * otherwise. | |||
*/ | */ | |||
int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options); | int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options); | |||
/* The option to produce marked up assembly. */ | /* The option to produce marked up assembly. */ | |||
#define LLVMDisassembler_Option_UseMarkup 1 | #define LLVMDisassembler_Option_UseMarkup 1 | |||
/* The option to print immediates as hex. */ | ||||
#define LLVMDisassembler_Option_PrintImmHex 2 | ||||
/* The option use the other assembler printer variant */ | ||||
#define LLVMDisassembler_Option_AsmPrinterVariant 4 | ||||
/** | /** | |||
* Dispose of a disassembler context. | * Dispose of a disassembler context. | |||
*/ | */ | |||
void LLVMDisasmDispose(LLVMDisasmContextRef DC); | void LLVMDisasmDispose(LLVMDisasmContextRef DC); | |||
/** | /** | |||
* Disassemble a single instruction using the disassembler context specifie d in | * Disassemble a single instruction using the disassembler context specifie d in | |||
* the parameter DC. The bytes of the instruction are specified in the | * the parameter DC. The bytes of the instruction are specified in the | |||
* parameter Bytes, and contains at least BytesSize number of bytes. The | * parameter Bytes, and contains at least BytesSize number of bytes. The | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 23 lines changed or added | |||
Disassemblers.def | Disassemblers.def | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
|* The set of targets supported by LLVM is generated at configuration *| | |* The set of targets supported by LLVM is generated at configuration *| | |||
|* time, at which point this header is generated. Do not modify this *| | |* time, at which point this header is generated. Do not modify this *| | |||
|* header directly. *| | |* header directly. *| | |||
|* *| | |* *| | |||
\*===---------------------------------------------------------------------- ===*/ | \*===---------------------------------------------------------------------- ===*/ | |||
#ifndef LLVM_DISASSEMBLER | #ifndef LLVM_DISASSEMBLER | |||
# error Please define the macro LLVM_DISASSEMBLER(TargetName) | # error Please define the macro LLVM_DISASSEMBLER(TargetName) | |||
#endif | #endif | |||
LLVM_DISASSEMBLER(MBlaze) LLVM_DISASSEMBLER(Mips) LLVM_DISASSEMBLER(ARM) LL VM_DISASSEMBLER(X86) | LLVM_DISASSEMBLER(MBlaze) LLVM_DISASSEMBLER(XCore) LLVM_DISASSEMBLER(Mips) LLVM_DISASSEMBLER(ARM) LLVM_DISASSEMBLER(AArch64) LLVM_DISASSEMBLER(X86) | |||
#undef LLVM_DISASSEMBLER | #undef LLVM_DISASSEMBLER | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
DominatorInternals.h | DominatorInternals.h | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H | #ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H | |||
#define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H | #define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H | |||
#include "llvm/Analysis/Dominators.h" | ||||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/Analysis/Dominators.h" | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// DominatorTree construction - This pass constructs immediate dominator | // DominatorTree construction - This pass constructs immediate dominator | |||
// information for a flow-graph based on the algorithm described in this | // information for a flow-graph based on the algorithm described in this | |||
// document: | // document: | |||
// | // | |||
// A Fast Algorithm for Finding Dominators in a Flowgraph | // A Fast Algorithm for Finding Dominators in a Flowgraph | |||
// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141. | // T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141. | |||
// | // | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Dominators.h | Dominators.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the DominatorTree class, which provides fast and effic ient | // This file defines the DominatorTree class, which provides fast and effic ient | |||
// dominance queries. | // dominance queries. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_DOMINATORS_H | #ifndef LLVM_ANALYSIS_DOMINATORS_H | |||
#define LLVM_ANALYSIS_DOMINATORS_H | #define LLVM_ANALYSIS_DOMINATORS_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/Function.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/DepthFirstIterator.h" | #include "llvm/ADT/DepthFirstIterator.h" | |||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/IR/Function.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/Support/CFG.h" | #include "llvm/Support/CFG.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
#include <algorithm> | #include <algorithm> | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// DominatorBase - Base class that other, more interesting dominator analy ses | /// DominatorBase - Base class that other, more interesting dominator analy ses | |||
/// inherit from. | /// inherit from. | |||
skipping to change at line 103 | skipping to change at line 103 | |||
} | } | |||
size_t getNumChildren() const { | size_t getNumChildren() const { | |||
return Children.size(); | return Children.size(); | |||
} | } | |||
void clearAllChildren() { | void clearAllChildren() { | |||
Children.clear(); | Children.clear(); | |||
} | } | |||
bool compare(DomTreeNodeBase<NodeT> *Other) { | bool compare(const DomTreeNodeBase<NodeT> *Other) const { | |||
if (getNumChildren() != Other->getNumChildren()) | if (getNumChildren() != Other->getNumChildren()) | |||
return true; | return true; | |||
SmallPtrSet<NodeT *, 4> OtherChildren; | SmallPtrSet<const NodeT *, 4> OtherChildren; | |||
for (iterator I = Other->begin(), E = Other->end(); I != E; ++I) { | for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) | |||
NodeT *Nd = (*I)->getBlock(); | { | |||
const NodeT *Nd = (*I)->getBlock(); | ||||
OtherChildren.insert(Nd); | OtherChildren.insert(Nd); | |||
} | } | |||
for (iterator I = begin(), E = end(); I != E; ++I) { | for (const_iterator I = begin(), E = end(); I != E; ++I) { | |||
NodeT *N = (*I)->getBlock(); | const NodeT *N = (*I)->getBlock(); | |||
if (OtherChildren.count(N) == 0) | if (OtherChildren.count(N) == 0) | |||
return true; | return true; | |||
} | } | |||
return false; | return false; | |||
} | } | |||
void setIDom(DomTreeNodeBase<NodeT> *NewIDom) { | void setIDom(DomTreeNodeBase<NodeT> *NewIDom) { | |||
assert(IDom && "No immediate dominator?"); | assert(IDom && "No immediate dominator?"); | |||
if (IDom != NewIDom) { | if (IDom != NewIDom) { | |||
typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I = | typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I = | |||
skipping to change at line 665 | skipping to change at line 665 | |||
NodeT *entry = TraitsTy::getEntryNode(&F); | NodeT *entry = TraitsTy::getEntryNode(&F); | |||
this->Roots.push_back(entry); | this->Roots.push_back(entry); | |||
this->IDoms[entry] = 0; | this->IDoms[entry] = 0; | |||
this->DomTreeNodes[entry] = 0; | this->DomTreeNodes[entry] = 0; | |||
Calculate<FT, NodeT*>(*this, F); | Calculate<FT, NodeT*>(*this, F); | |||
} else { | } else { | |||
// Initialize the roots list | // Initialize the roots list | |||
for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F), | for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F), | |||
E = TraitsTy::nodes_end(&F); I != E ; ++I) { | E = TraitsTy::nodes_end(&F); I != E ; ++I) { | |||
if (std::distance(TraitsTy::child_begin(I), | if (TraitsTy::child_begin(I) == TraitsTy::child_end(I)) | |||
TraitsTy::child_end(I)) == 0) | ||||
addRoot(I); | addRoot(I); | |||
// Prepopulate maps so that we don't get iterator invalidation issu es later. | // Prepopulate maps so that we don't get iterator invalidation issu es later. | |||
this->IDoms[I] = 0; | this->IDoms[I] = 0; | |||
this->DomTreeNodes[I] = 0; | this->DomTreeNodes[I] = 0; | |||
} | } | |||
Calculate<FT, Inverse<NodeT*> >(*this, F); | Calculate<FT, Inverse<NodeT*> >(*this, F); | |||
} | } | |||
} | } | |||
End of changes. 6 change blocks. | ||||
10 lines changed or deleted | 10 lines changed or added | |||
Dwarf.h | Dwarf.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file contains constants used for implementing Dwarf debug support. For | // This file contains constants used for implementing Dwarf debug support. For | |||
// Details on the Dwarf 3 specfication see DWARF Debugging Information Form at | // Details on the Dwarf 3 specfication see DWARF Debugging Information Form at | |||
// V.3 reference manual http://dwarf.freestandards.org , | // V.3 reference manual http://dwarf.freestandards.org , | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_DWARF_H | #ifndef LLVM_SUPPORT_DWARF_H | |||
#define LLVM_SUPPORT_DWARF_H | #define LLVM_SUPPORT_DWARF_H | |||
#include "llvm/Support/DataTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Debug info constants. | // Debug info constants. | |||
enum { | enum { | |||
LLVMDebugVersion = (12 << 16), // Current version of debug informa tion. | LLVMDebugVersion = (12 << 16), // Current version of debug informa tion. | |||
LLVMDebugVersion11 = (11 << 16), // Constant for version 11. | LLVMDebugVersion11 = (11 << 16), // Constant for version 11. | |||
LLVMDebugVersion10 = (10 << 16), // Constant for version 10. | LLVMDebugVersion10 = (10 << 16), // Constant for version 10. | |||
LLVMDebugVersion9 = (9 << 16), // Constant for version 9. | LLVMDebugVersion9 = (9 << 16), // Constant for version 9. | |||
skipping to change at line 40 | skipping to change at line 42 | |||
LLVMDebugVersion7 = (7 << 16), // Constant for version 7. | LLVMDebugVersion7 = (7 << 16), // Constant for version 7. | |||
LLVMDebugVersion6 = (6 << 16), // Constant for version 6. | LLVMDebugVersion6 = (6 << 16), // Constant for version 6. | |||
LLVMDebugVersion5 = (5 << 16), // Constant for version 5. | LLVMDebugVersion5 = (5 << 16), // Constant for version 5. | |||
LLVMDebugVersion4 = (4 << 16), // Constant for version 4. | LLVMDebugVersion4 = (4 << 16), // Constant for version 4. | |||
LLVMDebugVersionMask = 0xffff0000 // Mask for version number. | LLVMDebugVersionMask = 0xffff0000 // Mask for version number. | |||
}; | }; | |||
namespace dwarf { | namespace dwarf { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Dwarf constants as gleaned from the DWARF Debugging Information Format V .3 | // Dwarf constants as gleaned from the DWARF Debugging Information Format V .4 | |||
// reference manual http://dwarf.freestandards.org . | // reference manual http://dwarf.freestandards.org . | |||
// | // | |||
// Do not mix the following two enumerations sets. DW_TAG_invalid changes the | // Do not mix the following two enumerations sets. DW_TAG_invalid changes the | |||
// enumeration base type. | // enumeration base type. | |||
enum llvm_dwarf_constants { | enum llvm_dwarf_constants { | |||
// llvm mock tags | // llvm mock tags | |||
DW_TAG_invalid = ~0U, // Tag for invalid results. | DW_TAG_invalid = ~0U, // Tag for invalid results. | |||
DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables. | DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables. | |||
DW_TAG_arg_variable = 0x101, // Tag for argument variables. | DW_TAG_arg_variable = 0x101, // Tag for argument variables. | |||
DW_TAG_return_variable = 0x102, // Tag for return variables. | ||||
DW_TAG_vector_type = 0x103, // Tag for vector types. | ||||
DW_TAG_user_base = 0x1000, // Recommended base for user tags. | DW_TAG_user_base = 0x1000, // Recommended base for user tags. | |||
DW_CIE_VERSION = 1, // Common frame information version | DW_CIE_VERSION = 1 // Common frame information version | |||
. | . | |||
DW_CIE_ID = 0xffffffff // Common frame information mark. | ||||
}; | }; | |||
// Special ID values that distinguish a CIE from a FDE in DWARF CFI. | ||||
// Not inside an enum because a 64-bit value is needed. | ||||
const uint32_t DW_CIE_ID = UINT32_MAX; | ||||
const uint64_t DW64_CIE_ID = UINT64_MAX; | ||||
enum dwarf_constants { | enum dwarf_constants { | |||
DWARF_VERSION = 2, | DWARF_VERSION = 2, | |||
// Tags | // Tags | |||
DW_TAG_array_type = 0x01, | DW_TAG_array_type = 0x01, | |||
DW_TAG_class_type = 0x02, | DW_TAG_class_type = 0x02, | |||
DW_TAG_entry_point = 0x03, | DW_TAG_entry_point = 0x03, | |||
DW_TAG_enumeration_type = 0x04, | DW_TAG_enumeration_type = 0x04, | |||
DW_TAG_formal_parameter = 0x05, | DW_TAG_formal_parameter = 0x05, | |||
DW_TAG_imported_declaration = 0x08, | DW_TAG_imported_declaration = 0x08, | |||
skipping to change at line 234 | skipping to change at line 238 | |||
DW_AT_endianity = 0x65, | DW_AT_endianity = 0x65, | |||
DW_AT_elemental = 0x66, | DW_AT_elemental = 0x66, | |||
DW_AT_pure = 0x67, | DW_AT_pure = 0x67, | |||
DW_AT_recursive = 0x68, | DW_AT_recursive = 0x68, | |||
DW_AT_signature = 0x69, | DW_AT_signature = 0x69, | |||
DW_AT_main_subprogram = 0x6a, | DW_AT_main_subprogram = 0x6a, | |||
DW_AT_data_bit_offset = 0x6b, | DW_AT_data_bit_offset = 0x6b, | |||
DW_AT_const_expr = 0x6c, | DW_AT_const_expr = 0x6c, | |||
DW_AT_enum_class = 0x6d, | DW_AT_enum_class = 0x6d, | |||
DW_AT_linkage_name = 0x6e, | DW_AT_linkage_name = 0x6e, | |||
DW_AT_lo_user = 0x2000, | ||||
DW_AT_hi_user = 0x3fff, | ||||
DW_AT_MIPS_loop_begin = 0x2002, | DW_AT_MIPS_loop_begin = 0x2002, | |||
DW_AT_MIPS_tail_loop_begin = 0x2003, | DW_AT_MIPS_tail_loop_begin = 0x2003, | |||
DW_AT_MIPS_epilog_begin = 0x2004, | DW_AT_MIPS_epilog_begin = 0x2004, | |||
DW_AT_MIPS_loop_unroll_factor = 0x2005, | DW_AT_MIPS_loop_unroll_factor = 0x2005, | |||
DW_AT_MIPS_software_pipeline_depth = 0x2006, | DW_AT_MIPS_software_pipeline_depth = 0x2006, | |||
DW_AT_MIPS_linkage_name = 0x2007, | DW_AT_MIPS_linkage_name = 0x2007, | |||
DW_AT_MIPS_stride = 0x2008, | DW_AT_MIPS_stride = 0x2008, | |||
DW_AT_MIPS_abstract_name = 0x2009, | DW_AT_MIPS_abstract_name = 0x2009, | |||
DW_AT_MIPS_clone_origin = 0x200a, | DW_AT_MIPS_clone_origin = 0x200a, | |||
DW_AT_MIPS_has_inlines = 0x200b, | DW_AT_MIPS_has_inlines = 0x200b, | |||
DW_AT_MIPS_stride_byte = 0x200c, | DW_AT_MIPS_stride_byte = 0x200c, | |||
DW_AT_MIPS_stride_elem = 0x200d, | DW_AT_MIPS_stride_elem = 0x200d, | |||
DW_AT_MIPS_ptr_dopetype = 0x200e, | DW_AT_MIPS_ptr_dopetype = 0x200e, | |||
DW_AT_MIPS_allocatable_dopetype = 0x200f, | DW_AT_MIPS_allocatable_dopetype = 0x200f, | |||
DW_AT_MIPS_assumed_shape_dopetype = 0x2010, | DW_AT_MIPS_assumed_shape_dopetype = 0x2010, | |||
// This one appears to have only been implemented by Open64 for | ||||
// fortran and may conflict with other extensions. | ||||
DW_AT_MIPS_assumed_size = 0x2011, | ||||
// GNU extensions | ||||
DW_AT_sf_names = 0x2101, | DW_AT_sf_names = 0x2101, | |||
DW_AT_src_info = 0x2102, | DW_AT_src_info = 0x2102, | |||
DW_AT_mac_info = 0x2103, | DW_AT_mac_info = 0x2103, | |||
DW_AT_src_coords = 0x2104, | DW_AT_src_coords = 0x2104, | |||
DW_AT_body_begin = 0x2105, | DW_AT_body_begin = 0x2105, | |||
DW_AT_body_end = 0x2106, | DW_AT_body_end = 0x2106, | |||
DW_AT_GNU_vector = 0x2107, | DW_AT_GNU_vector = 0x2107, | |||
DW_AT_GNU_template_name = 0x2110, | DW_AT_GNU_template_name = 0x2110, | |||
DW_AT_MIPS_assumed_size = 0x2011, | ||||
DW_AT_lo_user = 0x2000, | // Extensions for Fission proposal. | |||
DW_AT_hi_user = 0x3fff, | DW_AT_GNU_dwo_name = 0x2130, | |||
DW_AT_GNU_dwo_id = 0x2131, | ||||
DW_AT_GNU_ranges_base = 0x2132, | ||||
DW_AT_GNU_addr_base = 0x2133, | ||||
DW_AT_GNU_pubnames = 0x2134, | ||||
DW_AT_GNU_pubtypes = 0x2135, | ||||
// Apple extensions. | // Apple extensions. | |||
DW_AT_APPLE_optimized = 0x3fe1, | DW_AT_APPLE_optimized = 0x3fe1, | |||
DW_AT_APPLE_flags = 0x3fe2, | DW_AT_APPLE_flags = 0x3fe2, | |||
DW_AT_APPLE_isa = 0x3fe3, | DW_AT_APPLE_isa = 0x3fe3, | |||
DW_AT_APPLE_block = 0x3fe4, | DW_AT_APPLE_block = 0x3fe4, | |||
DW_AT_APPLE_major_runtime_vers = 0x3fe5, | DW_AT_APPLE_major_runtime_vers = 0x3fe5, | |||
DW_AT_APPLE_runtime_class = 0x3fe6, | DW_AT_APPLE_runtime_class = 0x3fe6, | |||
DW_AT_APPLE_omit_frame_ptr = 0x3fe7, | DW_AT_APPLE_omit_frame_ptr = 0x3fe7, | |||
DW_AT_APPLE_property_name = 0x3fe8, | DW_AT_APPLE_property_name = 0x3fe8, | |||
skipping to change at line 303 | skipping to change at line 322 | |||
DW_FORM_ref2 = 0x12, | DW_FORM_ref2 = 0x12, | |||
DW_FORM_ref4 = 0x13, | DW_FORM_ref4 = 0x13, | |||
DW_FORM_ref8 = 0x14, | DW_FORM_ref8 = 0x14, | |||
DW_FORM_ref_udata = 0x15, | DW_FORM_ref_udata = 0x15, | |||
DW_FORM_indirect = 0x16, | DW_FORM_indirect = 0x16, | |||
DW_FORM_sec_offset = 0x17, | DW_FORM_sec_offset = 0x17, | |||
DW_FORM_exprloc = 0x18, | DW_FORM_exprloc = 0x18, | |||
DW_FORM_flag_present = 0x19, | DW_FORM_flag_present = 0x19, | |||
DW_FORM_ref_sig8 = 0x20, | DW_FORM_ref_sig8 = 0x20, | |||
// Extensions for Fission proposal | ||||
DW_FORM_GNU_addr_index = 0x1f01, | ||||
DW_FORM_GNU_str_index = 0x1f02, | ||||
// Operation encodings | // Operation encodings | |||
DW_OP_addr = 0x03, | DW_OP_addr = 0x03, | |||
DW_OP_deref = 0x06, | DW_OP_deref = 0x06, | |||
DW_OP_const1u = 0x08, | DW_OP_const1u = 0x08, | |||
DW_OP_const1s = 0x09, | DW_OP_const1s = 0x09, | |||
DW_OP_const2u = 0x0a, | DW_OP_const2u = 0x0a, | |||
DW_OP_const2s = 0x0b, | DW_OP_const2s = 0x0b, | |||
DW_OP_const4u = 0x0c, | DW_OP_const4u = 0x0c, | |||
DW_OP_const4s = 0x0d, | DW_OP_const4s = 0x0d, | |||
DW_OP_const8u = 0x0e, | DW_OP_const8u = 0x0e, | |||
skipping to change at line 461 | skipping to change at line 484 | |||
DW_OP_call4 = 0x99, | DW_OP_call4 = 0x99, | |||
DW_OP_call_ref = 0x9a, | DW_OP_call_ref = 0x9a, | |||
DW_OP_form_tls_address = 0x9b, | DW_OP_form_tls_address = 0x9b, | |||
DW_OP_call_frame_cfa = 0x9c, | DW_OP_call_frame_cfa = 0x9c, | |||
DW_OP_bit_piece = 0x9d, | DW_OP_bit_piece = 0x9d, | |||
DW_OP_implicit_value = 0x9e, | DW_OP_implicit_value = 0x9e, | |||
DW_OP_stack_value = 0x9f, | DW_OP_stack_value = 0x9f, | |||
DW_OP_lo_user = 0xe0, | DW_OP_lo_user = 0xe0, | |||
DW_OP_hi_user = 0xff, | DW_OP_hi_user = 0xff, | |||
// Extensions for Fission proposal. | ||||
DW_OP_GNU_addr_index = 0xfb, | ||||
DW_OP_GNU_const_index = 0xfc, | ||||
// Encoding attribute values | // Encoding attribute values | |||
DW_ATE_address = 0x01, | DW_ATE_address = 0x01, | |||
DW_ATE_boolean = 0x02, | DW_ATE_boolean = 0x02, | |||
DW_ATE_complex_float = 0x03, | DW_ATE_complex_float = 0x03, | |||
DW_ATE_float = 0x04, | DW_ATE_float = 0x04, | |||
DW_ATE_signed = 0x05, | DW_ATE_signed = 0x05, | |||
DW_ATE_signed_char = 0x06, | DW_ATE_signed_char = 0x06, | |||
DW_ATE_unsigned = 0x07, | DW_ATE_unsigned = 0x07, | |||
DW_ATE_unsigned_char = 0x08, | DW_ATE_unsigned_char = 0x08, | |||
DW_ATE_imaginary_float = 0x09, | DW_ATE_imaginary_float = 0x09, | |||
End of changes. 10 change blocks. | ||||
9 lines changed or deleted | 36 lines changed or added | |||
DynamicLibrary.h | DynamicLibrary.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the sys::DynamicLibrary class. | // This file declares the sys::DynamicLibrary class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_DYNAMIC_LIBRARY_H | #ifndef LLVM_SYSTEM_DYNAMICLIBRARY_H | |||
#define LLVM_SYSTEM_DYNAMIC_LIBRARY_H | #define LLVM_SYSTEM_DYNAMICLIBRARY_H | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class StringRef; | class StringRef; | |||
namespace sys { | namespace sys { | |||
/// This class provides a portable interface to dynamic libraries which a lso | /// This class provides a portable interface to dynamic libraries which a lso | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
ELF.h | ELF.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the ELFObjectFile template class. | // This file declares the ELFObjectFile template class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_OBJECT_ELF_H | #ifndef LLVM_OBJECT_ELF_H | |||
#define LLVM_OBJECT_ELF_H | #define LLVM_OBJECT_ELF_H | |||
#include "llvm/ADT/DenseMap.h" | ||||
#include "llvm/ADT/PointerIntPair.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/StringSwitch.h" | #include "llvm/ADT/StringSwitch.h" | |||
#include "llvm/ADT/Triple.h" | #include "llvm/ADT/Triple.h" | |||
#include "llvm/ADT/DenseMap.h" | ||||
#include "llvm/ADT/PointerIntPair.h" | ||||
#include "llvm/Object/ObjectFile.h" | #include "llvm/Object/ObjectFile.h" | |||
#include "llvm/Support/Casting.h" | #include "llvm/Support/Casting.h" | |||
#include "llvm/Support/ELF.h" | #include "llvm/Support/ELF.h" | |||
#include "llvm/Support/Endian.h" | #include "llvm/Support/Endian.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include "llvm/Support/MemoryBuffer.h" | #include "llvm/Support/MemoryBuffer.h" | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
#include <algorithm> | #include <algorithm> | |||
#include <limits> | #include <limits> | |||
#include <utility> | #include <utility> | |||
namespace llvm { | namespace llvm { | |||
namespace object { | namespace object { | |||
using support::endianness; | ||||
template<endianness target_endianness, std::size_t max_alignment, bool is64 | ||||
Bits> | ||||
struct ELFType { | ||||
static const endianness TargetEndianness = target_endianness; | ||||
static const std::size_t MaxAlignment = max_alignment; | ||||
static const bool Is64Bits = is64Bits; | ||||
}; | ||||
template<typename T, int max_align> | ||||
struct MaximumAlignment { | ||||
enum {value = AlignOf<T>::Alignment > max_align ? max_align | ||||
: AlignOf<T>::Alignment}; | ||||
}; | ||||
// Subclasses of ELFObjectFile may need this for template instantiation | // Subclasses of ELFObjectFile may need this for template instantiation | |||
inline std::pair<unsigned char, unsigned char> | inline std::pair<unsigned char, unsigned char> | |||
getElfArchType(MemoryBuffer *Object) { | getElfArchType(MemoryBuffer *Object) { | |||
if (Object->getBufferSize() < ELF::EI_NIDENT) | if (Object->getBufferSize() < ELF::EI_NIDENT) | |||
return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATAN ONE); | return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATAN ONE); | |||
return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS] | return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS] | |||
, (uint8_t)Object->getBufferStart()[ELF::EI_DATA]); | , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]); | |||
} | } | |||
// Templates to choose Elf_Addr and Elf_Off depending on is64Bits. | // Templates to choose Elf_Addr and Elf_Off depending on is64Bits. | |||
template<support::endianness target_endianness> | template<endianness target_endianness, std::size_t max_alignment> | |||
struct ELFDataTypeTypedefHelperCommon { | struct ELFDataTypeTypedefHelperCommon { | |||
typedef support::detail::packed_endian_specific_integral | typedef support::detail::packed_endian_specific_integral | |||
<uint16_t, target_endianness, support::aligned> Elf_Half; | <uint16_t, target_endianness, | |||
MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half; | ||||
typedef support::detail::packed_endian_specific_integral | typedef support::detail::packed_endian_specific_integral | |||
<uint32_t, target_endianness, support::aligned> Elf_Word; | <uint32_t, target_endianness, | |||
MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word; | ||||
typedef support::detail::packed_endian_specific_integral | typedef support::detail::packed_endian_specific_integral | |||
<int32_t, target_endianness, support::aligned> Elf_Sword; | <int32_t, target_endianness, | |||
MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword; | ||||
typedef support::detail::packed_endian_specific_integral | typedef support::detail::packed_endian_specific_integral | |||
<uint64_t, target_endianness, support::aligned> Elf_Xword; | <uint64_t, target_endianness, | |||
MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword; | ||||
typedef support::detail::packed_endian_specific_integral | typedef support::detail::packed_endian_specific_integral | |||
<int64_t, target_endianness, support::aligned> Elf_Sxword; | <int64_t, target_endianness, | |||
MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword; | ||||
}; | }; | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct ELFDataTypeTypedefHelper; | struct ELFDataTypeTypedefHelper; | |||
/// ELF 32bit types. | /// ELF 32bit types. | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct ELFDataTypeTypedefHelper<target_endianness, false> | struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> | |||
: ELFDataTypeTypedefHelperCommon<target_endianness> { | > | |||
: ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { | ||||
typedef uint32_t value_type; | typedef uint32_t value_type; | |||
typedef support::detail::packed_endian_specific_integral | typedef support::detail::packed_endian_specific_integral | |||
<value_type, target_endianness, support::aligned> Elf_Addr; | <value_type, TargetEndianness, | |||
MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; | ||||
typedef support::detail::packed_endian_specific_integral | typedef support::detail::packed_endian_specific_integral | |||
<value_type, target_endianness, support::aligned> Elf_Off; | <value_type, TargetEndianness, | |||
MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; | ||||
}; | }; | |||
/// ELF 64bit types. | /// ELF 64bit types. | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct ELFDataTypeTypedefHelper<target_endianness, true> | struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> > | |||
: ELFDataTypeTypedefHelperCommon<target_endianness>{ | : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { | |||
typedef uint64_t value_type; | typedef uint64_t value_type; | |||
typedef support::detail::packed_endian_specific_integral | typedef support::detail::packed_endian_specific_integral | |||
<value_type, target_endianness, support::aligned> Elf_Addr; | <value_type, TargetEndianness, | |||
MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; | ||||
typedef support::detail::packed_endian_specific_integral | typedef support::detail::packed_endian_specific_integral | |||
<value_type, target_endianness, support::aligned> Elf_Off; | <value_type, TargetEndianness, | |||
MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; | ||||
}; | }; | |||
// I really don't like doing this, but the alternative is copypasta. | // I really don't like doing this, but the alternative is copypasta. | |||
#define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \ | #define LLVM_ELF_IMPORT_TYPES(E, M, W) | |||
typedef typename \ | \ | |||
ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; | typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Addr Elf_Ad | |||
\ | dr; \ | |||
typedef typename \ | typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Off Elf_Off | |||
ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \ | ; \ | |||
typedef typename \ | typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Half Elf_Ha | |||
ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; | lf; \ | |||
\ | typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Word Elf_Wo | |||
typedef typename \ | rd; \ | |||
ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; | typedef typename | |||
\ | \ | |||
typedef typename \ | ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Sword Elf_Sword; | |||
ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Swor | \ | |||
d; \ | typedef typename | |||
typedef typename \ | \ | |||
ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xwor | ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Xword Elf_Xword; | |||
d; \ | \ | |||
typedef typename \ | typedef typename | |||
ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxw | \ | |||
ord; | ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Sxword Elf_Sxword; | |||
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) | ||||
\ | ||||
LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, | ||||
\ | ||||
ELFT::Is64Bits) | ||||
// Section header. | // Section header. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Shdr_Base; | struct Elf_Shdr_Base; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Shdr_Base<target_endianness, false> { | struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, false) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) | |||
Elf_Word sh_name; // Section name (index into string table) | Elf_Word sh_name; // Section name (index into string table) | |||
Elf_Word sh_type; // Section type (SHT_*) | Elf_Word sh_type; // Section type (SHT_*) | |||
Elf_Word sh_flags; // Section flags (SHF_*) | Elf_Word sh_flags; // Section flags (SHF_*) | |||
Elf_Addr sh_addr; // Address where section is to be loaded | Elf_Addr sh_addr; // Address where section is to be loaded | |||
Elf_Off sh_offset; // File offset of section data, in bytes | Elf_Off sh_offset; // File offset of section data, in bytes | |||
Elf_Word sh_size; // Size of section, in bytes | Elf_Word sh_size; // Size of section, in bytes | |||
Elf_Word sh_link; // Section type-specific header table index link | Elf_Word sh_link; // Section type-specific header table index link | |||
Elf_Word sh_info; // Section type-specific extra information | Elf_Word sh_info; // Section type-specific extra information | |||
Elf_Word sh_addralign;// Section address alignment | Elf_Word sh_addralign;// Section address alignment | |||
Elf_Word sh_entsize; // Size of records contained within the section | Elf_Word sh_entsize; // Size of records contained within the section | |||
}; | }; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Shdr_Base<target_endianness, true> { | struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, true) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) | |||
Elf_Word sh_name; // Section name (index into string table) | Elf_Word sh_name; // Section name (index into string table) | |||
Elf_Word sh_type; // Section type (SHT_*) | Elf_Word sh_type; // Section type (SHT_*) | |||
Elf_Xword sh_flags; // Section flags (SHF_*) | Elf_Xword sh_flags; // Section flags (SHF_*) | |||
Elf_Addr sh_addr; // Address where section is to be loaded | Elf_Addr sh_addr; // Address where section is to be loaded | |||
Elf_Off sh_offset; // File offset of section data, in bytes | Elf_Off sh_offset; // File offset of section data, in bytes | |||
Elf_Xword sh_size; // Size of section, in bytes | Elf_Xword sh_size; // Size of section, in bytes | |||
Elf_Word sh_link; // Section type-specific header table index link | Elf_Word sh_link; // Section type-specific header table index link | |||
Elf_Word sh_info; // Section type-specific extra information | Elf_Word sh_info; // Section type-specific extra information | |||
Elf_Xword sh_addralign;// Section address alignment | Elf_Xword sh_addralign;// Section address alignment | |||
Elf_Xword sh_entsize; // Size of records contained within the section | Elf_Xword sh_entsize; // Size of records contained within the section | |||
}; | }; | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> { | struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> { | |||
using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize; | using Elf_Shdr_Base<ELFT>::sh_entsize; | |||
using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size; | using Elf_Shdr_Base<ELFT>::sh_size; | |||
/// @brief Get the number of entities this section contains if it has any . | /// @brief Get the number of entities this section contains if it has any . | |||
unsigned getEntityCount() const { | unsigned getEntityCount() const { | |||
if (sh_entsize == 0) | if (sh_entsize == 0) | |||
return 0; | return 0; | |||
return sh_size / sh_entsize; | return sh_size / sh_entsize; | |||
} | } | |||
}; | }; | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Sym_Base; | struct Elf_Sym_Base; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Sym_Base<target_endianness, false> { | struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, false) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) | |||
Elf_Word st_name; // Symbol name (index into string table) | Elf_Word st_name; // Symbol name (index into string table) | |||
Elf_Addr st_value; // Value or address associated with the symbol | Elf_Addr st_value; // Value or address associated with the symbol | |||
Elf_Word st_size; // Size of the symbol | Elf_Word st_size; // Size of the symbol | |||
unsigned char st_info; // Symbol's type and binding attributes | unsigned char st_info; // Symbol's type and binding attributes | |||
unsigned char st_other; // Must be zero; reserved | unsigned char st_other; // Must be zero; reserved | |||
Elf_Half st_shndx; // Which section (header table index) it's define d in | Elf_Half st_shndx; // Which section (header table index) it's define d in | |||
}; | }; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Sym_Base<target_endianness, true> { | struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, true) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) | |||
Elf_Word st_name; // Symbol name (index into string table) | Elf_Word st_name; // Symbol name (index into string table) | |||
unsigned char st_info; // Symbol's type and binding attributes | unsigned char st_info; // Symbol's type and binding attributes | |||
unsigned char st_other; // Must be zero; reserved | unsigned char st_other; // Must be zero; reserved | |||
Elf_Half st_shndx; // Which section (header table index) it's define d in | Elf_Half st_shndx; // Which section (header table index) it's define d in | |||
Elf_Addr st_value; // Value or address associated with the symbol | Elf_Addr st_value; // Value or address associated with the symbol | |||
Elf_Xword st_size; // Size of the symbol | Elf_Xword st_size; // Size of the symbol | |||
}; | }; | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> { | struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> { | |||
using Elf_Sym_Base<target_endianness, is64Bits>::st_info; | using Elf_Sym_Base<ELFT>::st_info; | |||
// These accessors and mutators correspond to the ELF32_ST_BIND, | // These accessors and mutators correspond to the ELF32_ST_BIND, | |||
// ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specificati on: | // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specificati on: | |||
unsigned char getBinding() const { return st_info >> 4; } | unsigned char getBinding() const { return st_info >> 4; } | |||
unsigned char getType() const { return st_info & 0x0f; } | unsigned char getType() const { return st_info & 0x0f; } | |||
void setBinding(unsigned char b) { setBindingAndType(b, getType()); } | void setBinding(unsigned char b) { setBindingAndType(b, getType()); } | |||
void setType(unsigned char t) { setBindingAndType(getBinding(), t); } | void setType(unsigned char t) { setBindingAndType(getBinding(), t); } | |||
void setBindingAndType(unsigned char b, unsigned char t) { | void setBindingAndType(unsigned char b, unsigned char t) { | |||
st_info = (b << 4) + (t & 0x0f); | st_info = (b << 4) + (t & 0x0f); | |||
} | } | |||
}; | }; | |||
/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym sect ion | /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym sect ion | |||
/// (.gnu.version). This structure is identical for ELF32 and ELF64. | /// (.gnu.version). This structure is identical for ELF32 and ELF64. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Versym_Impl { | struct Elf_Versym_Impl { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) | LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) | |||
Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN) | Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN) | |||
}; | }; | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Verdaux_Impl; | struct Elf_Verdaux_Impl; | |||
/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef sect ion | /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef sect ion | |||
/// (.gnu.version_d). This structure is identical for ELF32 and ELF64. | /// (.gnu.version_d). This structure is identical for ELF32 and ELF64. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Verdef_Impl { | struct Elf_Verdef_Impl { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) | LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) | |||
typedef Elf_Verdaux_Impl<target_endianness, is64Bits> Elf_Verdaux; | typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux; | |||
Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT) | Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT) | |||
Elf_Half vd_flags; // Bitwise flags (VER_DEF_*) | Elf_Half vd_flags; // Bitwise flags (VER_DEF_*) | |||
Elf_Half vd_ndx; // Version index, used in .gnu.version entries | Elf_Half vd_ndx; // Version index, used in .gnu.version entries | |||
Elf_Half vd_cnt; // Number of Verdaux entries | Elf_Half vd_cnt; // Number of Verdaux entries | |||
Elf_Word vd_hash; // Hash of name | Elf_Word vd_hash; // Hash of name | |||
Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes) | Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes) | |||
Elf_Word vd_next; // Offset to the next Verdef entry (in bytes) | Elf_Word vd_next; // Offset to the next Verdef entry (in bytes) | |||
/// Get the first Verdaux entry for this Verdef. | /// Get the first Verdaux entry for this Verdef. | |||
const Elf_Verdaux *getAux() const { | const Elf_Verdaux *getAux() const { | |||
return reinterpret_cast<const Elf_Verdaux*>((const char*)this + vd_aux) ; | return reinterpret_cast<const Elf_Verdaux*>((const char*)this + vd_aux) ; | |||
} | } | |||
}; | }; | |||
/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_ver def | /// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_ver def | |||
/// section (.gnu.version_d). This structure is identical for ELF32 and ELF 64. | /// section (.gnu.version_d). This structure is identical for ELF32 and ELF 64. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Verdaux_Impl { | struct Elf_Verdaux_Impl { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) | LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) | |||
Elf_Word vda_name; // Version name (offset in string table) | Elf_Word vda_name; // Version name (offset in string table) | |||
Elf_Word vda_next; // Offset to next Verdaux entry (in bytes) | Elf_Word vda_next; // Offset to next Verdaux entry (in bytes) | |||
}; | }; | |||
/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed | /// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed | |||
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF 64. | /// section (.gnu.version_r). This structure is identical for ELF32 and ELF 64. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Verneed_Impl { | struct Elf_Verneed_Impl { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) | LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) | |||
Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT) | Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT) | |||
Elf_Half vn_cnt; // Number of associated Vernaux entries | Elf_Half vn_cnt; // Number of associated Vernaux entries | |||
Elf_Word vn_file; // Library name (string table offset) | Elf_Word vn_file; // Library name (string table offset) | |||
Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes) | Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes) | |||
Elf_Word vn_next; // Offset to next Verneed entry (in bytes) | Elf_Word vn_next; // Offset to next Verneed entry (in bytes) | |||
}; | }; | |||
/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed | /// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed | |||
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF 64. | /// section (.gnu.version_r). This structure is identical for ELF32 and ELF 64. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Vernaux_Impl { | struct Elf_Vernaux_Impl { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) | LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) | |||
Elf_Word vna_hash; // Hash of dependency name | Elf_Word vna_hash; // Hash of dependency name | |||
Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*) | Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*) | |||
Elf_Half vna_other; // Version index, used in .gnu.version entries | Elf_Half vna_other; // Version index, used in .gnu.version entries | |||
Elf_Word vna_name; // Dependency name | Elf_Word vna_name; // Dependency name | |||
Elf_Word vna_next; // Offset to next Vernaux entry (in bytes) | Elf_Word vna_next; // Offset to next Vernaux entry (in bytes) | |||
}; | }; | |||
/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic | /// Elf_Dyn_Base: This structure matches the form of entries in the dynamic | |||
/// table section (.dynamic) look like. | /// table section (.dynamic) look like. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Dyn_Base; | struct Elf_Dyn_Base; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Dyn_Base<target_endianness, false> { | struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, false) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) | |||
Elf_Sword d_tag; | Elf_Sword d_tag; | |||
union { | union { | |||
Elf_Word d_val; | Elf_Word d_val; | |||
Elf_Addr d_ptr; | Elf_Addr d_ptr; | |||
} d_un; | } d_un; | |||
}; | }; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Dyn_Base<target_endianness, true> { | struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, true) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) | |||
Elf_Sxword d_tag; | Elf_Sxword d_tag; | |||
union { | union { | |||
Elf_Xword d_val; | Elf_Xword d_val; | |||
Elf_Addr d_ptr; | Elf_Addr d_ptr; | |||
} d_un; | } d_un; | |||
}; | }; | |||
/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and sette rs. | /// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and sette rs. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Dyn_Impl : Elf_Dyn_Base<target_endianness, is64Bits> { | struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> { | |||
using Elf_Dyn_Base<target_endianness, is64Bits>::d_tag; | using Elf_Dyn_Base<ELFT>::d_tag; | |||
using Elf_Dyn_Base<target_endianness, is64Bits>::d_un; | using Elf_Dyn_Base<ELFT>::d_un; | |||
int64_t getTag() const { return d_tag; } | int64_t getTag() const { return d_tag; } | |||
uint64_t getVal() const { return d_un.d_val; } | uint64_t getVal() const { return d_un.d_val; } | |||
uint64_t getPtr() const { return d_un.ptr; } | uint64_t getPtr() const { return d_un.ptr; } | |||
}; | }; | |||
template<support::endianness target_endianness, bool is64Bits> | ||||
class ELFObjectFile; | ||||
// DynRefImpl: Reference to an entry in the dynamic table | ||||
// This is an ELF-specific interface. | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
class DynRefImpl { | ||||
typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn; | ||||
typedef ELFObjectFile<target_endianness, is64Bits> OwningType; | ||||
DataRefImpl DynPimpl; | ||||
const OwningType *OwningObject; | ||||
public: | ||||
DynRefImpl() : OwningObject(NULL) { } | ||||
DynRefImpl(DataRefImpl DynP, const OwningType *Owner); | ||||
bool operator==(const DynRefImpl &Other) const; | ||||
bool operator <(const DynRefImpl &Other) const; | ||||
error_code getNext(DynRefImpl &Result) const; | ||||
int64_t getTag() const; | ||||
uint64_t getVal() const; | ||||
uint64_t getPtr() const; | ||||
DataRefImpl getRawDataRefImpl() const; | ||||
}; | ||||
// Elf_Rel: Elf Relocation | // Elf_Rel: Elf Relocation | |||
template<support::endianness target_endianness, bool is64Bits, bool isRela> | template<class ELFT, bool isRela> | |||
struct Elf_Rel_Base; | struct Elf_Rel_Base; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Rel_Base<target_endianness, false, false> { | struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, false) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) | |||
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) | Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) | |||
Elf_Word r_info; // Symbol table index and type of relocation to ap ply | Elf_Word r_info; // Symbol table index and type of relocation to ap ply | |||
uint32_t getRInfo(bool isMips64EL) const { | ||||
assert(!isMips64EL); | ||||
return r_info; | ||||
} | ||||
void setRInfo(uint32_t R) { | ||||
r_info = R; | ||||
} | ||||
}; | }; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Rel_Base<target_endianness, true, false> { | struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, true) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) | |||
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) | Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) | |||
Elf_Xword r_info; // Symbol table index and type of relocation to a pply | Elf_Xword r_info; // Symbol table index and type of relocation to a pply | |||
uint64_t getRInfo(bool isMips64EL) const { | ||||
uint64_t t = r_info; | ||||
if (!isMips64EL) | ||||
return t; | ||||
// Mip64 little endian has a "special" encoding of r_info. Instead of o | ||||
ne | ||||
// 64 bit little endian number, it is a little ending 32 bit number fol | ||||
lowed | ||||
// by a 32 bit big endian number. | ||||
return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | | ||||
((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); | ||||
return r_info; | ||||
} | ||||
void setRInfo(uint64_t R) { | ||||
// FIXME: Add mips64el support. | ||||
r_info = R; | ||||
} | ||||
}; | }; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Rel_Base<target_endianness, false, true> { | struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, false) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) | |||
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) | Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) | |||
Elf_Word r_info; // Symbol table index and type of relocation to a pply | Elf_Word r_info; // Symbol table index and type of relocation to a pply | |||
Elf_Sword r_addend; // Compute value for relocatable field by adding this | Elf_Sword r_addend; // Compute value for relocatable field by adding this | |||
uint32_t getRInfo(bool isMips64EL) const { | ||||
assert(!isMips64EL); | ||||
return r_info; | ||||
} | ||||
void setRInfo(uint32_t R) { | ||||
r_info = R; | ||||
} | ||||
}; | }; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Rel_Base<target_endianness, true, true> { | struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, true) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) | |||
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) | Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) | |||
Elf_Xword r_info; // Symbol table index and type of relocation to a pply | Elf_Xword r_info; // Symbol table index and type of relocation to a pply | |||
Elf_Sxword r_addend; // Compute value for relocatable field by adding this. | Elf_Sxword r_addend; // Compute value for relocatable field by adding this. | |||
uint64_t getRInfo(bool isMips64EL) const { | ||||
// Mip64 little endian has a "special" encoding of r_info. Instead of o | ||||
ne | ||||
// 64 bit little endian number, it is a little ending 32 bit number fol | ||||
lowed | ||||
// by a 32 bit big endian number. | ||||
uint64_t t = r_info; | ||||
if (!isMips64EL) | ||||
return t; | ||||
return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | | ||||
((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); | ||||
} | ||||
void setRInfo(uint64_t R) { | ||||
// FIXME: Add mips64el support. | ||||
r_info = R; | ||||
} | ||||
}; | }; | |||
template<support::endianness target_endianness, bool is64Bits, bool isRela> | template<class ELFT, bool isRela> | |||
struct Elf_Rel_Impl; | struct Elf_Rel_Impl; | |||
template<support::endianness target_endianness, bool isRela> | template<endianness TargetEndianness, std::size_t MaxAlign, bool isRela> | |||
struct Elf_Rel_Impl<target_endianness, true, isRela> | struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>, isRela> | |||
: Elf_Rel_Base<target_endianness, true, isRela> { | : Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, isRela> { | |||
using Elf_Rel_Base<target_endianness, true, isRela>::r_info; | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, true) | ||||
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TY PE, | // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TY PE, | |||
// and ELF64_R_INFO macros defined in the ELF specification: | // and ELF64_R_INFO macros defined in the ELF specification: | |||
uint64_t getSymbol() const { return (r_info >> 32); } | uint32_t getSymbol(bool isMips64EL) const { | |||
unsigned char getType() const { | return (uint32_t) (this->getRInfo(isMips64EL) >> 32); | |||
return (unsigned char) (r_info & 0xffffffffL); | ||||
} | } | |||
void setSymbol(uint64_t s) { setSymbolAndType(s, getType()); } | uint32_t getType(bool isMips64EL) const { | |||
void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } | return (uint32_t) (this->getRInfo(isMips64EL) & 0xffffffffL); | |||
void setSymbolAndType(uint64_t s, unsigned char t) { | } | |||
r_info = (s << 32) + (t&0xffffffffL); | void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } | |||
void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); } | ||||
void setSymbolAndType(uint32_t s, uint32_t t) { | ||||
this->setRInfo(((uint64_t)s << 32) + (t&0xffffffffL)); | ||||
} | } | |||
}; | }; | |||
template<support::endianness target_endianness, bool isRela> | template<endianness TargetEndianness, std::size_t MaxAlign, bool isRela> | |||
struct Elf_Rel_Impl<target_endianness, false, isRela> | struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>, isRela> | |||
: Elf_Rel_Base<target_endianness, false, isRela> { | : Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, isRela> { | |||
using Elf_Rel_Base<target_endianness, false, isRela>::r_info; | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, false) | ||||
// These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TY PE, | // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TY PE, | |||
// and ELF32_R_INFO macros defined in the ELF specification: | // and ELF32_R_INFO macros defined in the ELF specification: | |||
uint32_t getSymbol() const { return (r_info >> 8); } | uint32_t getSymbol(bool isMips64EL) const { | |||
unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); | return this->getRInfo(isMips64EL) >> 8; | |||
} | } | |||
unsigned char getType(bool isMips64EL) const { | ||||
return (unsigned char) (this->getRInfo(isMips64EL) & 0x0ff); | ||||
} | ||||
void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } | void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } | |||
void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } | void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } | |||
void setSymbolAndType(uint32_t s, unsigned char t) { | void setSymbolAndType(uint32_t s, unsigned char t) { | |||
r_info = (s << 8) + t; | this->setRInfo((s << 8) + t); | |||
} | } | |||
}; | }; | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Ehdr_Impl { | struct Elf_Ehdr_Impl { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) | LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) | |||
unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes | unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes | |||
Elf_Half e_type; // Type of file (see ET_*) | Elf_Half e_type; // Type of file (see ET_*) | |||
Elf_Half e_machine; // Required architecture for this file (see EM_*) | Elf_Half e_machine; // Required architecture for this file (see EM_*) | |||
Elf_Word e_version; // Must be equal to 1 | Elf_Word e_version; // Must be equal to 1 | |||
Elf_Addr e_entry; // Address to jump to in order to start program | Elf_Addr e_entry; // Address to jump to in order to start program | |||
Elf_Off e_phoff; // Program header table's file offset, in bytes | Elf_Off e_phoff; // Program header table's file offset, in bytes | |||
Elf_Off e_shoff; // Section header table's file offset, in bytes | Elf_Off e_shoff; // Section header table's file offset, in bytes | |||
Elf_Word e_flags; // Processor-specific flags | Elf_Word e_flags; // Processor-specific flags | |||
Elf_Half e_ehsize; // Size of ELF header, in bytes | Elf_Half e_ehsize; // Size of ELF header, in bytes | |||
Elf_Half e_phentsize;// Size of an entry in the program header table | Elf_Half e_phentsize;// Size of an entry in the program header table | |||
skipping to change at line 415 | skipping to change at line 461 | |||
Elf_Half e_shnum; // Number of entries in the section header table | Elf_Half e_shnum; // Number of entries in the section header table | |||
Elf_Half e_shstrndx; // Section header table index of section name | Elf_Half e_shstrndx; // Section header table index of section name | |||
// string table | // string table | |||
bool checkMagic() const { | bool checkMagic() const { | |||
return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; | return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; | |||
} | } | |||
unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; } | unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; } | |||
unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } | unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } | |||
}; | }; | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
struct Elf_Phdr; | struct Elf_Phdr_Impl; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Phdr<target_endianness, false> { | struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, false) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) | |||
Elf_Word p_type; // Type of segment | Elf_Word p_type; // Type of segment | |||
Elf_Off p_offset; // FileOffset where segment is located, in bytes | Elf_Off p_offset; // FileOffset where segment is located, in bytes | |||
Elf_Addr p_vaddr; // Virtual Address of beginning of segment | Elf_Addr p_vaddr; // Virtual Address of beginning of segment | |||
Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specif ic) | Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specif ic) | |||
Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero ) | Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero ) | |||
Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero) | Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero) | |||
Elf_Word p_flags; // Segment flags | Elf_Word p_flags; // Segment flags | |||
Elf_Word p_align; // Segment alignment constraint | Elf_Word p_align; // Segment alignment constraint | |||
}; | }; | |||
template<support::endianness target_endianness> | template<endianness TargetEndianness, std::size_t MaxAlign> | |||
struct Elf_Phdr<target_endianness, true> { | struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, true) | LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) | |||
Elf_Word p_type; // Type of segment | Elf_Word p_type; // Type of segment | |||
Elf_Word p_flags; // Segment flags | Elf_Word p_flags; // Segment flags | |||
Elf_Off p_offset; // FileOffset where segment is located, in bytes | Elf_Off p_offset; // FileOffset where segment is located, in bytes | |||
Elf_Addr p_vaddr; // Virtual Address of beginning of segment | Elf_Addr p_vaddr; // Virtual Address of beginning of segment | |||
Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specif ic) | Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specif ic) | |||
Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero | Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zer | |||
) | o) | |||
Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero) | Elf_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero | |||
Elf_Word p_align; // Segment alignment constraint | ) | |||
Elf_Xword p_align; // Segment alignment constraint | ||||
}; | }; | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
class ELFObjectFile : public ObjectFile { | class ELFObjectFile : public ObjectFile { | |||
LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) | LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) | |||
typedef Elf_Ehdr_Impl<target_endianness, is64Bits> Elf_Ehdr; | ||||
typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr; | ||||
typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym; | ||||
typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn; | ||||
typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel; | ||||
typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela; | ||||
typedef Elf_Verdef_Impl<target_endianness, is64Bits> Elf_Verdef; | ||||
typedef Elf_Verdaux_Impl<target_endianness, is64Bits> Elf_Verdaux; | ||||
typedef Elf_Verneed_Impl<target_endianness, is64Bits> Elf_Verneed; | ||||
typedef Elf_Vernaux_Impl<target_endianness, is64Bits> Elf_Vernaux; | ||||
typedef Elf_Versym_Impl<target_endianness, is64Bits> Elf_Versym; | ||||
typedef DynRefImpl<target_endianness, is64Bits> DynRef; | ||||
typedef content_iterator<DynRef> dyn_iterator; | ||||
protected: | ||||
// This flag is used for classof, to distinguish ELFObjectFile from | ||||
// its subclass. If more subclasses will be created, this flag will | ||||
// have to become an enum. | ||||
bool isDyldELFObject; | ||||
private: | ||||
typedef SmallVector<const Elf_Shdr*, 1> Sections_t; | ||||
typedef DenseMap<unsigned, unsigned> IndexMap_t; | ||||
typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t; | ||||
const Elf_Ehdr *Header; | ||||
const Elf_Shdr *SectionHeaderTable; | ||||
const Elf_Shdr *dot_shstrtab_sec; // Section header string table. | ||||
const Elf_Shdr *dot_strtab_sec; // Symbol header string table. | ||||
const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table. | ||||
// SymbolTableSections[0] always points to the dynamic string table secti | ||||
on | ||||
// header, or NULL if there is no dynamic string table. | ||||
Sections_t SymbolTableSections; | ||||
IndexMap_t SymbolTableSectionsIndexMap; | ||||
DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable; | ||||
const Elf_Shdr *dot_dynamic_sec; // .dynamic | ||||
const Elf_Shdr *dot_gnu_version_sec; // .gnu.version | ||||
const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r | ||||
const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d | ||||
// Pointer to SONAME entry in dynamic string table | ||||
// This is set the first time getLoadName is called. | ||||
mutable const char *dt_soname; | ||||
public: | public: | |||
/// \brief Iterate over relocations in a .rel or .rela section. | /// \brief Iterate over constant sized entities. | |||
template<class RelocT> | template<class EntT> | |||
class ELFRelocationIterator { | class ELFEntityIterator { | |||
public: | public: | |||
typedef void difference_type; | typedef ptrdiff_t difference_type; | |||
typedef const RelocT value_type; | typedef EntT value_type; | |||
typedef std::forward_iterator_tag iterator_category; | typedef std::random_access_iterator_tag iterator_category; | |||
typedef value_type &reference; | typedef value_type &reference; | |||
typedef value_type *pointer; | typedef value_type *pointer; | |||
/// \brief Default construct iterator. | /// \brief Default construct iterator. | |||
ELFRelocationIterator() : Section(0), Current(0) {} | ELFEntityIterator() : EntitySize(0), Current(0) {} | |||
ELFRelocationIterator(const Elf_Shdr *Sec, const char *Start) | ELFEntityIterator(uint64_t EntSize, const char *Start) | |||
: Section(Sec) | : EntitySize(EntSize) | |||
, Current(Start) {} | , Current(Start) {} | |||
reference operator *() { | reference operator *() { | |||
assert(Current && "Attempted to dereference an invalid iterator!"); | assert(Current && "Attempted to dereference an invalid iterator!"); | |||
return *reinterpret_cast<const RelocT*>(Current); | return *reinterpret_cast<pointer>(Current); | |||
} | } | |||
pointer operator ->() { | pointer operator ->() { | |||
assert(Current && "Attempted to dereference an invalid iterator!"); | assert(Current && "Attempted to dereference an invalid iterator!"); | |||
return reinterpret_cast<const RelocT*>(Current); | return reinterpret_cast<pointer>(Current); | |||
} | } | |||
bool operator ==(const ELFRelocationIterator &Other) { | bool operator ==(const ELFEntityIterator &Other) { | |||
return Section == Other.Section && Current == Other.Current; | return Current == Other.Current; | |||
} | } | |||
bool operator !=(const ELFRelocationIterator &Other) { | bool operator !=(const ELFEntityIterator &Other) { | |||
return !(*this == Other); | return !(*this == Other); | |||
} | } | |||
ELFRelocationIterator &operator ++(int) { | ELFEntityIterator &operator ++() { | |||
assert(Current && "Attempted to increment an invalid iterator!"); | assert(Current && "Attempted to increment an invalid iterator!"); | |||
Current += Section->sh_entsize; | Current += EntitySize; | |||
return *this; | return *this; | |||
} | } | |||
ELFRelocationIterator operator ++() { | ELFEntityIterator operator ++(int) { | |||
ELFRelocationIterator Tmp = *this; | ELFEntityIterator Tmp = *this; | |||
++*this; | ++*this; | |||
return Tmp; | return Tmp; | |||
} | } | |||
ELFEntityIterator &operator =(const ELFEntityIterator &Other) { | ||||
EntitySize = Other.EntitySize; | ||||
Current = Other.Current; | ||||
return *this; | ||||
} | ||||
difference_type operator -(const ELFEntityIterator &Other) const { | ||||
assert(EntitySize == Other.EntitySize && | ||||
"Subtracting iterators of different EntitiySize!"); | ||||
return (Current - Other.Current) / EntitySize; | ||||
} | ||||
const char *get() const { return Current; } | ||||
private: | private: | |||
const Elf_Shdr *Section; | uint64_t EntitySize; | |||
const char *Current; | const char *Current; | |||
}; | }; | |||
typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr; | ||||
typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; | ||||
typedef Elf_Sym_Impl<ELFT> Elf_Sym; | ||||
typedef Elf_Dyn_Impl<ELFT> Elf_Dyn; | ||||
typedef Elf_Phdr_Impl<ELFT> Elf_Phdr; | ||||
typedef Elf_Rel_Impl<ELFT, false> Elf_Rel; | ||||
typedef Elf_Rel_Impl<ELFT, true> Elf_Rela; | ||||
typedef Elf_Verdef_Impl<ELFT> Elf_Verdef; | ||||
typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux; | ||||
typedef Elf_Verneed_Impl<ELFT> Elf_Verneed; | ||||
typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux; | ||||
typedef Elf_Versym_Impl<ELFT> Elf_Versym; | ||||
typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_iterator; | ||||
typedef ELFEntityIterator<const Elf_Sym> Elf_Sym_iterator; | ||||
typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter; | ||||
typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter; | ||||
protected: | ||||
// This flag is used for classof, to distinguish ELFObjectFile from | ||||
// its subclass. If more subclasses will be created, this flag will | ||||
// have to become an enum. | ||||
bool isDyldELFObject; | ||||
private: | ||||
typedef SmallVector<const Elf_Shdr *, 2> Sections_t; | ||||
typedef DenseMap<unsigned, unsigned> IndexMap_t; | ||||
typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t; | ||||
const Elf_Ehdr *Header; | ||||
const Elf_Shdr *SectionHeaderTable; | ||||
const Elf_Shdr *dot_shstrtab_sec; // Section header string table. | ||||
const Elf_Shdr *dot_strtab_sec; // Symbol header string table. | ||||
const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table. | ||||
// SymbolTableSections[0] always points to the dynamic string table secti | ||||
on | ||||
// header, or NULL if there is no dynamic string table. | ||||
Sections_t SymbolTableSections; | ||||
IndexMap_t SymbolTableSectionsIndexMap; | ||||
DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable; | ||||
const Elf_Shdr *dot_dynamic_sec; // .dynamic | ||||
const Elf_Shdr *dot_gnu_version_sec; // .gnu.version | ||||
const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r | ||||
const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d | ||||
// Pointer to SONAME entry in dynamic string table | ||||
// This is set the first time getLoadName is called. | ||||
mutable const char *dt_soname; | ||||
private: | private: | |||
uint64_t getROffset(DataRefImpl Rel) const; | ||||
// Records for each version index the corresponding Verdef or Vernaux ent ry. | // Records for each version index the corresponding Verdef or Vernaux ent ry. | |||
// This is filled the first time LoadVersionMap() is called. | // This is filled the first time LoadVersionMap() is called. | |||
class VersionMapEntry : public PointerIntPair<const void*, 1> { | class VersionMapEntry : public PointerIntPair<const void*, 1> { | |||
public: | public: | |||
// If the integer is 0, this is an Elf_Verdef*. | // If the integer is 0, this is an Elf_Verdef*. | |||
// If the integer is 1, this is an Elf_Vernaux*. | // If the integer is 1, this is an Elf_Vernaux*. | |||
VersionMapEntry() : PointerIntPair<const void*, 1>(NULL, 0) { } | VersionMapEntry() : PointerIntPair<const void*, 1>(NULL, 0) { } | |||
VersionMapEntry(const Elf_Verdef *verdef) | VersionMapEntry(const Elf_Verdef *verdef) | |||
: PointerIntPair<const void*, 1>(verdef, 0) { } | : PointerIntPair<const void*, 1>(verdef, 0) { } | |||
VersionMapEntry(const Elf_Vernaux *vernaux) | VersionMapEntry(const Elf_Vernaux *vernaux) | |||
skipping to change at line 582 | skipping to change at line 647 | |||
/// @brief Map sections to an array of relocation sections that reference | /// @brief Map sections to an array of relocation sections that reference | |||
/// them sorted by section index. | /// them sorted by section index. | |||
RelocMap_t SectionRelocMap; | RelocMap_t SectionRelocMap; | |||
/// @brief Get the relocation section that contains \a Rel. | /// @brief Get the relocation section that contains \a Rel. | |||
const Elf_Shdr *getRelSection(DataRefImpl Rel) const { | const Elf_Shdr *getRelSection(DataRefImpl Rel) const { | |||
return getSection(Rel.w.b); | return getSection(Rel.w.b); | |||
} | } | |||
public: | ||||
bool isRelocationHasAddend(DataRefImpl Rel) const; | bool isRelocationHasAddend(DataRefImpl Rel) const; | |||
template<typename T> | template<typename T> | |||
const T *getEntry(uint16_t Section, uint32_t Entry) const; | const T *getEntry(uint16_t Section, uint32_t Entry) const; | |||
template<typename T> | template<typename T> | |||
const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const; | const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const; | |||
const Elf_Shdr *getSection(DataRefImpl index) const; | const Elf_Shdr *getSection(DataRefImpl index) const; | |||
const Elf_Shdr *getSection(uint32_t index) const; | const Elf_Shdr *getSection(uint32_t index) const; | |||
const Elf_Rel *getRel(DataRefImpl Rel) const; | const Elf_Rel *getRel(DataRefImpl Rel) const; | |||
const Elf_Rela *getRela(DataRefImpl Rela) const; | const Elf_Rela *getRela(DataRefImpl Rela) const; | |||
const char *getString(uint32_t section, uint32_t offset) const; | const char *getString(uint32_t section, uint32_t offset) const; | |||
const char *getString(const Elf_Shdr *section, uint32_t offset) const ; | const char *getString(const Elf_Shdr *section, uint32_t offset) const ; | |||
error_code getSymbolVersion(const Elf_Shdr *section, | error_code getSymbolVersion(const Elf_Shdr *section, | |||
const Elf_Sym *Symb, | const Elf_Sym *Symb, | |||
StringRef &Version, | StringRef &Version, | |||
bool &IsDefault) const; | bool &IsDefault) const; | |||
void VerifyStrTab(const Elf_Shdr *sh) const; | void VerifyStrTab(const Elf_Shdr *sh) const; | |||
protected: | protected: | |||
const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be pr ivate? | const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be pr ivate? | |||
void validateSymbol(DataRefImpl Symb) const; | void validateSymbol(DataRefImpl Symb) const; | |||
StringRef getRelocationTypeName(uint32_t Type) const; | ||||
public: | public: | |||
error_code getSymbolName(const Elf_Shdr *section, | error_code getSymbolName(const Elf_Shdr *section, | |||
const Elf_Sym *Symb, | const Elf_Sym *Symb, | |||
StringRef &Res) const; | StringRef &Res) const; | |||
error_code getSectionName(const Elf_Shdr *section, | error_code getSectionName(const Elf_Shdr *section, | |||
StringRef &Res) const; | StringRef &Res) const; | |||
const Elf_Dyn *getDyn(DataRefImpl DynData) const; | const Elf_Dyn *getDyn(DataRefImpl DynData) const; | |||
error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, | error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, | |||
bool &IsDefault) const; | bool &IsDefault) const; | |||
uint64_t getSymbolIndex(const Elf_Sym *sym) const; | ||||
protected: | protected: | |||
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; | virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; | |||
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; | virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; | |||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) c onst; | virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) c onst; | |||
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) cons t; | virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) cons t; | |||
virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) co nst; | ||||
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; | virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; | |||
virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const ; | virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const ; | |||
virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; | virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; | |||
virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; | virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; | |||
virtual error_code getSymbolSection(DataRefImpl Symb, | virtual error_code getSymbolSection(DataRefImpl Symb, | |||
section_iterator &Res) const; | section_iterator &Res) const; | |||
virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; | virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; | |||
friend class DynRefImpl<target_endianness, is64Bits>; | ||||
virtual error_code getDynNext(DataRefImpl DynData, DynRef &Result) const; | ||||
virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) c onst; | virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) c onst; | |||
virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const ; | virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const ; | |||
virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const ; | virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const ; | |||
virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; | virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; | |||
virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) cons t; | virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) cons t; | |||
virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; | virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; | |||
virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) co nst; | virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) co nst; | |||
virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) co nst; | virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) co nst; | |||
virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; | virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; | |||
skipping to change at line 669 | skipping to change at line 735 | |||
uint64_t &Res) const; | uint64_t &Res) const; | |||
virtual error_code getRelocationTypeName(DataRefImpl Rel, | virtual error_code getRelocationTypeName(DataRefImpl Rel, | |||
SmallVectorImpl<char> &Result) c onst; | SmallVectorImpl<char> &Result) c onst; | |||
virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, | virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, | |||
int64_t &Res) const; | int64_t &Res) const; | |||
virtual error_code getRelocationValueString(DataRefImpl Rel, | virtual error_code getRelocationValueString(DataRefImpl Rel, | |||
SmallVectorImpl<char> &Result) c onst; | SmallVectorImpl<char> &Result) c onst; | |||
public: | public: | |||
ELFObjectFile(MemoryBuffer *Object, error_code &ec); | ELFObjectFile(MemoryBuffer *Object, error_code &ec); | |||
bool isMips64EL() const { | ||||
return Header->e_machine == ELF::EM_MIPS && | ||||
Header->getFileClass() == ELF::ELFCLASS64 && | ||||
Header->getDataEncoding() == ELF::ELFDATA2LSB; | ||||
} | ||||
virtual symbol_iterator begin_symbols() const; | virtual symbol_iterator begin_symbols() const; | |||
virtual symbol_iterator end_symbols() const; | virtual symbol_iterator end_symbols() const; | |||
virtual symbol_iterator begin_dynamic_symbols() const; | virtual symbol_iterator begin_dynamic_symbols() const; | |||
virtual symbol_iterator end_dynamic_symbols() const; | virtual symbol_iterator end_dynamic_symbols() const; | |||
virtual section_iterator begin_sections() const; | virtual section_iterator begin_sections() const; | |||
virtual section_iterator end_sections() const; | virtual section_iterator end_sections() const; | |||
virtual library_iterator begin_libraries_needed() const; | virtual library_iterator begin_libraries_needed() const; | |||
virtual library_iterator end_libraries_needed() const; | virtual library_iterator end_libraries_needed() const; | |||
virtual dyn_iterator begin_dynamic_table() const; | const Elf_Shdr *getDynamicSymbolTableSectionHeader() const { | |||
virtual dyn_iterator end_dynamic_table() const; | return SymbolTableSections[0]; | |||
} | ||||
const Elf_Shdr *getDynamicStringTableSectionHeader() const { | ||||
return dot_dynstr_sec; | ||||
} | ||||
Elf_Dyn_iterator begin_dynamic_table() const; | ||||
/// \param NULLEnd use one past the first DT_NULL entry as the end instea | ||||
d of | ||||
/// the section size. | ||||
Elf_Dyn_iterator end_dynamic_table(bool NULLEnd = false) const; | ||||
typedef ELFRelocationIterator<Elf_Rela> Elf_Rela_Iter; | Elf_Sym_iterator begin_elf_dynamic_symbols() const { | |||
typedef ELFRelocationIterator<Elf_Rel> Elf_Rel_Iter; | const Elf_Shdr *DynSymtab = SymbolTableSections[0]; | |||
if (DynSymtab) | ||||
return Elf_Sym_iterator(DynSymtab->sh_entsize, | ||||
(const char *)base() + DynSymtab->sh_offset); | ||||
return Elf_Sym_iterator(0, 0); | ||||
} | ||||
virtual Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const { | Elf_Sym_iterator end_elf_dynamic_symbols() const { | |||
return Elf_Rela_Iter(sec, (const char *)(base() + sec->sh_offset)); | const Elf_Shdr *DynSymtab = SymbolTableSections[0]; | |||
if (DynSymtab) | ||||
return Elf_Sym_iterator(DynSymtab->sh_entsize, (const char *)base() + | ||||
DynSymtab->sh_offset + DynSymtab->sh_size); | ||||
return Elf_Sym_iterator(0, 0); | ||||
} | } | |||
virtual Elf_Rela_Iter endELFRela(const Elf_Shdr *sec) const { | Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const { | |||
return Elf_Rela_Iter(sec, (const char *) | return Elf_Rela_Iter(sec->sh_entsize, | |||
(const char *)(base() + sec->sh_offset)); | ||||
} | ||||
Elf_Rela_Iter endELFRela(const Elf_Shdr *sec) const { | ||||
return Elf_Rela_Iter(sec->sh_entsize, (const char *) | ||||
(base() + sec->sh_offset + sec->sh_size)); | (base() + sec->sh_offset + sec->sh_size)); | |||
} | } | |||
virtual Elf_Rel_Iter beginELFRel(const Elf_Shdr *sec) const { | Elf_Rel_Iter beginELFRel(const Elf_Shdr *sec) const { | |||
return Elf_Rel_Iter(sec, (const char *)(base() + sec->sh_offset)); | return Elf_Rel_Iter(sec->sh_entsize, | |||
(const char *)(base() + sec->sh_offset)); | ||||
} | } | |||
virtual Elf_Rel_Iter endELFRel(const Elf_Shdr *sec) const { | Elf_Rel_Iter endELFRel(const Elf_Shdr *sec) const { | |||
return Elf_Rel_Iter(sec, (const char *) | return Elf_Rel_Iter(sec->sh_entsize, (const char *) | |||
(base() + sec->sh_offset + sec->sh_size)); | (base() + sec->sh_offset + sec->sh_size)); | |||
} | } | |||
/// \brief Iterate over program header table. | ||||
typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter; | ||||
Elf_Phdr_Iter begin_program_headers() const { | ||||
return Elf_Phdr_Iter(Header->e_phentsize, | ||||
(const char*)base() + Header->e_phoff); | ||||
} | ||||
Elf_Phdr_Iter end_program_headers() const { | ||||
return Elf_Phdr_Iter(Header->e_phentsize, | ||||
(const char*)base() + | ||||
Header->e_phoff + | ||||
(Header->e_phnum * Header->e_phentsize)); | ||||
} | ||||
virtual uint8_t getBytesInAddress() const; | virtual uint8_t getBytesInAddress() const; | |||
virtual StringRef getFileFormatName() const; | virtual StringRef getFileFormatName() const; | |||
virtual StringRef getObjectType() const { return "ELF"; } | virtual StringRef getObjectType() const { return "ELF"; } | |||
virtual unsigned getArch() const; | virtual unsigned getArch() const; | |||
virtual StringRef getLoadName() const; | virtual StringRef getLoadName() const; | |||
virtual error_code getSectionContents(const Elf_Shdr *sec, | virtual error_code getSectionContents(const Elf_Shdr *sec, | |||
StringRef &Res) const; | StringRef &Res) const; | |||
uint64_t getNumSections() const; | uint64_t getNumSections() const; | |||
uint64_t getStringTableIndex() const; | uint64_t getStringTableIndex() const; | |||
ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const; | ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const; | |||
const Elf_Ehdr *getElfHeader() const; | ||||
const Elf_Shdr *getSection(const Elf_Sym *symb) const; | const Elf_Shdr *getSection(const Elf_Sym *symb) const; | |||
const Elf_Shdr *getElfSection(section_iterator &It) const; | const Elf_Shdr *getElfSection(section_iterator &It) const; | |||
const Elf_Sym *getElfSymbol(symbol_iterator &It) const; | const Elf_Sym *getElfSymbol(symbol_iterator &It) const; | |||
const Elf_Sym *getElfSymbol(uint32_t index) const; | const Elf_Sym *getElfSymbol(uint32_t index) const; | |||
// Methods for type inquiry through isa, cast, and dyn_cast | // Methods for type inquiry through isa, cast, and dyn_cast | |||
bool isDyldType() const { return isDyldELFObject; } | bool isDyldType() const { return isDyldELFObject; } | |||
static inline bool classof(const Binary *v) { | static inline bool classof(const Binary *v) { | |||
return v->getType() == getELFType(target_endianness == support::little, | return v->getType() == getELFType(ELFT::TargetEndianness == support::li | |||
is64Bits); | ttle, | |||
ELFT::Is64Bits); | ||||
} | } | |||
}; | }; | |||
// Iterate through the version definitions, and place each Elf_Verdef | // Iterate through the version definitions, and place each Elf_Verdef | |||
// in the VersionMap according to its index. | // in the VersionMap according to its index. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
void ELFObjectFile<target_endianness, is64Bits>:: | void ELFObjectFile<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const { | |||
LoadVersionDefs(const Elf_Shdr *sec) const { | ||||
unsigned vd_size = sec->sh_size; // Size of section in bytes | unsigned vd_size = sec->sh_size; // Size of section in bytes | |||
unsigned vd_count = sec->sh_info; // Number of Verdef entries | unsigned vd_count = sec->sh_info; // Number of Verdef entries | |||
const char *sec_start = (const char*)base() + sec->sh_offset; | const char *sec_start = (const char*)base() + sec->sh_offset; | |||
const char *sec_end = sec_start + vd_size; | const char *sec_end = sec_start + vd_size; | |||
// The first Verdef entry is at the start of the section. | // The first Verdef entry is at the start of the section. | |||
const char *p = sec_start; | const char *p = sec_start; | |||
for (unsigned i = 0; i < vd_count; i++) { | for (unsigned i = 0; i < vd_count; i++) { | |||
if (p + sizeof(Elf_Verdef) > sec_end) | if (p + sizeof(Elf_Verdef) > sec_end) | |||
report_fatal_error("Section ended unexpectedly while scanning " | report_fatal_error("Section ended unexpectedly while scanning " | |||
"version definitions."); | "version definitions."); | |||
skipping to change at line 757 | skipping to change at line 870 | |||
size_t index = vd->vd_ndx & ELF::VERSYM_VERSION; | size_t index = vd->vd_ndx & ELF::VERSYM_VERSION; | |||
if (index >= VersionMap.size()) | if (index >= VersionMap.size()) | |||
VersionMap.resize(index+1); | VersionMap.resize(index+1); | |||
VersionMap[index] = VersionMapEntry(vd); | VersionMap[index] = VersionMapEntry(vd); | |||
p += vd->vd_next; | p += vd->vd_next; | |||
} | } | |||
} | } | |||
// Iterate through the versions needed section, and place each Elf_Vernaux | // Iterate through the versions needed section, and place each Elf_Vernaux | |||
// in the VersionMap according to its index. | // in the VersionMap according to its index. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
void ELFObjectFile<target_endianness, is64Bits>:: | void ELFObjectFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const { | |||
LoadVersionNeeds(const Elf_Shdr *sec) const { | ||||
unsigned vn_size = sec->sh_size; // Size of section in bytes | unsigned vn_size = sec->sh_size; // Size of section in bytes | |||
unsigned vn_count = sec->sh_info; // Number of Verneed entries | unsigned vn_count = sec->sh_info; // Number of Verneed entries | |||
const char *sec_start = (const char*)base() + sec->sh_offset; | const char *sec_start = (const char*)base() + sec->sh_offset; | |||
const char *sec_end = sec_start + vn_size; | const char *sec_end = sec_start + vn_size; | |||
// The first Verneed entry is at the start of the section. | // The first Verneed entry is at the start of the section. | |||
const char *p = sec_start; | const char *p = sec_start; | |||
for (unsigned i = 0; i < vn_count; i++) { | for (unsigned i = 0; i < vn_count; i++) { | |||
if (p + sizeof(Elf_Verneed) > sec_end) | if (p + sizeof(Elf_Verneed) > sec_end) | |||
report_fatal_error("Section ended unexpectedly while scanning " | report_fatal_error("Section ended unexpectedly while scanning " | |||
"version needed records."); | "version needed records."); | |||
skipping to change at line 790 | skipping to change at line 902 | |||
size_t index = vna->vna_other & ELF::VERSYM_VERSION; | size_t index = vna->vna_other & ELF::VERSYM_VERSION; | |||
if (index >= VersionMap.size()) | if (index >= VersionMap.size()) | |||
VersionMap.resize(index+1); | VersionMap.resize(index+1); | |||
VersionMap[index] = VersionMapEntry(vna); | VersionMap[index] = VersionMapEntry(vna); | |||
paux += vna->vna_next; | paux += vna->vna_next; | |||
} | } | |||
p += vn->vn_next; | p += vn->vn_next; | |||
} | } | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
void ELFObjectFile<target_endianness, is64Bits>::LoadVersionMap() const { | void ELFObjectFile<ELFT>::LoadVersionMap() const { | |||
// If there is no dynamic symtab or version table, there is nothing to do . | // If there is no dynamic symtab or version table, there is nothing to do . | |||
if (SymbolTableSections[0] == NULL || dot_gnu_version_sec == NULL) | if (SymbolTableSections[0] == NULL || dot_gnu_version_sec == NULL) | |||
return; | return; | |||
// Has the VersionMap already been loaded? | // Has the VersionMap already been loaded? | |||
if (VersionMap.size() > 0) | if (VersionMap.size() > 0) | |||
return; | return; | |||
// The first two version indexes are reserved. | // The first two version indexes are reserved. | |||
// Index 0 is LOCAL, index 1 is GLOBAL. | // Index 0 is LOCAL, index 1 is GLOBAL. | |||
VersionMap.push_back(VersionMapEntry()); | VersionMap.push_back(VersionMapEntry()); | |||
VersionMap.push_back(VersionMapEntry()); | VersionMap.push_back(VersionMapEntry()); | |||
if (dot_gnu_version_d_sec) | if (dot_gnu_version_d_sec) | |||
LoadVersionDefs(dot_gnu_version_d_sec); | LoadVersionDefs(dot_gnu_version_d_sec); | |||
if (dot_gnu_version_r_sec) | if (dot_gnu_version_r_sec) | |||
LoadVersionNeeds(dot_gnu_version_r_sec); | LoadVersionNeeds(dot_gnu_version_r_sec); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
void ELFObjectFile<target_endianness, is64Bits> | void ELFObjectFile<ELFT>::validateSymbol(DataRefImpl Symb) const { | |||
::validateSymbol(DataRefImpl Symb) const { | #ifndef NDEBUG | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; | const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; | |||
// FIXME: We really need to do proper error handling in the case of an in valid | // FIXME: We really need to do proper error handling in the case of an in valid | |||
// input file. Because we don't use exceptions, I think we'll just pass | // input file. Because we don't use exceptions, I think we'll just pass | |||
// an error object around. | // an error object around. | |||
if (!( symb | if (!( symb | |||
&& SymbolTableSection | && SymbolTableSection | |||
&& symb >= (const Elf_Sym*)(base() | && symb >= (const Elf_Sym*)(base() | |||
+ SymbolTableSection->sh_offset) | + SymbolTableSection->sh_offset) | |||
&& symb < (const Elf_Sym*)(base() | && symb < (const Elf_Sym*)(base() | |||
+ SymbolTableSection->sh_offset | + SymbolTableSection->sh_offset | |||
+ SymbolTableSection->sh_size))) | + SymbolTableSection->sh_size))) | |||
// FIXME: Proper error handling. | // FIXME: Proper error handling. | |||
report_fatal_error("Symb must point to a valid symbol!"); | report_fatal_error("Symb must point to a valid symbol!"); | |||
#endif | ||||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb, | |||
::getSymbolNext(DataRefImpl Symb, | SymbolRef &Result) const { | |||
SymbolRef &Result) const { | ||||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; | const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; | |||
++Symb.d.a; | ++Symb.d.a; | |||
// Check to see if we are at the end of this symbol table. | // Check to see if we are at the end of this symbol table. | |||
if (Symb.d.a >= SymbolTableSection->getEntityCount()) { | if (Symb.d.a >= SymbolTableSection->getEntityCount()) { | |||
// We are at the end. If there are other symbol tables, jump to them. | // We are at the end. If there are other symbol tables, jump to them. | |||
// If the symbol table is .dynsym, we are iterating dynamic symbols, | // If the symbol table is .dynsym, we are iterating dynamic symbols, | |||
// and there is only one table of these. | // and there is only one table of these. | |||
if (Symb.d.b != 0) { | if (Symb.d.b != 0) { | |||
skipping to change at line 859 | skipping to change at line 971 | |||
if (Symb.d.b == 0 || Symb.d.b >= SymbolTableSections.size()) { | if (Symb.d.b == 0 || Symb.d.b >= SymbolTableSections.size()) { | |||
Symb.d.a = std::numeric_limits<uint32_t>::max(); | Symb.d.a = std::numeric_limits<uint32_t>::max(); | |||
Symb.d.b = std::numeric_limits<uint32_t>::max(); | Symb.d.b = std::numeric_limits<uint32_t>::max(); | |||
} | } | |||
} | } | |||
Result = SymbolRef(Symb, this); | Result = SymbolRef(Symb, this); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, | |||
::getSymbolName(DataRefImpl Symb, | StringRef &Result) const { | |||
StringRef &Result) const { | ||||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result); | return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef, | |||
::getSymbolVersion(SymbolRef SymRef, | StringRef &Version, | |||
StringRef &Version, | bool &IsDefault) const { | |||
bool &IsDefault) const { | ||||
DataRefImpl Symb = SymRef.getRawDataRefImpl(); | DataRefImpl Symb = SymRef.getRawDataRefImpl(); | |||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
return getSymbolVersion(SymbolTableSections[Symb.d.b], symb, | return getSymbolVersion(SymbolTableSections[Symb.d.b], symb, | |||
Version, IsDefault); | Version, IsDefault); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
ELF::Elf64_Word ELFObjectFile<target_endianness, is64Bits> | ELF::Elf64_Word ELFObjectFile<ELFT> | |||
::getSymbolTableIndex(const Elf_Sym *symb) const { | ::getSymbolTableIndex(const Elf_Sym *symb) con | |||
st { | ||||
if (symb->st_shndx == ELF::SHN_XINDEX) | if (symb->st_shndx == ELF::SHN_XINDEX) | |||
return ExtendedSymbolTable.lookup(symb); | return ExtendedSymbolTable.lookup(symb); | |||
return symb->st_shndx; | return symb->st_shndx; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * | const typename ELFObjectFile<ELFT>::Elf_Shdr * | |||
ELFObjectFile<target_endianness, is64Bits> | ELFObjectFile<ELFT>::getSection(const Elf_Sym *symb) const { | |||
::getSection(const Elf_Sym *symb) const { | ||||
if (symb->st_shndx == ELF::SHN_XINDEX) | if (symb->st_shndx == ELF::SHN_XINDEX) | |||
return getSection(ExtendedSymbolTable.lookup(symb)); | return getSection(ExtendedSymbolTable.lookup(symb)); | |||
if (symb->st_shndx >= ELF::SHN_LORESERVE) | if (symb->st_shndx >= ELF::SHN_LORESERVE) | |||
return 0; | return 0; | |||
return getSection(symb->st_shndx); | return getSection(symb->st_shndx); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * | const typename ELFObjectFile<ELFT>::Elf_Ehdr * | |||
ELFObjectFile<target_endianness, is64Bits> | ELFObjectFile<ELFT>::getElfHeader() const { | |||
::getElfSection(section_iterator &It) const { | return Header; | |||
} | ||||
template<class ELFT> | ||||
const typename ELFObjectFile<ELFT>::Elf_Shdr * | ||||
ELFObjectFile<ELFT>::getElfSection(section_iterator &It) const { | ||||
llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl(); | llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl(); | |||
return reinterpret_cast<const Elf_Shdr *>(ShdrRef.p); | return reinterpret_cast<const Elf_Shdr *>(ShdrRef.p); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym * | const typename ELFObjectFile<ELFT>::Elf_Sym * | |||
ELFObjectFile<target_endianness, is64Bits> | ELFObjectFile<ELFT>::getElfSymbol(symbol_iterator &It) const { | |||
::getElfSymbol(symbol_iterator &It) const { | ||||
return getSymbol(It->getRawDataRefImpl()); | return getSymbol(It->getRawDataRefImpl()); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym * | const typename ELFObjectFile<ELFT>::Elf_Sym * | |||
ELFObjectFile<target_endianness, is64Bits> | ELFObjectFile<ELFT>::getElfSymbol(uint32_t index) const { | |||
::getElfSymbol(uint32_t index) const { | ||||
DataRefImpl SymbolData; | DataRefImpl SymbolData; | |||
SymbolData.d.a = index; | SymbolData.d.a = index; | |||
SymbolData.d.b = 1; | SymbolData.d.b = 1; | |||
return getSymbol(SymbolData); | return getSymbol(SymbolData); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb, | |||
::getSymbolFileOffset(DataRefImpl Symb, | uint64_t &Result) const | |||
uint64_t &Result) const { | { | |||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
const Elf_Shdr *Section; | const Elf_Shdr *Section; | |||
switch (getSymbolTableIndex(symb)) { | switch (getSymbolTableIndex(symb)) { | |||
case ELF::SHN_COMMON: | case ELF::SHN_COMMON: | |||
// Unintialized symbols have no offset in the object file | // Unintialized symbols have no offset in the object file | |||
case ELF::SHN_UNDEF: | case ELF::SHN_UNDEF: | |||
Result = UnknownAddressOrSize; | Result = UnknownAddressOrSize; | |||
return object_error::success; | return object_error::success; | |||
case ELF::SHN_ABS: | case ELF::SHN_ABS: | |||
Result = symb->st_value; | Result = symb->st_value; | |||
return object_error::success; | return object_error::success; | |||
default: Section = getSection(symb); | default: Section = getSection(symb); | |||
} | } | |||
switch (symb->getType()) { | switch (symb->getType()) { | |||
case ELF::STT_SECTION: | case ELF::STT_SECTION: | |||
Result = Section ? Section->sh_addr : UnknownAddressOrSize; | Result = Section ? Section->sh_offset : UnknownAddressOrSize; | |||
return object_error::success; | return object_error::success; | |||
case ELF::STT_FUNC: | case ELF::STT_FUNC: | |||
case ELF::STT_OBJECT: | case ELF::STT_OBJECT: | |||
case ELF::STT_NOTYPE: | case ELF::STT_NOTYPE: | |||
Result = symb->st_value + | Result = symb->st_value + | |||
(Section ? Section->sh_offset : 0); | (Section ? Section->sh_offset : 0); | |||
return object_error::success; | return object_error::success; | |||
default: | default: | |||
Result = UnknownAddressOrSize; | Result = UnknownAddressOrSize; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, | |||
::getSymbolAddress(DataRefImpl Symb, | uint64_t &Result) const { | |||
uint64_t &Result) const { | ||||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
const Elf_Shdr *Section; | const Elf_Shdr *Section; | |||
switch (getSymbolTableIndex(symb)) { | switch (getSymbolTableIndex(symb)) { | |||
case ELF::SHN_COMMON: | case ELF::SHN_COMMON: | |||
case ELF::SHN_UNDEF: | case ELF::SHN_UNDEF: | |||
Result = UnknownAddressOrSize; | Result = UnknownAddressOrSize; | |||
return object_error::success; | return object_error::success; | |||
case ELF::SHN_ABS: | case ELF::SHN_ABS: | |||
Result = symb->st_value; | Result = symb->st_value; | |||
skipping to change at line 994 | skipping to change at line 1104 | |||
bool IsRelocatable; | bool IsRelocatable; | |||
switch(Header->e_type) { | switch(Header->e_type) { | |||
case ELF::ET_EXEC: | case ELF::ET_EXEC: | |||
case ELF::ET_DYN: | case ELF::ET_DYN: | |||
IsRelocatable = false; | IsRelocatable = false; | |||
break; | break; | |||
default: | default: | |||
IsRelocatable = true; | IsRelocatable = true; | |||
} | } | |||
Result = symb->st_value; | Result = symb->st_value; | |||
// Clear the ARM/Thumb indicator flag. | ||||
if (Header->e_machine == ELF::EM_ARM) | ||||
Result &= ~1; | ||||
if (IsRelocatable && Section != 0) | if (IsRelocatable && Section != 0) | |||
Result += Section->sh_addr; | Result += Section->sh_addr; | |||
return object_error::success; | return object_error::success; | |||
default: | default: | |||
Result = UnknownAddressOrSize; | Result = UnknownAddressOrSize; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb, | |||
::getSymbolSize(DataRefImpl Symb, | uint32_t &Res) const { | |||
uint64_t &Result) const { | uint32_t flags; | |||
getSymbolFlags(Symb, flags); | ||||
if (flags & SymbolRef::SF_Common) { | ||||
uint64_t Value; | ||||
getSymbolValue(Symb, Value); | ||||
Res = Value; | ||||
} else { | ||||
Res = 0; | ||||
} | ||||
return object_error::success; | ||||
} | ||||
template<class ELFT> | ||||
error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb, | ||||
uint64_t &Result) const { | ||||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
if (symb->st_size == 0) | if (symb->st_size == 0) | |||
Result = UnknownAddressOrSize; | Result = UnknownAddressOrSize; | |||
Result = symb->st_size; | Result = symb->st_size; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolNMTypeChar(DataRefImpl Symb, | |||
::getSymbolNMTypeChar(DataRefImpl Symb, | char &Result) const { | |||
char &Result) const { | ||||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
const Elf_Shdr *Section = getSection(symb); | const Elf_Shdr *Section = getSection(symb); | |||
char ret = '?'; | char ret = '?'; | |||
if (Section) { | if (Section) { | |||
switch (Section->sh_type) { | switch (Section->sh_type) { | |||
case ELF::SHT_PROGBITS: | case ELF::SHT_PROGBITS: | |||
case ELF::SHT_DYNAMIC: | case ELF::SHT_DYNAMIC: | |||
skipping to change at line 1080 | skipping to change at line 1208 | |||
.StartsWith(".debug", 'N') | .StartsWith(".debug", 'N') | |||
.StartsWith(".note", 'n') | .StartsWith(".note", 'n') | |||
.Default('?'); | .Default('?'); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
Result = ret; | Result = ret; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, | |||
::getSymbolType(DataRefImpl Symb, | SymbolRef::Type &Result) cons | |||
SymbolRef::Type &Result) const { | t { | |||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
switch (symb->getType()) { | switch (symb->getType()) { | |||
case ELF::STT_NOTYPE: | case ELF::STT_NOTYPE: | |||
Result = SymbolRef::ST_Unknown; | Result = SymbolRef::ST_Unknown; | |||
break; | break; | |||
case ELF::STT_SECTION: | case ELF::STT_SECTION: | |||
Result = SymbolRef::ST_Debug; | Result = SymbolRef::ST_Debug; | |||
break; | break; | |||
skipping to change at line 1112 | skipping to change at line 1239 | |||
case ELF::STT_TLS: | case ELF::STT_TLS: | |||
Result = SymbolRef::ST_Data; | Result = SymbolRef::ST_Data; | |||
break; | break; | |||
default: | default: | |||
Result = SymbolRef::ST_Other; | Result = SymbolRef::ST_Other; | |||
break; | break; | |||
} | } | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb, | |||
::getSymbolFlags(DataRefImpl Symb, | uint32_t &Result) const { | |||
uint32_t &Result) const { | ||||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
Result = SymbolRef::SF_None; | Result = SymbolRef::SF_None; | |||
if (symb->getBinding() != ELF::STB_LOCAL) | if (symb->getBinding() != ELF::STB_LOCAL) | |||
Result |= SymbolRef::SF_Global; | Result |= SymbolRef::SF_Global; | |||
if (symb->getBinding() == ELF::STB_WEAK) | if (symb->getBinding() == ELF::STB_WEAK) | |||
Result |= SymbolRef::SF_Weak; | Result |= SymbolRef::SF_Weak; | |||
skipping to change at line 1147 | skipping to change at line 1273 | |||
if (symb->getType() == ELF::STT_COMMON || | if (symb->getType() == ELF::STT_COMMON || | |||
getSymbolTableIndex(symb) == ELF::SHN_COMMON) | getSymbolTableIndex(symb) == ELF::SHN_COMMON) | |||
Result |= SymbolRef::SF_Common; | Result |= SymbolRef::SF_Common; | |||
if (symb->getType() == ELF::STT_TLS) | if (symb->getType() == ELF::STT_TLS) | |||
Result |= SymbolRef::SF_ThreadLocal; | Result |= SymbolRef::SF_ThreadLocal; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, | |||
::getSymbolSection(DataRefImpl Symb, | section_iterator &Res) con | |||
section_iterator &Res) const { | st { | |||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
const Elf_Shdr *sec = getSection(symb); | const Elf_Shdr *sec = getSection(symb); | |||
if (!sec) | if (!sec) | |||
Res = end_sections(); | Res = end_sections(); | |||
else { | else { | |||
DataRefImpl Sec; | DataRefImpl Sec; | |||
Sec.p = reinterpret_cast<intptr_t>(sec); | Sec.p = reinterpret_cast<intptr_t>(sec); | |||
Res = section_iterator(SectionRef(Sec, this)); | Res = section_iterator(SectionRef(Sec, this)); | |||
} | } | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb, | |||
::getSymbolValue(DataRefImpl Symb, | uint64_t &Val) const { | |||
uint64_t &Val) const { | ||||
validateSymbol(Symb); | validateSymbol(Symb); | |||
const Elf_Sym *symb = getSymbol(Symb); | const Elf_Sym *symb = getSymbol(Symb); | |||
Val = symb->st_value; | Val = symb->st_value; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec, | |||
::getSectionNext(DataRefImpl Sec, SectionRef &Resul | SectionRef &Result) const { | |||
t) const { | ||||
const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p); | const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p); | |||
sec += Header->e_shentsize; | sec += Header->e_shentsize; | |||
Sec.p = reinterpret_cast<intptr_t>(sec); | Sec.p = reinterpret_cast<intptr_t>(sec); | |||
Result = SectionRef(Sec, this); | Result = SectionRef(Sec, this); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, | |||
::getSectionName(DataRefImpl Sec, | StringRef &Result) const { | |||
StringRef &Result) const { | ||||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name)); | Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name)); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec, | |||
::getSectionAddress(DataRefImpl Sec, | uint64_t &Result) const { | |||
uint64_t &Result) const { | ||||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
Result = sec->sh_addr; | Result = sec->sh_addr; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec, | |||
::getSectionSize(DataRefImpl Sec, | uint64_t &Result) const { | |||
uint64_t &Result) const { | ||||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
Result = sec->sh_size; | Result = sec->sh_size; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, | |||
::getSectionContents(DataRefImpl Sec, | StringRef &Result) const | |||
StringRef &Result) const { | { | |||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
const char *start = (const char*)base() + sec->sh_offset; | const char *start = (const char*)base() + sec->sh_offset; | |||
Result = StringRef(start, sec->sh_size); | Result = StringRef(start, sec->sh_size); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSectionContents(const Elf_Shdr *Sec, | |||
::getSectionContents(const Elf_Shdr *Sec, | StringRef &Result) const | |||
StringRef &Result) const { | { | |||
const char *start = (const char*)base() + Sec->sh_offset; | const char *start = (const char*)base() + Sec->sh_offset; | |||
Result = StringRef(start, Sec->sh_size); | Result = StringRef(start, Sec->sh_size); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec, | |||
::getSectionAlignment(DataRefImpl Sec, | uint64_t &Result) const | |||
uint64_t &Result) const { | { | |||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
Result = sec->sh_addralign; | Result = sec->sh_addralign; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec, | |||
::isSectionText(DataRefImpl Sec, | bool &Result) const { | |||
bool &Result) const { | ||||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
if (sec->sh_flags & ELF::SHF_EXECINSTR) | if (sec->sh_flags & ELF::SHF_EXECINSTR) | |||
Result = true; | Result = true; | |||
else | else | |||
Result = false; | Result = false; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec, | |||
::isSectionData(DataRefImpl Sec, | bool &Result) const { | |||
bool &Result) const { | ||||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) | if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) | |||
&& sec->sh_type == ELF::SHT_PROGBITS) | && sec->sh_type == ELF::SHT_PROGBITS) | |||
Result = true; | Result = true; | |||
else | else | |||
Result = false; | Result = false; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec, | |||
::isSectionBSS(DataRefImpl Sec, | bool &Result) const { | |||
bool &Result) const { | ||||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) | if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) | |||
&& sec->sh_type == ELF::SHT_NOBITS) | && sec->sh_type == ELF::SHT_NOBITS) | |||
Result = true; | Result = true; | |||
else | else | |||
Result = false; | Result = false; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::isSectionRequiredForExecution( | |||
::isSectionRequiredForExecution(DataRefImpl Sec, | DataRefImpl Sec, bool &Result) const { | |||
bool &Result) const | ||||
{ | ||||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
if (sec->sh_flags & ELF::SHF_ALLOC) | if (sec->sh_flags & ELF::SHF_ALLOC) | |||
Result = true; | Result = true; | |||
else | else | |||
Result = false; | Result = false; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec, | |||
::isSectionVirtual(DataRefImpl Sec, | bool &Result) const { | |||
bool &Result) const { | ||||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
if (sec->sh_type == ELF::SHT_NOBITS) | if (sec->sh_type == ELF::SHT_NOBITS) | |||
Result = true; | Result = true; | |||
else | else | |||
Result = false; | Result = false; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec, | |||
::isSectionZeroInit(DataRefImpl Sec, | bool &Result) const { | |||
bool &Result) const { | ||||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
// For ELF, all zero-init sections are virtual (that is, they occupy no s pace | // For ELF, all zero-init sections are virtual (that is, they occupy no s pace | |||
// in the object image) and vice versa. | // in the object image) and vice versa. | |||
if (sec->sh_flags & ELF::SHT_NOBITS) | Result = sec->sh_type == ELF::SHT_NOBITS; | |||
Result = true; | ||||
else | ||||
Result = false; | ||||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec, | |||
::isSectionReadOnlyData(DataRefImpl Sec, | bool &Result) const { | |||
bool &Result) const { | ||||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
if (sec->sh_flags & ELF::SHF_WRITE || sec->sh_flags & ELF::SHF_EXECINSTR) | if (sec->sh_flags & ELF::SHF_WRITE || sec->sh_flags & ELF::SHF_EXECINSTR) | |||
Result = false; | Result = false; | |||
else | else | |||
Result = true; | Result = true; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec, | |||
::sectionContainsSymbol(DataRefImpl Sec, | DataRefImpl Symb, | |||
DataRefImpl Symb, | bool &Result) const { | |||
bool &Result) const { | validateSymbol(Symb); | |||
// FIXME: Unimplemented. | ||||
Result = false; | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
const Elf_Sym *symb = getSymbol(Symb); | ||||
unsigned shndx = symb->st_shndx; | ||||
bool Reserved = shndx >= ELF::SHN_LORESERVE | ||||
&& shndx <= ELF::SHN_HIRESERVE; | ||||
Result = !Reserved && (sec == getSection(symb->st_shndx)); | ||||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
relocation_iterator ELFObjectFile<target_endianness, is64Bits> | relocation_iterator | |||
::getSectionRelBegin(DataRefImpl Sec) cons | ELFObjectFile<ELFT>::getSectionRelBegin(DataRefImpl Sec) const { | |||
t { | ||||
DataRefImpl RelData; | DataRefImpl RelData; | |||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); | typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); | |||
if (sec != 0 && ittr != SectionRelocMap.end()) { | if (sec != 0 && ittr != SectionRelocMap.end()) { | |||
RelData.w.a = getSection(ittr->second[0])->sh_info; | RelData.w.a = getSection(ittr->second[0])->sh_info; | |||
RelData.w.b = ittr->second[0]; | RelData.w.b = ittr->second[0]; | |||
RelData.w.c = 0; | RelData.w.c = 0; | |||
} | } | |||
return relocation_iterator(RelocationRef(RelData, this)); | return relocation_iterator(RelocationRef(RelData, this)); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
relocation_iterator ELFObjectFile<target_endianness, is64Bits> | relocation_iterator | |||
::getSectionRelEnd(DataRefImpl Sec) const | ELFObjectFile<ELFT>::getSectionRelEnd(DataRefImpl Sec) const { | |||
{ | ||||
DataRefImpl RelData; | DataRefImpl RelData; | |||
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); | |||
typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); | typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); | |||
if (sec != 0 && ittr != SectionRelocMap.end()) { | if (sec != 0 && ittr != SectionRelocMap.end()) { | |||
// Get the index of the last relocation section for this section. | // Get the index of the last relocation section for this section. | |||
std::size_t relocsecindex = ittr->second[ittr->second.size() - 1]; | std::size_t relocsecindex = ittr->second[ittr->second.size() - 1]; | |||
const Elf_Shdr *relocsec = getSection(relocsecindex); | const Elf_Shdr *relocsec = getSection(relocsecindex); | |||
RelData.w.a = relocsec->sh_info; | RelData.w.a = relocsec->sh_info; | |||
RelData.w.b = relocsecindex; | RelData.w.b = relocsecindex; | |||
RelData.w.c = relocsec->sh_size / relocsec->sh_entsize; | RelData.w.c = relocsec->sh_size / relocsec->sh_entsize; | |||
} | } | |||
return relocation_iterator(RelocationRef(RelData, this)); | return relocation_iterator(RelocationRef(RelData, this)); | |||
} | } | |||
// Relocations | // Relocations | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel, | |||
::getRelocationNext(DataRefImpl Rel, | RelocationRef &Result) co | |||
RelocationRef &Result) const { | nst { | |||
++Rel.w.c; | ++Rel.w.c; | |||
const Elf_Shdr *relocsec = getSection(Rel.w.b); | const Elf_Shdr *relocsec = getSection(Rel.w.b); | |||
if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) { | if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) { | |||
// We have reached the end of the relocations for this section. See if there | // We have reached the end of the relocations for this section. See if there | |||
// is another relocation section. | // is another relocation section. | |||
typename RelocMap_t::mapped_type relocseclist = | typename RelocMap_t::mapped_type relocseclist = | |||
SectionRelocMap.lookup(getSection(Rel.w.a)); | SectionRelocMap.lookup(getSection(Rel.w.a)); | |||
// Do a binary search for the current reloc section index (which must b e | // Do a binary search for the current reloc section index (which must b e | |||
// present). Then get the next one. | // present). Then get the next one. | |||
skipping to change at line 1398 | skipping to change at line 1512 | |||
// to the end iterator. | // to the end iterator. | |||
if (loc != relocseclist.end()) { | if (loc != relocseclist.end()) { | |||
Rel.w.b = *loc; | Rel.w.b = *loc; | |||
Rel.w.a = 0; | Rel.w.a = 0; | |||
} | } | |||
} | } | |||
Result = RelocationRef(Rel, this); | Result = RelocationRef(Rel, this); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel, | |||
::getRelocationSymbol(DataRefImpl Rel, | SymbolRef &Result) cons | |||
SymbolRef &Result) const { | t { | |||
uint32_t symbolIdx; | uint32_t symbolIdx; | |||
const Elf_Shdr *sec = getSection(Rel.w.b); | const Elf_Shdr *sec = getSection(Rel.w.b); | |||
switch (sec->sh_type) { | switch (sec->sh_type) { | |||
default : | default : | |||
report_fatal_error("Invalid section type in Rel!"); | report_fatal_error("Invalid section type in Rel!"); | |||
case ELF::SHT_REL : { | case ELF::SHT_REL : { | |||
symbolIdx = getRel(Rel)->getSymbol(); | symbolIdx = getRel(Rel)->getSymbol(isMips64EL()); | |||
break; | break; | |||
} | } | |||
case ELF::SHT_RELA : { | case ELF::SHT_RELA : { | |||
symbolIdx = getRela(Rel)->getSymbol(); | symbolIdx = getRela(Rel)->getSymbol(isMips64EL()); | |||
break; | break; | |||
} | } | |||
} | } | |||
DataRefImpl SymbolData; | DataRefImpl SymbolData; | |||
IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_ link); | IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_ link); | |||
if (it == SymbolTableSectionsIndexMap.end()) | if (it == SymbolTableSectionsIndexMap.end()) | |||
report_fatal_error("Relocation symbol table not found!"); | report_fatal_error("Relocation symbol table not found!"); | |||
SymbolData.d.a = symbolIdx; | SymbolData.d.a = symbolIdx; | |||
SymbolData.d.b = it->second; | SymbolData.d.b = it->second; | |||
Result = SymbolRef(SymbolData, this); | Result = SymbolRef(SymbolData, this); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, | |||
::getRelocationAddress(DataRefImpl Rel, | uint64_t &Result) cons | |||
uint64_t &Result) const { | t { | |||
uint64_t offset; | assert((Header->e_type == ELF::ET_EXEC || Header->e_type == ELF::ET_DYN) | |||
const Elf_Shdr *sec = getSection(Rel.w.b); | && | |||
switch (sec->sh_type) { | "Only executable and shared objects files have addresses"); | |||
default : | Result = getROffset(Rel); | |||
report_fatal_error("Invalid section type in Rel!"); | return object_error::success; | |||
case ELF::SHT_REL : { | } | |||
offset = getRel(Rel)->r_offset; | ||||
break; | ||||
} | ||||
case ELF::SHT_RELA : { | ||||
offset = getRela(Rel)->r_offset; | ||||
break; | ||||
} | ||||
} | ||||
Result = offset; | template<class ELFT> | |||
error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, | ||||
uint64_t &Result) const | ||||
{ | ||||
assert(Header->e_type == ELF::ET_REL && | ||||
"Only relocatable object files have relocation offsets"); | ||||
Result = getROffset(Rel); | ||||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const { | |||
::getRelocationOffset(DataRefImpl Rel, | ||||
uint64_t &Result) const { | ||||
uint64_t offset; | ||||
const Elf_Shdr *sec = getSection(Rel.w.b); | const Elf_Shdr *sec = getSection(Rel.w.b); | |||
switch (sec->sh_type) { | switch (sec->sh_type) { | |||
default : | default: | |||
report_fatal_error("Invalid section type in Rel!"); | report_fatal_error("Invalid section type in Rel!"); | |||
case ELF::SHT_REL : { | case ELF::SHT_REL: | |||
offset = getRel(Rel)->r_offset; | return getRel(Rel)->r_offset; | |||
break; | case ELF::SHT_RELA: | |||
} | return getRela(Rel)->r_offset; | |||
case ELF::SHT_RELA : { | ||||
offset = getRela(Rel)->r_offset; | ||||
break; | ||||
} | ||||
} | } | |||
Result = offset - sec->sh_addr; | ||||
return object_error::success; | ||||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, | |||
::getRelocationType(DataRefImpl Rel, | uint64_t &Result) const { | |||
uint64_t &Result) const { | ||||
const Elf_Shdr *sec = getSection(Rel.w.b); | const Elf_Shdr *sec = getSection(Rel.w.b); | |||
switch (sec->sh_type) { | switch (sec->sh_type) { | |||
default : | default : | |||
report_fatal_error("Invalid section type in Rel!"); | report_fatal_error("Invalid section type in Rel!"); | |||
case ELF::SHT_REL : { | case ELF::SHT_REL : { | |||
Result = getRel(Rel)->getType(); | Result = getRel(Rel)->getType(isMips64EL()); | |||
break; | break; | |||
} | } | |||
case ELF::SHT_RELA : { | case ELF::SHT_RELA : { | |||
Result = getRela(Rel)->getType(); | Result = getRela(Rel)->getType(isMips64EL()); | |||
break; | break; | |||
} | } | |||
} | } | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \ | #define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \ | |||
case ELF::enum: res = #enum; break; | case ELF::enum: Res = #enum; break; | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { | |||
::getRelocationTypeName(DataRefImpl Rel, | StringRef Res = "Unknown"; | |||
SmallVectorImpl<char> &Result) co | ||||
nst { | ||||
const Elf_Shdr *sec = getSection(Rel.w.b); | ||||
uint8_t type; | ||||
StringRef res; | ||||
switch (sec->sh_type) { | ||||
default : | ||||
return object_error::parse_failed; | ||||
case ELF::SHT_REL : { | ||||
type = getRel(Rel)->getType(); | ||||
break; | ||||
} | ||||
case ELF::SHT_RELA : { | ||||
type = getRela(Rel)->getType(); | ||||
break; | ||||
} | ||||
} | ||||
switch (Header->e_machine) { | switch (Header->e_machine) { | |||
case ELF::EM_X86_64: | case ELF::EM_X86_64: | |||
switch (type) { | switch (Type) { | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL); | |||
skipping to change at line 1544 | skipping to change at line 1625 | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPLT64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLTOFF64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC); | |||
default: | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_IRELATIVE); | |||
res = "Unknown"; | default: break; | |||
} | } | |||
break; | break; | |||
case ELF::EM_386: | case ELF::EM_386: | |||
switch (type) { | switch (Type) { | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF); | |||
skipping to change at line 1595 | skipping to change at line 1681 | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE); | |||
default: | default: break; | |||
res = "Unknown"; | } | |||
break; | ||||
case ELF::EM_MIPS: | ||||
switch (Type) { | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NONE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_26); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HI16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LO16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LITERAL); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT16); | ||||
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_SHIFT5); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT6); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_DISP); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_PAGE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_OFST); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_HI16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_LO16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SUB); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_A); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_B); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_DELETE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHER); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHEST); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_HI16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_LO16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SCN_DISP); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_ADD_IMMEDIATE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PJUMP); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_RELGOT); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JALR); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GD); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_LDM); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_HI16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_LO16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GOTTPREL); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_HI16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_LO16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GLOB_DAT); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_COPY); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JUMP_SLOT); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NUM); | ||||
default: break; | ||||
} | ||||
break; | ||||
case ELF::EM_AARCH64: | ||||
switch (Type) { | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_NONE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G0); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G0_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G1); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G1_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G2); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G2_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G3); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G0); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G1); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G2); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LD_PREL_LO19); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_PREL_LO21); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_PREL_PG_HI21); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADD_ABS_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST8_ABS_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TSTBR14); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_CONDBR19); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_JUMP26); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_CALL26); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST16_ABS_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST32_ABS_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST64_ABS_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST128_ABS_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_GOT_PAGE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LD64_GOT_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G2); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G1); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G0); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_HI12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_LO12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST8_DTPREL_LO12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC) | ||||
; | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST16_DTPREL_LO12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC | ||||
); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST32_DTPREL_LO12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC | ||||
); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST64_DTPREL_LO12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC | ||||
); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC | ||||
); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G2); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G1); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G0); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_HI12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_LO12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST8_TPREL_LO12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST16_TPREL_LO12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC) | ||||
; | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST32_TPREL_LO12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC) | ||||
; | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST64_TPREL_LO12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC) | ||||
; | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADR_PAGE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_LD64_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADD_LO12_NC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_CALL); | ||||
default: break; | ||||
} | } | |||
break; | break; | |||
case ELF::EM_ARM: | case ELF::EM_ARM: | |||
switch (type) { | switch (Type) { | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_NONE); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_NONE); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PC24); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PC24); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_REL32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_REL32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G0); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G0); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS16); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS16); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS12); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS12); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_ABS5); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_ABS5); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS8); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS8); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_SBREL32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_SBREL32); | |||
skipping to change at line 1732 | skipping to change at line 1952 | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_9); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_9); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_10); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_10); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_11); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_11); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_12); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_12); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_13); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_13); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_14); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_14); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_15); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_15); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ME_TOO); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ME_TOO); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ16); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ16); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ32); | |||
default: | default: break; | |||
res = "Unknown"; | ||||
} | } | |||
break; | break; | |||
case ELF::EM_HEXAGON: | case ELF::EM_HEXAGON: | |||
switch (type) { | switch (Type) { | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_NONE); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_NONE); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B22_PCREL); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B22_PCREL); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B15_PCREL); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B15_PCREL); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B7_PCREL); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B7_PCREL); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_LO16); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_LO16); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_HI16); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_HI16); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_32); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_32); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_16); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_16); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_8); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_8); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_0); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_0); | |||
skipping to change at line 1824 | skipping to change at line 2043 | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_16_X); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_16_X); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_11_X); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_11_X); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_32_6_X); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_32_6_X); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_16_X); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_16_X); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_32_6_X); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_32_6_X); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_16_X); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_16_X); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_11_X); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_11_X); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_32_6_X); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_32_6_X); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_16_X); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_16_X); | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_11_X); | LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_11_X); | |||
default: | default: break; | |||
res = "Unknown"; | ||||
} | } | |||
break; | break; | |||
default: | case ELF::EM_PPC: | |||
res = "Unknown"; | switch (Type) { | |||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_NONE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR24); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_LO); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_HI); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_HA); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14_BRTAKEN); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14_BRNTAKEN); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL24); | ||||
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_REL32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_LO); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HA); | ||||
default: break; | ||||
} | ||||
break; | ||||
case ELF::EM_PPC64: | ||||
switch (Type) { | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_NONE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HI); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR14); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL24); | ||||
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_HIGHEST); | ||||
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_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_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_TPREL16_LO); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HA); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_LO); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HA); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_LO); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_HA); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_LO); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_HA); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_LO_DS); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_HA); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSGD); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSLD); | ||||
default: break; | ||||
} | ||||
break; | ||||
case ELF::EM_S390: | ||||
switch (Type) { | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_NONE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_8); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_COPY); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GLOB_DAT); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_JMP_SLOT); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_RELATIVE); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPC); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC16DBL); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT16DBL); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC32DBL); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT32DBL); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPCDBL); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTENT); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLTENT); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF16); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LOAD); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GDCALL); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDCALL); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GD32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GD64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE12); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDM32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDM64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IE32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IE64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IEENT); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LE32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LE64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDO32); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDO64); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_DTPMOD); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_DTPOFF); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_TPOFF); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_20); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT20); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT20); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE20); | ||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_IRELATIVE); | ||||
default: break; | ||||
} | ||||
break; | ||||
default: break; | ||||
} | } | |||
Result.append(res.begin(), res.end()); | return Res; | |||
return object_error::success; | ||||
} | } | |||
#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME | #undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getRelocationTypeName( | |||
::getRelocationAdditionalInfo(DataRefImpl Rel, | DataRefImpl Rel, SmallVectorImpl<char> &Result) const { | |||
int64_t &Result) cons | const Elf_Shdr *sec = getSection(Rel.w.b); | |||
t { | uint32_t type; | |||
switch (sec->sh_type) { | ||||
default : | ||||
return object_error::parse_failed; | ||||
case ELF::SHT_REL : { | ||||
type = getRel(Rel)->getType(isMips64EL()); | ||||
break; | ||||
} | ||||
case ELF::SHT_RELA : { | ||||
type = getRela(Rel)->getType(isMips64EL()); | ||||
break; | ||||
} | ||||
} | ||||
if (!isMips64EL()) { | ||||
StringRef Name = getRelocationTypeName(type); | ||||
Result.append(Name.begin(), Name.end()); | ||||
} else { | ||||
uint8_t Type1 = (type >> 0) & 0xFF; | ||||
uint8_t Type2 = (type >> 8) & 0xFF; | ||||
uint8_t Type3 = (type >> 16) & 0xFF; | ||||
// Concat all three relocation type names. | ||||
StringRef Name = getRelocationTypeName(Type1); | ||||
Result.append(Name.begin(), Name.end()); | ||||
Name = getRelocationTypeName(Type2); | ||||
Result.append(1, '/'); | ||||
Result.append(Name.begin(), Name.end()); | ||||
Name = getRelocationTypeName(Type3); | ||||
Result.append(1, '/'); | ||||
Result.append(Name.begin(), Name.end()); | ||||
} | ||||
return object_error::success; | ||||
} | ||||
template<class ELFT> | ||||
error_code ELFObjectFile<ELFT>::getRelocationAdditionalInfo( | ||||
DataRefImpl Rel, int64_t &Result) const { | ||||
const Elf_Shdr *sec = getSection(Rel.w.b); | const Elf_Shdr *sec = getSection(Rel.w.b); | |||
switch (sec->sh_type) { | switch (sec->sh_type) { | |||
default : | default : | |||
report_fatal_error("Invalid section type in Rel!"); | report_fatal_error("Invalid section type in Rel!"); | |||
case ELF::SHT_REL : { | case ELF::SHT_REL : { | |||
Result = 0; | Result = 0; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
case ELF::SHT_RELA : { | case ELF::SHT_RELA : { | |||
Result = getRela(Rel)->r_addend; | Result = getRela(Rel)->r_addend; | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
} | } | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getRelocationValueString( | |||
::getRelocationValueString(DataRefImpl Rel, | DataRefImpl Rel, SmallVectorImpl<char> &Result) const { | |||
SmallVectorImpl<char> &Result) co | ||||
nst { | ||||
const Elf_Shdr *sec = getSection(Rel.w.b); | const Elf_Shdr *sec = getSection(Rel.w.b); | |||
uint8_t type; | uint8_t type; | |||
StringRef res; | StringRef res; | |||
int64_t addend = 0; | int64_t addend = 0; | |||
uint16_t symbol_index = 0; | uint16_t symbol_index = 0; | |||
switch (sec->sh_type) { | switch (sec->sh_type) { | |||
default: | default: | |||
return object_error::parse_failed; | return object_error::parse_failed; | |||
case ELF::SHT_REL: { | case ELF::SHT_REL: { | |||
type = getRel(Rel)->getType(); | type = getRel(Rel)->getType(isMips64EL()); | |||
symbol_index = getRel(Rel)->getSymbol(); | symbol_index = getRel(Rel)->getSymbol(isMips64EL()); | |||
// TODO: Read implicit addend from section data. | // TODO: Read implicit addend from section data. | |||
break; | break; | |||
} | } | |||
case ELF::SHT_RELA: { | case ELF::SHT_RELA: { | |||
type = getRela(Rel)->getType(); | type = getRela(Rel)->getType(isMips64EL()); | |||
symbol_index = getRela(Rel)->getSymbol(); | symbol_index = getRela(Rel)->getSymbol(isMips64EL()); | |||
addend = getRela(Rel)->r_addend; | addend = getRela(Rel)->r_addend; | |||
break; | break; | |||
} | } | |||
} | } | |||
const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index); | const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index); | |||
StringRef symname; | StringRef symname; | |||
if (error_code ec = getSymbolName(getSection(sec->sh_link), symb, symname )) | if (error_code ec = getSymbolName(getSection(sec->sh_link), symb, symname )) | |||
return ec; | return ec; | |||
switch (Header->e_machine) { | switch (Header->e_machine) { | |||
case ELF::EM_X86_64: | case ELF::EM_X86_64: | |||
skipping to change at line 1914 | skipping to change at line 2296 | |||
raw_string_ostream fmt(fmtbuf); | raw_string_ostream fmt(fmtbuf); | |||
fmt << symname << (addend < 0 ? "" : "+") << addend; | fmt << symname << (addend < 0 ? "" : "+") << addend; | |||
fmt.flush(); | fmt.flush(); | |||
Result.append(fmtbuf.begin(), fmtbuf.end()); | Result.append(fmtbuf.begin(), fmtbuf.end()); | |||
} | } | |||
break; | break; | |||
default: | default: | |||
res = "Unknown"; | res = "Unknown"; | |||
} | } | |||
break; | break; | |||
case ELF::EM_AARCH64: | ||||
case ELF::EM_ARM: | case ELF::EM_ARM: | |||
case ELF::EM_HEXAGON: | case ELF::EM_HEXAGON: | |||
res = symname; | res = symname; | |||
break; | break; | |||
default: | default: | |||
res = "Unknown"; | res = "Unknown"; | |||
} | } | |||
if (Result.empty()) | if (Result.empty()) | |||
Result.append(res.begin(), res.end()); | Result.append(res.begin(), res.end()); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
// Verify that the last byte in the string table in a null. | // Verify that the last byte in the string table in a null. | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
void ELFObjectFile<target_endianness, is64Bits> | void ELFObjectFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const { | |||
::VerifyStrTab(const Elf_Shdr *sh) const { | ||||
const char *strtab = (const char*)base() + sh->sh_offset; | const char *strtab = (const char*)base() + sh->sh_offset; | |||
if (strtab[sh->sh_size - 1] != 0) | if (strtab[sh->sh_size - 1] != 0) | |||
// FIXME: Proper error handling. | // FIXME: Proper error handling. | |||
report_fatal_error("String table must end with a null terminator!"); | report_fatal_error("String table must end with a null terminator!"); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Obj | ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec) | |||
ect | : ObjectFile(getELFType( | |||
, error_code &ec) | static_cast<endianness>(ELFT::TargetEndianness) == support::little, | |||
: ObjectFile(getELFType(target_endianness == support::little, is64Bits), | ELFT::Is64Bits), | |||
Object, ec) | Object) | |||
, isDyldELFObject(false) | , isDyldELFObject(false) | |||
, SectionHeaderTable(0) | , SectionHeaderTable(0) | |||
, dot_shstrtab_sec(0) | , dot_shstrtab_sec(0) | |||
, dot_strtab_sec(0) | , dot_strtab_sec(0) | |||
, dot_dynstr_sec(0) | , dot_dynstr_sec(0) | |||
, dot_dynamic_sec(0) | , dot_dynamic_sec(0) | |||
, dot_gnu_version_sec(0) | , dot_gnu_version_sec(0) | |||
, dot_gnu_version_r_sec(0) | , dot_gnu_version_r_sec(0) | |||
, dot_gnu_version_d_sec(0) | , dot_gnu_version_d_sec(0) | |||
, dt_soname(0) | , dt_soname(0) | |||
skipping to change at line 2097 | skipping to change at line 2480 | |||
se = end_symbols(); si != se; si.increment(ec)) { | se = end_symbols(); si != se; si.increment(ec)) { | |||
if (ec) | if (ec) | |||
report_fatal_error("Fewer extended symbol table entries than symbol s!"); | report_fatal_error("Fewer extended symbol table entries than symbol s!"); | |||
if (*ShndxTable != ELF::SHN_UNDEF) | if (*ShndxTable != ELF::SHN_UNDEF) | |||
ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTab le; | ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTab le; | |||
++ShndxTable; | ++ShndxTable; | |||
} | } | |||
} | } | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | // Get the symbol table index in the symtab section given a symbol | |||
symbol_iterator ELFObjectFile<target_endianness, is64Bits> | template<class ELFT> | |||
::begin_symbols() const { | uint64_t ELFObjectFile<ELFT>::getSymbolIndex(const Elf_Sym *Sym) const { | |||
assert(SymbolTableSections.size() == 1 && "Only one symbol table supporte | ||||
d!"); | ||||
const Elf_Shdr *SymTab = *SymbolTableSections.begin(); | ||||
uintptr_t SymLoc = uintptr_t(Sym); | ||||
uintptr_t SymTabLoc = uintptr_t(base() + SymTab->sh_offset); | ||||
assert(SymLoc > SymTabLoc && "Symbol not in symbol table!"); | ||||
uint64_t SymOffset = SymLoc - SymTabLoc; | ||||
assert(SymOffset % SymTab->sh_entsize == 0 && | ||||
"Symbol not multiple of symbol size!"); | ||||
return SymOffset / SymTab->sh_entsize; | ||||
} | ||||
template<class ELFT> | ||||
symbol_iterator ELFObjectFile<ELFT>::begin_symbols() const { | ||||
DataRefImpl SymbolData; | DataRefImpl SymbolData; | |||
if (SymbolTableSections.size() <= 1) { | if (SymbolTableSections.size() <= 1) { | |||
SymbolData.d.a = std::numeric_limits<uint32_t>::max(); | SymbolData.d.a = std::numeric_limits<uint32_t>::max(); | |||
SymbolData.d.b = std::numeric_limits<uint32_t>::max(); | SymbolData.d.b = std::numeric_limits<uint32_t>::max(); | |||
} else { | } else { | |||
SymbolData.d.a = 1; // The 0th symbol in ELF is fake. | SymbolData.d.a = 1; // The 0th symbol in ELF is fake. | |||
SymbolData.d.b = 1; // The 0th table is .dynsym | SymbolData.d.b = 1; // The 0th table is .dynsym | |||
} | } | |||
return symbol_iterator(SymbolRef(SymbolData, this)); | return symbol_iterator(SymbolRef(SymbolData, this)); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
symbol_iterator ELFObjectFile<target_endianness, is64Bits> | symbol_iterator ELFObjectFile<ELFT>::end_symbols() const { | |||
::end_symbols() const { | ||||
DataRefImpl SymbolData; | DataRefImpl SymbolData; | |||
SymbolData.d.a = std::numeric_limits<uint32_t>::max(); | SymbolData.d.a = std::numeric_limits<uint32_t>::max(); | |||
SymbolData.d.b = std::numeric_limits<uint32_t>::max(); | SymbolData.d.b = std::numeric_limits<uint32_t>::max(); | |||
return symbol_iterator(SymbolRef(SymbolData, this)); | return symbol_iterator(SymbolRef(SymbolData, this)); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
symbol_iterator ELFObjectFile<target_endianness, is64Bits> | symbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const { | |||
::begin_dynamic_symbols() const { | ||||
DataRefImpl SymbolData; | DataRefImpl SymbolData; | |||
if (SymbolTableSections[0] == NULL) { | if (SymbolTableSections[0] == NULL) { | |||
SymbolData.d.a = std::numeric_limits<uint32_t>::max(); | SymbolData.d.a = std::numeric_limits<uint32_t>::max(); | |||
SymbolData.d.b = std::numeric_limits<uint32_t>::max(); | SymbolData.d.b = std::numeric_limits<uint32_t>::max(); | |||
} else { | } else { | |||
SymbolData.d.a = 1; // The 0th symbol in ELF is fake. | SymbolData.d.a = 1; // The 0th symbol in ELF is fake. | |||
SymbolData.d.b = 0; // The 0th table is .dynsym | SymbolData.d.b = 0; // The 0th table is .dynsym | |||
} | } | |||
return symbol_iterator(SymbolRef(SymbolData, this)); | return symbol_iterator(SymbolRef(SymbolData, this)); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
symbol_iterator ELFObjectFile<target_endianness, is64Bits> | symbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const { | |||
::end_dynamic_symbols() const { | ||||
DataRefImpl SymbolData; | DataRefImpl SymbolData; | |||
SymbolData.d.a = std::numeric_limits<uint32_t>::max(); | SymbolData.d.a = std::numeric_limits<uint32_t>::max(); | |||
SymbolData.d.b = std::numeric_limits<uint32_t>::max(); | SymbolData.d.b = std::numeric_limits<uint32_t>::max(); | |||
return symbol_iterator(SymbolRef(SymbolData, this)); | return symbol_iterator(SymbolRef(SymbolData, this)); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
section_iterator ELFObjectFile<target_endianness, is64Bits> | section_iterator ELFObjectFile<ELFT>::begin_sections() const { | |||
::begin_sections() const { | ||||
DataRefImpl ret; | DataRefImpl ret; | |||
ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff); | ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff); | |||
return section_iterator(SectionRef(ret, this)); | return section_iterator(SectionRef(ret, this)); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
section_iterator ELFObjectFile<target_endianness, is64Bits> | section_iterator ELFObjectFile<ELFT>::end_sections() const { | |||
::end_sections() const { | ||||
DataRefImpl ret; | DataRefImpl ret; | |||
ret.p = reinterpret_cast<intptr_t>(base() | ret.p = reinterpret_cast<intptr_t>(base() | |||
+ Header->e_shoff | + Header->e_shoff | |||
+ (Header->e_shentsize*getNumSections( ))); | + (Header->e_shentsize*getNumSections( ))); | |||
return section_iterator(SectionRef(ret, this)); | return section_iterator(SectionRef(ret, this)); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator | typename ELFObjectFile<ELFT>::Elf_Dyn_iterator | |||
ELFObjectFile<target_endianness, is64Bits>::begin_dynamic_table() const { | ELFObjectFile<ELFT>::begin_dynamic_table() const { | |||
DataRefImpl DynData; | if (dot_dynamic_sec) | |||
if (dot_dynamic_sec == NULL || dot_dynamic_sec->sh_size == 0) { | return Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize, | |||
DynData.d.a = std::numeric_limits<uint32_t>::max(); | (const char *)base() + dot_dynamic_sec->sh_offs | |||
} else { | et); | |||
DynData.d.a = 0; | return Elf_Dyn_iterator(0, 0); | |||
} | ||||
template<class ELFT> | ||||
typename ELFObjectFile<ELFT>::Elf_Dyn_iterator | ||||
ELFObjectFile<ELFT>::end_dynamic_table(bool NULLEnd) const { | ||||
if (dot_dynamic_sec) { | ||||
Elf_Dyn_iterator Ret(dot_dynamic_sec->sh_entsize, | ||||
(const char *)base() + dot_dynamic_sec->sh_offset | ||||
+ | ||||
dot_dynamic_sec->sh_size); | ||||
if (NULLEnd) { | ||||
Elf_Dyn_iterator Start = begin_dynamic_table(); | ||||
while (Start != Ret && Start->getTag() != ELF::DT_NULL) | ||||
++Start; | ||||
// Include the DT_NULL. | ||||
if (Start != Ret) | ||||
++Start; | ||||
Ret = Start; | ||||
} | ||||
return Ret; | ||||
} | } | |||
return dyn_iterator(DynRef(DynData, this)); | return Elf_Dyn_iterator(0, 0); | |||
} | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator | ||||
ELFObjectFile<target_endianness, is64Bits> | ||||
::end_dynamic_table() const { | ||||
DataRefImpl DynData; | ||||
DynData.d.a = std::numeric_limits<uint32_t>::max(); | ||||
return dyn_iterator(DynRef(DynData, this)); | ||||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | StringRef ELFObjectFile<ELFT>::getLoadName() const { | |||
::getDynNext(DataRefImpl DynData, | ||||
DynRef &Result) const { | ||||
++DynData.d.a; | ||||
// Check to see if we are at the end of .dynamic | ||||
if (DynData.d.a >= dot_dynamic_sec->getEntityCount()) { | ||||
// We are at the end. Return the terminator. | ||||
DynData.d.a = std::numeric_limits<uint32_t>::max(); | ||||
} | ||||
Result = DynRef(DynData, this); | ||||
return object_error::success; | ||||
} | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
StringRef | ||||
ELFObjectFile<target_endianness, is64Bits>::getLoadName() const { | ||||
if (!dt_soname) { | if (!dt_soname) { | |||
// Find the DT_SONAME entry | // Find the DT_SONAME entry | |||
dyn_iterator it = begin_dynamic_table(); | Elf_Dyn_iterator it = begin_dynamic_table(); | |||
dyn_iterator ie = end_dynamic_table(); | Elf_Dyn_iterator ie = end_dynamic_table(); | |||
error_code ec; | while (it != ie && it->getTag() != ELF::DT_SONAME) | |||
while (it != ie) { | ++it; | |||
if (it->getTag() == ELF::DT_SONAME) | ||||
break; | ||||
it.increment(ec); | ||||
if (ec) | ||||
report_fatal_error("dynamic table iteration failed"); | ||||
} | ||||
if (it != ie) { | if (it != ie) { | |||
if (dot_dynstr_sec == NULL) | if (dot_dynstr_sec == NULL) | |||
report_fatal_error("Dynamic string table is missing"); | report_fatal_error("Dynamic string table is missing"); | |||
dt_soname = getString(dot_dynstr_sec, it->getVal()); | dt_soname = getString(dot_dynstr_sec, it->getVal()); | |||
} else { | } else { | |||
dt_soname = ""; | dt_soname = ""; | |||
} | } | |||
} | } | |||
return dt_soname; | return dt_soname; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
library_iterator ELFObjectFile<target_endianness, is64Bits> | library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const { | |||
::begin_libraries_needed() const { | ||||
// Find the first DT_NEEDED entry | // Find the first DT_NEEDED entry | |||
dyn_iterator i = begin_dynamic_table(); | Elf_Dyn_iterator i = begin_dynamic_table(); | |||
dyn_iterator e = end_dynamic_table(); | Elf_Dyn_iterator e = end_dynamic_table(); | |||
error_code ec; | while (i != e && i->getTag() != ELF::DT_NEEDED) | |||
while (i != e) { | ++i; | |||
if (i->getTag() == ELF::DT_NEEDED) | ||||
break; | DataRefImpl DRI; | |||
i.increment(ec); | DRI.p = reinterpret_cast<uintptr_t>(i.get()); | |||
if (ec) | return library_iterator(LibraryRef(DRI, this)); | |||
report_fatal_error("dynamic table iteration failed"); | ||||
} | ||||
// Use the same DataRefImpl format as DynRef. | ||||
return library_iterator(LibraryRef(i->getRawDataRefImpl(), this)); | ||||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data, | |||
::getLibraryNext(DataRefImpl Data, | LibraryRef &Result) const { | |||
LibraryRef &Result) const { | ||||
// Use the same DataRefImpl format as DynRef. | // Use the same DataRefImpl format as DynRef. | |||
dyn_iterator i = dyn_iterator(DynRef(Data, this)); | Elf_Dyn_iterator i = Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize, | |||
dyn_iterator e = end_dynamic_table(); | reinterpret_cast<const char *>(Data | |||
.p)); | ||||
// Skip the current dynamic table entry. | Elf_Dyn_iterator e = end_dynamic_table(); | |||
error_code ec; | ||||
if (i != e) { | // Skip the current dynamic table entry and find the next DT_NEEDED entry | |||
i.increment(ec); | . | |||
// TODO: proper error handling | do | |||
if (ec) | ++i; | |||
report_fatal_error("dynamic table iteration failed"); | while (i != e && i->getTag() != ELF::DT_NEEDED); | |||
} | ||||
DataRefImpl DRI; | ||||
// Find the next DT_NEEDED entry. | DRI.p = reinterpret_cast<uintptr_t>(i.get()); | |||
while (i != e) { | Result = LibraryRef(DRI, this); | |||
if (i->getTag() == ELF::DT_NEEDED) | ||||
break; | ||||
i.increment(ec); | ||||
if (ec) | ||||
report_fatal_error("dynamic table iteration failed"); | ||||
} | ||||
Result = LibraryRef(i->getRawDataRefImpl(), this); | ||||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data, | |||
::getLibraryPath(DataRefImpl Data, StringRef &Res) const { | StringRef &Res) const { | |||
dyn_iterator i = dyn_iterator(DynRef(Data, this)); | Elf_Dyn_iterator i = Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize, | |||
reinterpret_cast<const char *>(Data | ||||
.p)); | ||||
if (i == end_dynamic_table()) | if (i == end_dynamic_table()) | |||
report_fatal_error("getLibraryPath() called on iterator end"); | report_fatal_error("getLibraryPath() called on iterator end"); | |||
if (i->getTag() != ELF::DT_NEEDED) | if (i->getTag() != ELF::DT_NEEDED) | |||
report_fatal_error("Invalid library_iterator"); | report_fatal_error("Invalid library_iterator"); | |||
// This uses .dynstr to lookup the name of the DT_NEEDED entry. | // This uses .dynstr to lookup the name of the DT_NEEDED entry. | |||
// THis works as long as DT_STRTAB == .dynstr. This is true most of | // THis works as long as DT_STRTAB == .dynstr. This is true most of | |||
// the time, but the specification allows exceptions. | // the time, but the specification allows exceptions. | |||
// TODO: This should really use DT_STRTAB instead. Doing this requires | // TODO: This should really use DT_STRTAB instead. Doing this requires | |||
// reading the program headers. | // reading the program headers. | |||
if (dot_dynstr_sec == NULL) | if (dot_dynstr_sec == NULL) | |||
report_fatal_error("Dynamic string table is missing"); | report_fatal_error("Dynamic string table is missing"); | |||
Res = getString(dot_dynstr_sec, i->getVal()); | Res = getString(dot_dynstr_sec, i->getVal()); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
library_iterator ELFObjectFile<target_endianness, is64Bits> | library_iterator ELFObjectFile<ELFT>::end_libraries_needed() const { | |||
::end_libraries_needed() const { | Elf_Dyn_iterator e = end_dynamic_table(); | |||
dyn_iterator e = end_dynamic_table(); | DataRefImpl DRI; | |||
// Use the same DataRefImpl format as DynRef. | DRI.p = reinterpret_cast<uintptr_t>(e.get()); | |||
return library_iterator(LibraryRef(e->getRawDataRefImpl(), this)); | return library_iterator(LibraryRef(DRI, this)); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() con | uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const { | |||
st { | return ELFT::Is64Bits ? 8 : 4; | |||
return is64Bits ? 8 : 4; | ||||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
StringRef ELFObjectFile<target_endianness, is64Bits> | StringRef ELFObjectFile<ELFT>::getFileFormatName() const { | |||
::getFileFormatName() const { | ||||
switch(Header->e_ident[ELF::EI_CLASS]) { | switch(Header->e_ident[ELF::EI_CLASS]) { | |||
case ELF::ELFCLASS32: | case ELF::ELFCLASS32: | |||
switch(Header->e_machine) { | switch(Header->e_machine) { | |||
case ELF::EM_386: | case ELF::EM_386: | |||
return "ELF32-i386"; | return "ELF32-i386"; | |||
case ELF::EM_X86_64: | case ELF::EM_X86_64: | |||
return "ELF32-x86-64"; | return "ELF32-x86-64"; | |||
case ELF::EM_ARM: | case ELF::EM_ARM: | |||
return "ELF32-arm"; | return "ELF32-arm"; | |||
case ELF::EM_HEXAGON: | case ELF::EM_HEXAGON: | |||
return "ELF32-hexagon"; | return "ELF32-hexagon"; | |||
case ELF::EM_MIPS: | ||||
return "ELF32-mips"; | ||||
default: | default: | |||
return "ELF32-unknown"; | return "ELF32-unknown"; | |||
} | } | |||
case ELF::ELFCLASS64: | case ELF::ELFCLASS64: | |||
switch(Header->e_machine) { | switch(Header->e_machine) { | |||
case ELF::EM_386: | case ELF::EM_386: | |||
return "ELF64-i386"; | return "ELF64-i386"; | |||
case ELF::EM_X86_64: | case ELF::EM_X86_64: | |||
return "ELF64-x86-64"; | return "ELF64-x86-64"; | |||
case ELF::EM_AARCH64: | ||||
return "ELF64-aarch64"; | ||||
case ELF::EM_PPC64: | case ELF::EM_PPC64: | |||
return "ELF64-ppc64"; | return "ELF64-ppc64"; | |||
case ELF::EM_S390: | ||||
return "ELF64-s390"; | ||||
default: | default: | |||
return "ELF64-unknown"; | return "ELF64-unknown"; | |||
} | } | |||
default: | default: | |||
// FIXME: Proper error handling. | // FIXME: Proper error handling. | |||
report_fatal_error("Invalid ELFCLASS!"); | report_fatal_error("Invalid ELFCLASS!"); | |||
} | } | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const { | unsigned ELFObjectFile<ELFT>::getArch() const { | |||
switch(Header->e_machine) { | switch(Header->e_machine) { | |||
case ELF::EM_386: | case ELF::EM_386: | |||
return Triple::x86; | return Triple::x86; | |||
case ELF::EM_X86_64: | case ELF::EM_X86_64: | |||
return Triple::x86_64; | return Triple::x86_64; | |||
case ELF::EM_AARCH64: | ||||
return Triple::aarch64; | ||||
case ELF::EM_ARM: | case ELF::EM_ARM: | |||
return Triple::arm; | return Triple::arm; | |||
case ELF::EM_HEXAGON: | case ELF::EM_HEXAGON: | |||
return Triple::hexagon; | return Triple::hexagon; | |||
case ELF::EM_MIPS: | case ELF::EM_MIPS: | |||
return (target_endianness == support::little) ? | return (ELFT::TargetEndianness == support::little) ? | |||
Triple::mipsel : Triple::mips; | Triple::mipsel : Triple::mips; | |||
case ELF::EM_PPC64: | case ELF::EM_PPC64: | |||
return Triple::ppc64; | return Triple::ppc64; | |||
case ELF::EM_S390: | ||||
return Triple::systemz; | ||||
default: | default: | |||
return Triple::UnknownArch; | return Triple::UnknownArch; | |||
} | } | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
uint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const | uint64_t ELFObjectFile<ELFT>::getNumSections() const { | |||
{ | ||||
assert(Header && "Header not initialized!"); | assert(Header && "Header not initialized!"); | |||
if (Header->e_shnum == ELF::SHN_UNDEF) { | if (Header->e_shnum == ELF::SHN_UNDEF) { | |||
assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); | assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); | |||
return SectionHeaderTable->sh_size; | return SectionHeaderTable->sh_size; | |||
} | } | |||
return Header->e_shnum; | return Header->e_shnum; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
uint64_t | uint64_t | |||
ELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const { | ELFObjectFile<ELFT>::getStringTableIndex() const { | |||
if (Header->e_shnum == ELF::SHN_UNDEF) { | if (Header->e_shnum == ELF::SHN_UNDEF) { | |||
if (Header->e_shstrndx == ELF::SHN_HIRESERVE) | if (Header->e_shstrndx == ELF::SHN_HIRESERVE) | |||
return SectionHeaderTable->sh_link; | return SectionHeaderTable->sh_link; | |||
if (Header->e_shstrndx >= getNumSections()) | if (Header->e_shstrndx >= getNumSections()) | |||
return 0; | return 0; | |||
} | } | |||
return Header->e_shstrndx; | return Header->e_shstrndx; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
template<typename T> | template<typename T> | |||
inline const T * | inline const T * | |||
ELFObjectFile<target_endianness, is64Bits>::getEntry(uint16_t Section, | ELFObjectFile<ELFT>::getEntry(uint16_t Section, uint32_t Entry) const { | |||
uint32_t Entry) const | ||||
{ | ||||
return getEntry<T>(getSection(Section), Entry); | return getEntry<T>(getSection(Section), Entry); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
template<typename T> | template<typename T> | |||
inline const T * | inline const T * | |||
ELFObjectFile<target_endianness, is64Bits>::getEntry(const Elf_Shdr * Secti | ELFObjectFile<ELFT>::getEntry(const Elf_Shdr * Section, uint32_t Entry) con | |||
on, | st { | |||
uint32_t Entry) const | ||||
{ | ||||
return reinterpret_cast<const T *>( | return reinterpret_cast<const T *>( | |||
base() | base() | |||
+ Section->sh_offset | + Section->sh_offset | |||
+ (Entry * Section->sh_entsize)); | + (Entry * Section->sh_entsize)); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym * | const typename ELFObjectFile<ELFT>::Elf_Sym * | |||
ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) con | ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const { | |||
st { | ||||
return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a); | return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Dyn * | const typename ELFObjectFile<ELFT>::Elf_Rel * | |||
ELFObjectFile<target_endianness, is64Bits>::getDyn(DataRefImpl DynData) con | ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { | |||
st { | ||||
return getEntry<Elf_Dyn>(dot_dynamic_sec, DynData.d.a); | ||||
} | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel * | ||||
ELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const { | ||||
return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c); | return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rela * | const typename ELFObjectFile<ELFT>::Elf_Rela * | |||
ELFObjectFile<target_endianness, is64Bits>::getRela(DataRefImpl Rela) const | ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { | |||
{ | ||||
return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c); | return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * | const typename ELFObjectFile<ELFT>::Elf_Shdr * | |||
ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) co | ELFObjectFile<ELFT>::getSection(DataRefImpl Symb) const { | |||
nst { | ||||
const Elf_Shdr *sec = getSection(Symb.d.b); | const Elf_Shdr *sec = getSection(Symb.d.b); | |||
if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM) | if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM) | |||
// FIXME: Proper error handling. | // FIXME: Proper error handling. | |||
report_fatal_error("Invalid symbol table section!"); | report_fatal_error("Invalid symbol table section!"); | |||
return sec; | return sec; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * | const typename ELFObjectFile<ELFT>::Elf_Shdr * | |||
ELFObjectFile<target_endianness, is64Bits>::getSection(uint32_t index) cons | ELFObjectFile<ELFT>::getSection(uint32_t index) const { | |||
t { | ||||
if (index == 0) | if (index == 0) | |||
return 0; | return 0; | |||
if (!SectionHeaderTable || index >= getNumSections()) | if (!SectionHeaderTable || index >= getNumSections()) | |||
// FIXME: Proper error handling. | // FIXME: Proper error handling. | |||
report_fatal_error("Invalid section index!"); | report_fatal_error("Invalid section index!"); | |||
return reinterpret_cast<const Elf_Shdr *>( | return reinterpret_cast<const Elf_Shdr *>( | |||
reinterpret_cast<const char *>(SectionHeaderTable) | reinterpret_cast<const char *>(SectionHeaderTable) | |||
+ (index * Header->e_shentsize)); | + (index * Header->e_shentsize)); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const char *ELFObjectFile<target_endianness, is64Bits> | const char *ELFObjectFile<ELFT>::getString(uint32_t section, | |||
::getString(uint32_t section, | ELF::Elf32_Word offset) const { | |||
ELF::Elf32_Word offset) const { | ||||
return getString(getSection(section), offset); | return getString(getSection(section), offset); | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
const char *ELFObjectFile<target_endianness, is64Bits> | const char *ELFObjectFile<ELFT>::getString(const Elf_Shdr *section, | |||
::getString(const Elf_Shdr *section, | ELF::Elf32_Word offset) const { | |||
ELF::Elf32_Word offset) const { | ||||
assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section !"); | assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section !"); | |||
if (offset >= section->sh_size) | if (offset >= section->sh_size) | |||
// FIXME: Proper error handling. | // FIXME: Proper error handling. | |||
report_fatal_error("Symbol name offset outside of string table!"); | report_fatal_error("Symbol name offset outside of string table!"); | |||
return (const char *)base() + section->sh_offset + offset; | return (const char *)base() + section->sh_offset + offset; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolName(const Elf_Shdr *section, | |||
::getSymbolName(const Elf_Shdr *section, | const Elf_Sym *symb, | |||
const Elf_Sym *symb, | StringRef &Result) const { | |||
StringRef &Result) const { | ||||
if (symb->st_name == 0) { | if (symb->st_name == 0) { | |||
const Elf_Shdr *section = getSection(symb); | const Elf_Shdr *section = getSection(symb); | |||
if (!section) | if (!section) | |||
Result = ""; | Result = ""; | |||
else | else | |||
Result = getString(dot_shstrtab_sec, section->sh_name); | Result = getString(dot_shstrtab_sec, section->sh_name); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
if (section == SymbolTableSections[0]) { | if (section == SymbolTableSections[0]) { | |||
// Symbol is in .dynsym, use .dynstr string table | // Symbol is in .dynsym, use .dynstr string table | |||
Result = getString(dot_dynstr_sec, symb->st_name); | Result = getString(dot_dynstr_sec, symb->st_name); | |||
} else { | } else { | |||
// Use the default symbol table name section. | // Use the default symbol table name section. | |||
Result = getString(dot_strtab_sec, symb->st_name); | Result = getString(dot_strtab_sec, symb->st_name); | |||
} | } | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSectionName(const Elf_Shdr *section, | |||
::getSectionName(const Elf_Shdr *section, | StringRef &Result) const { | |||
StringRef &Result) const { | ||||
Result = StringRef(getString(dot_shstrtab_sec, section->sh_name)); | Result = StringRef(getString(dot_shstrtab_sec, section->sh_name)); | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | template<class ELFT> | |||
error_code ELFObjectFile<target_endianness, is64Bits> | error_code ELFObjectFile<ELFT>::getSymbolVersion(const Elf_Shdr *section, | |||
::getSymbolVersion(const Elf_Shdr *section, | const Elf_Sym *symb, | |||
const Elf_Sym *symb, | StringRef &Version, | |||
StringRef &Version, | bool &IsDefault) const { | |||
bool &IsDefault) const { | ||||
// Handle non-dynamic symbols. | // Handle non-dynamic symbols. | |||
if (section != SymbolTableSections[0]) { | if (section != SymbolTableSections[0]) { | |||
// Non-dynamic symbols can have versions in their names | // Non-dynamic symbols can have versions in their names | |||
// A name of the form 'foo@V1' indicates version 'V1', non-default. | // A name of the form 'foo@V1' indicates version 'V1', non-default. | |||
// A name of the form 'foo@@V2' indicates version 'V2', default version . | // A name of the form 'foo@@V2' indicates version 'V2', default version . | |||
StringRef Name; | StringRef Name; | |||
error_code ec = getSymbolName(section, symb, Name); | error_code ec = getSymbolName(section, symb, Name); | |||
if (ec != object_error::success) | if (ec != object_error::success) | |||
return ec; | return ec; | |||
size_t atpos = Name.find('@'); | size_t atpos = Name.find('@'); | |||
skipping to change at line 2582 | skipping to change at line 2944 | |||
// Set IsDefault | // Set IsDefault | |||
if (entry.isVerdef()) { | if (entry.isVerdef()) { | |||
IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN); | IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN); | |||
} else { | } else { | |||
IsDefault = false; | IsDefault = false; | |||
} | } | |||
return object_error::success; | return object_error::success; | |||
} | } | |||
template<support::endianness target_endianness, bool is64Bits> | ||||
inline DynRefImpl<target_endianness, is64Bits> | ||||
::DynRefImpl(DataRefImpl DynP, const OwningType *Owner) | ||||
: DynPimpl(DynP) | ||||
, OwningObject(Owner) {} | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
inline bool DynRefImpl<target_endianness, is64Bits> | ||||
::operator==(const DynRefImpl &Other) const { | ||||
return DynPimpl == Other.DynPimpl; | ||||
} | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
inline bool DynRefImpl<target_endianness, is64Bits> | ||||
::operator <(const DynRefImpl &Other) const { | ||||
return DynPimpl < Other.DynPimpl; | ||||
} | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
inline error_code DynRefImpl<target_endianness, is64Bits> | ||||
::getNext(DynRefImpl &Result) const { | ||||
return OwningObject->getDynNext(DynPimpl, Result); | ||||
} | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
inline int64_t DynRefImpl<target_endianness, is64Bits> | ||||
::getTag() const { | ||||
return OwningObject->getDyn(DynPimpl)->d_tag; | ||||
} | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
inline uint64_t DynRefImpl<target_endianness, is64Bits> | ||||
::getVal() const { | ||||
return OwningObject->getDyn(DynPimpl)->d_un.d_val; | ||||
} | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
inline uint64_t DynRefImpl<target_endianness, is64Bits> | ||||
::getPtr() const { | ||||
return OwningObject->getDyn(DynPimpl)->d_un.d_ptr; | ||||
} | ||||
template<support::endianness target_endianness, bool is64Bits> | ||||
inline DataRefImpl DynRefImpl<target_endianness, is64Bits> | ||||
::getRawDataRefImpl() const { | ||||
return DynPimpl; | ||||
} | ||||
/// This is a generic interface for retrieving GNU symbol version | /// This is a generic interface for retrieving GNU symbol version | |||
/// information from an ELFObjectFile. | /// information from an ELFObjectFile. | |||
static inline error_code GetELFSymbolVersion(const ObjectFile *Obj, | static inline error_code GetELFSymbolVersion(const ObjectFile *Obj, | |||
const SymbolRef &Sym, | const SymbolRef &Sym, | |||
StringRef &Version, | StringRef &Version, | |||
bool &IsDefault) { | bool &IsDefault) { | |||
// Little-endian 32-bit | // Little-endian 32-bit | |||
if (const ELFObjectFile<support::little, false> *ELFObj = | if (const ELFObjectFile<ELFType<support::little, 4, false> > *ELFObj = | |||
dyn_cast<ELFObjectFile<support::little, false> >(Obj)) | dyn_cast<ELFObjectFile<ELFType<support::little, 4, false> > >(Obj | |||
)) | ||||
return ELFObj->getSymbolVersion(Sym, Version, IsDefault); | return ELFObj->getSymbolVersion(Sym, Version, IsDefault); | |||
// Big-endian 32-bit | // Big-endian 32-bit | |||
if (const ELFObjectFile<support::big, false> *ELFObj = | if (const ELFObjectFile<ELFType<support::big, 4, false> > *ELFObj = | |||
dyn_cast<ELFObjectFile<support::big, false> >(Obj)) | dyn_cast<ELFObjectFile<ELFType<support::big, 4, false> > >(Obj)) | |||
return ELFObj->getSymbolVersion(Sym, Version, IsDefault); | return ELFObj->getSymbolVersion(Sym, Version, IsDefault); | |||
// Little-endian 64-bit | // Little-endian 64-bit | |||
if (const ELFObjectFile<support::little, true> *ELFObj = | if (const ELFObjectFile<ELFType<support::little, 8, true> > *ELFObj = | |||
dyn_cast<ELFObjectFile<support::little, true> >(Obj)) | dyn_cast<ELFObjectFile<ELFType<support::little, 8, true> > >(Obj) | |||
) | ||||
return ELFObj->getSymbolVersion(Sym, Version, IsDefault); | return ELFObj->getSymbolVersion(Sym, Version, IsDefault); | |||
// Big-endian 64-bit | // Big-endian 64-bit | |||
if (const ELFObjectFile<support::big, true> *ELFObj = | if (const ELFObjectFile<ELFType<support::big, 8, true> > *ELFObj = | |||
dyn_cast<ELFObjectFile<support::big, true> >(Obj)) | dyn_cast<ELFObjectFile<ELFType<support::big, 8, true> > >(Obj)) | |||
return ELFObj->getSymbolVersion(Sym, Version, IsDefault); | return ELFObj->getSymbolVersion(Sym, Version, IsDefault); | |||
llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); | llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); | |||
} | } | |||
/// This function returns the hash value for a symbol in the .dynsym sectio | ||||
n | ||||
/// Name of the API remains consistent as specified in the libelf | ||||
/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash | ||||
static inline unsigned elf_hash(StringRef &symbolName) { | ||||
unsigned h = 0, g; | ||||
for (unsigned i = 0, j = symbolName.size(); i < j; i++) { | ||||
h = (h << 4) + symbolName[i]; | ||||
g = h & 0xf0000000L; | ||||
if (g != 0) | ||||
h ^= g >> 24; | ||||
h &= ~g; | ||||
} | ||||
return h; | ||||
} | ||||
} | } | |||
} | } | |||
#endif | #endif | |||
End of changes. 215 change blocks. | ||||
757 lines changed or deleted | 1112 lines changed or added | |||
Endian.h | Endian.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares generic functions to read and write endian specific d ata. | // This file declares generic functions to read and write endian specific d ata. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_ENDIAN_H | #ifndef LLVM_SUPPORT_ENDIAN_H | |||
#define LLVM_SUPPORT_ENDIAN_H | #define LLVM_SUPPORT_ENDIAN_H | |||
#include "llvm/Support/AlignOf.h" | ||||
#include "llvm/Support/Host.h" | #include "llvm/Support/Host.h" | |||
#include "llvm/Support/SwapByteOrder.h" | #include "llvm/Support/SwapByteOrder.h" | |||
#include "llvm/Support/type_traits.h" | #include "llvm/Support/type_traits.h" | |||
namespace llvm { | namespace llvm { | |||
namespace support { | namespace support { | |||
enum endianness {big, little, native}; | ||||
enum endianness {big, little}; | // These are named values for common alignments. | |||
enum alignment {unaligned, aligned}; | enum {aligned = 0, unaligned = 1}; | |||
namespace detail { | namespace detail { | |||
/// \brief ::value is either alignment, or alignof(T) if alignment is 0. | ||||
template<typename value_type, alignment align> | template<class T, int alignment> | |||
struct alignment_access_helper; | struct PickAlignment { | |||
enum {value = alignment == 0 ? AlignOf<T>::Alignment : alignment}; | ||||
template<typename value_type> | }; | |||
struct alignment_access_helper<value_type, aligned> | ||||
{ | ||||
value_type val; | ||||
}; | ||||
// Provides unaligned loads and stores. | ||||
#pragma pack(push) | ||||
#pragma pack(1) | ||||
template<typename value_type> | ||||
struct alignment_access_helper<value_type, unaligned> | ||||
{ | ||||
value_type val; | ||||
}; | ||||
#pragma pack(pop) | ||||
} // end namespace detail | } // end namespace detail | |||
namespace endian { | namespace endian { | |||
template<typename value_type, alignment align> | template<typename value_type, endianness endian> | |||
inline value_type read_le(const void *memory) { | inline value_type byte_swap(value_type value) { | |||
value_type t = | if (endian != native && sys::IsBigEndianHost != (endian == big)) | |||
reinterpret_cast<const detail::alignment_access_helper | return sys::SwapByteOrder(value); | |||
<value_type, align> *>(memory)->val; | return value; | |||
if (sys::isBigEndianHost()) | } | |||
return sys::SwapByteOrder(t); | ||||
return t; | ||||
} | ||||
template<typename value_type, alignment align> | ||||
inline void write_le(void *memory, value_type value) { | ||||
if (sys::isBigEndianHost()) | ||||
value = sys::SwapByteOrder(value); | ||||
reinterpret_cast<detail::alignment_access_helper<value_type, align> *> | ||||
(memory)->val = value; | ||||
} | ||||
template<typename value_type, alignment align> | template<typename value_type, | |||
inline value_type read_be(const void *memory) { | endianness endian, | |||
value_type t = | std::size_t alignment> | |||
reinterpret_cast<const detail::alignment_access_helper | inline value_type read(const void *memory) { | |||
<value_type, align> *>(memory)->val; | value_type ret; | |||
if (sys::isLittleEndianHost()) | ||||
return sys::SwapByteOrder(t); | memcpy(&ret, | |||
return t; | LLVM_ASSUME_ALIGNED(memory, | |||
} | (detail::PickAlignment<value_type, alignment>::value)), | |||
sizeof(value_type)); | ||||
return byte_swap<value_type, endian>(ret); | ||||
} | ||||
template<typename value_type, alignment align> | template<typename value_type, | |||
inline void write_be(void *memory, value_type value) { | endianness endian, | |||
if (sys::isLittleEndianHost()) | std::size_t alignment> | |||
value = sys::SwapByteOrder(value); | inline void write(void *memory, value_type value) { | |||
reinterpret_cast<detail::alignment_access_helper<value_type, align> *> | value = byte_swap<value_type, endian>(value); | |||
(memory)->val = value; | memcpy(LLVM_ASSUME_ALIGNED(memory, | |||
} | (detail::PickAlignment<value_type, alignment>::value)), | |||
&value, | ||||
sizeof(value_type)); | ||||
} | } | |||
} // end namespace endian | ||||
namespace detail { | namespace detail { | |||
template<typename value_type, | template<typename value_type, | |||
endianness endian, | endianness endian, | |||
alignment align> | std::size_t alignment> | |||
class packed_endian_specific_integral; | struct packed_endian_specific_integral { | |||
template<typename value_type> | ||||
class packed_endian_specific_integral<value_type, little, unaligned> { | ||||
public: | ||||
operator value_type() const { | ||||
return endian::read_le<value_type, unaligned>(Value); | ||||
} | ||||
void operator=(value_type newValue) { | ||||
endian::write_le<value_type, unaligned>((void *)&Value, newValue); | ||||
} | ||||
private: | ||||
uint8_t Value[sizeof(value_type)]; | ||||
}; | ||||
template<typename value_type> | ||||
class packed_endian_specific_integral<value_type, big, unaligned> { | ||||
public: | ||||
operator value_type() const { | operator value_type() const { | |||
return endian::read_be<value_type, unaligned>(Value); | return endian::read<value_type, endian, alignment>( | |||
(const void*)Value.buffer); | ||||
} | } | |||
void operator=(value_type newValue) { | ||||
endian::write_be<value_type, unaligned>((void *)&Value, newValue); | ||||
} | ||||
private: | ||||
uint8_t Value[sizeof(value_type)]; | ||||
}; | ||||
template<typename value_type> | ||||
class packed_endian_specific_integral<value_type, little, aligned> { | ||||
public: | ||||
operator value_type() const { | ||||
return endian::read_le<value_type, aligned>(&Value); | ||||
} | ||||
void operator=(value_type newValue) { | void operator=(value_type newValue) { | |||
endian::write_le<value_type, aligned>((void *)&Value, newValue); | endian::write<value_type, endian, alignment>( | |||
(void*)Value.buffer, newValue); | ||||
} | } | |||
private: | ||||
value_type Value; | ||||
}; | ||||
template<typename value_type> | ||||
class packed_endian_specific_integral<value_type, big, aligned> { | ||||
public: | ||||
operator value_type() const { | ||||
return endian::read_be<value_type, aligned>(&Value); | ||||
} | ||||
void operator=(value_type newValue) { | ||||
endian::write_be<value_type, aligned>((void *)&Value, newValue); | ||||
} | ||||
private: | private: | |||
value_type Value; | AlignedCharArray<PickAlignment<value_type, alignment>::value, | |||
sizeof(value_type)> Value; | ||||
}; | }; | |||
} // end namespace detail | } // end namespace detail | |||
typedef detail::packed_endian_specific_integral | typedef detail::packed_endian_specific_integral | |||
<uint8_t, little, unaligned> ulittle8_t; | <uint8_t, little, unaligned> ulittle8_t; | |||
typedef detail::packed_endian_specific_integral | typedef detail::packed_endian_specific_integral | |||
<uint16_t, little, unaligned> ulittle16_t; | <uint16_t, little, unaligned> ulittle16_t; | |||
typedef detail::packed_endian_specific_integral | typedef detail::packed_endian_specific_integral | |||
<uint32_t, little, unaligned> ulittle32_t; | <uint32_t, little, unaligned> ulittle32_t; | |||
typedef detail::packed_endian_specific_integral | typedef detail::packed_endian_specific_integral | |||
<uint64_t, little, unaligned> ulittle64_t; | <uint64_t, little, unaligned> ulittle64_t; | |||
skipping to change at line 221 | skipping to change at line 163 | |||
typedef detail::packed_endian_specific_integral | typedef detail::packed_endian_specific_integral | |||
<int8_t, big, aligned> aligned_big8_t; | <int8_t, big, aligned> aligned_big8_t; | |||
typedef detail::packed_endian_specific_integral | typedef detail::packed_endian_specific_integral | |||
<int16_t, big, aligned> aligned_big16_t; | <int16_t, big, aligned> aligned_big16_t; | |||
typedef detail::packed_endian_specific_integral | typedef detail::packed_endian_specific_integral | |||
<int32_t, big, aligned> aligned_big32_t; | <int32_t, big, aligned> aligned_big32_t; | |||
typedef detail::packed_endian_specific_integral | typedef detail::packed_endian_specific_integral | |||
<int64_t, big, aligned> aligned_big64_t; | <int64_t, big, aligned> aligned_big64_t; | |||
typedef detail::packed_endian_specific_integral | ||||
<uint16_t, native, unaligned> unaligned_uint16_t; | ||||
typedef detail::packed_endian_specific_integral | ||||
<uint32_t, native, unaligned> unaligned_uint32_t; | ||||
typedef detail::packed_endian_specific_integral | ||||
<uint64_t, native, unaligned> unaligned_uint64_t; | ||||
typedef detail::packed_endian_specific_integral | ||||
<int16_t, native, unaligned> unaligned_int16_t; | ||||
typedef detail::packed_endian_specific_integral | ||||
<int32_t, native, unaligned> unaligned_int32_t; | ||||
typedef detail::packed_endian_specific_integral | ||||
<int64_t, native, unaligned> unaligned_int64_t; | ||||
} // end namespace llvm | } // end namespace llvm | |||
} // end namespace support | } // end namespace support | |||
#endif | #endif | |||
End of changes. 19 change blocks. | ||||
103 lines changed or deleted | 58 lines changed or added | |||
Errno.h | Errno.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares some portable and convenient functions to deal with e rrno. | // This file declares some portable and convenient functions to deal with e rrno. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_ERRNO_H | #ifndef LLVM_SUPPORT_ERRNO_H | |||
#define LLVM_SYSTEM_ERRNO_H | #define LLVM_SUPPORT_ERRNO_H | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
/// Returns a string representation of the errno value, using whatever | /// Returns a string representation of the errno value, using whatever | |||
/// thread-safe variant of strerror() is available. Be sure to call this | /// thread-safe variant of strerror() is available. Be sure to call this | |||
/// immediately after the function that set errno, or errno may have been | /// immediately after the function that set errno, or errno may have been | |||
/// overwritten by an intervening call. | /// overwritten by an intervening call. | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
ErrorHandling.h | ErrorHandling.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines an API used to indicate fatal error conditions. Non-f atal | // This file defines an API used to indicate fatal error conditions. Non-f atal | |||
// errors (most of them) should be handled through LLVMContext. | // errors (most of them) should be handled through LLVMContext. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_ERRORHANDLING_H | #ifndef LLVM_SUPPORT_ERRORHANDLING_H | |||
#define LLVM_SUPPORT_ERRORHANDLING_H | #define LLVM_SUPPORT_ERRORHANDLING_H | |||
#include "llvm/Support/Compiler.h" | ||||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/Compiler.h" | ||||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class Twine; | class Twine; | |||
/// An error handler callback. | /// An error handler callback. | |||
typedef void (*fatal_error_handler_t)(void *user_data, | typedef void (*fatal_error_handler_t)(void *user_data, | |||
const std::string& reason); | const std::string& reason, | |||
bool gen_crash_diag); | ||||
/// install_fatal_error_handler - Installs a new error handler to be used | /// install_fatal_error_handler - Installs a new error handler to be used | |||
/// whenever a serious (non-recoverable) error is encountered by LLVM. | /// whenever a serious (non-recoverable) error is encountered by LLVM. | |||
/// | /// | |||
/// If you are using llvm_start_multithreaded, you should register the ha ndler | /// If you are using llvm_start_multithreaded, you should register the ha ndler | |||
/// before doing that. | /// before doing that. | |||
/// | /// | |||
/// If no error handler is installed the default is to print the error me ssage | /// If no error handler is installed the default is to print the error me ssage | |||
/// to stderr, and call exit(1). If an error handler is installed then i t is | /// to stderr, and call exit(1). If an error handler is installed then i t is | |||
/// the handler's responsibility to log the message, it will no longer be | /// the handler's responsibility to log the message, it will no longer be | |||
skipping to change at line 76 | skipping to change at line 77 | |||
}; | }; | |||
/// Reports a serious error, calling any installed error handler. These | /// Reports a serious error, calling any installed error handler. These | |||
/// functions are intended to be used for error conditions which are outs ide | /// functions are intended to be used for error conditions which are outs ide | |||
/// the control of the compiler (I/O errors, invalid user input, etc.) | /// the control of the compiler (I/O errors, invalid user input, etc.) | |||
/// | /// | |||
/// If no error handler is installed the default is to print the message to | /// If no error handler is installed the default is to print the message to | |||
/// standard error, followed by a newline. | /// standard error, followed by a newline. | |||
/// After the error handler is called this function will call exit(1), it | /// After the error handler is called this function will call exit(1), it | |||
/// does not return. | /// does not return. | |||
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason); | LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, | |||
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason | bool gen_crash_diag = tru | |||
); | e); | |||
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason); | LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason | |||
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason); | , | |||
bool gen_crash_diag = tru | ||||
e); | ||||
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason, | ||||
bool gen_crash_diag = tru | ||||
e); | ||||
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason, | ||||
bool gen_crash_diag = tru | ||||
e); | ||||
/// This function calls abort(), and prints the optional message to stder r. | /// This function calls abort(), and prints the optional message to stder r. | |||
/// Use the llvm_unreachable macro (that adds location info), instead of | /// Use the llvm_unreachable macro (that adds location info), instead of | |||
/// calling this function directly. | /// calling this function directly. | |||
LLVM_ATTRIBUTE_NORETURN void llvm_unreachable_internal(const char *msg=0, | LLVM_ATTRIBUTE_NORETURN void llvm_unreachable_internal(const char *msg=0, | |||
const char *file=0 , | const char *file=0 , | |||
unsigned line=0); | unsigned line=0); | |||
} | } | |||
/// Marks that the current location is not supposed to be reachable. | /// Marks that the current location is not supposed to be reachable. | |||
End of changes. 4 change blocks. | ||||
7 lines changed or deleted | 16 lines changed or added | |||
ExecutionEngine.h | ExecutionEngine.h | |||
---|---|---|---|---|
skipping to change at line 24 | skipping to change at line 24 | |||
|* with C++ due to name mangling. So in addition to C, this interface enabl es *| | |* with C++ due to name mangling. So in addition to C, this interface enabl es *| | |||
|* tools written in such languages. *| | |* tools written in such languages. *| | |||
|* *| | |* *| | |||
\*===---------------------------------------------------------------------- ===*/ | \*===---------------------------------------------------------------------- ===*/ | |||
#ifndef LLVM_C_EXECUTIONENGINE_H | #ifndef LLVM_C_EXECUTIONENGINE_H | |||
#define LLVM_C_EXECUTIONENGINE_H | #define LLVM_C_EXECUTIONENGINE_H | |||
#include "llvm-c/Core.h" | #include "llvm-c/Core.h" | |||
#include "llvm-c/Target.h" | #include "llvm-c/Target.h" | |||
#include "llvm-c/TargetMachine.h" | ||||
#ifdef __cplusplus | #ifdef __cplusplus | |||
extern "C" { | extern "C" { | |||
#endif | #endif | |||
/** | /** | |||
* @defgroup LLVMCExecutionEngine Execution Engine | * @defgroup LLVMCExecutionEngine Execution Engine | |||
* @ingroup LLVMC | * @ingroup LLVMC | |||
* | * | |||
* @{ | * @{ | |||
*/ | */ | |||
void LLVMLinkInJIT(void); | void LLVMLinkInJIT(void); | |||
void LLVMLinkInMCJIT(void); | ||||
void LLVMLinkInInterpreter(void); | void LLVMLinkInInterpreter(void); | |||
typedef struct LLVMOpaqueGenericValue *LLVMGenericValueRef; | typedef struct LLVMOpaqueGenericValue *LLVMGenericValueRef; | |||
typedef struct LLVMOpaqueExecutionEngine *LLVMExecutionEngineRef; | typedef struct LLVMOpaqueExecutionEngine *LLVMExecutionEngineRef; | |||
struct LLVMMCJITCompilerOptions { | ||||
unsigned OptLevel; | ||||
LLVMCodeModel CodeModel; | ||||
LLVMBool NoFramePointerElim; | ||||
LLVMBool EnableFastISel; | ||||
}; | ||||
/*===-- Operations on generic values -------------------------------------- ===*/ | /*===-- Operations on generic values -------------------------------------- ===*/ | |||
LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty, | LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty, | |||
unsigned long long N, | unsigned long long N, | |||
LLVMBool IsSigned); | LLVMBool IsSigned); | |||
LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P); | LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P); | |||
LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef Ty, double N) ; | LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef Ty, double N) ; | |||
skipping to change at line 78 | skipping to change at line 87 | |||
LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp, | LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp, | |||
LLVMModuleRef M, | LLVMModuleRef M, | |||
char **OutError); | char **OutError); | |||
LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, | LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, | |||
LLVMModuleRef M, | LLVMModuleRef M, | |||
unsigned OptLevel, | unsigned OptLevel, | |||
char **OutError); | char **OutError); | |||
void LLVMInitializeMCJITCompilerOptions( | ||||
struct LLVMMCJITCompilerOptions *Options, size_t SizeOfOptions); | ||||
/** | ||||
* Create an MCJIT execution engine for a module, with the given options. I | ||||
t is | ||||
* the responsibility of the caller to ensure that all fields in Options up | ||||
to | ||||
* the given SizeOfOptions are initialized. It is correct to pass a smaller | ||||
* value of SizeOfOptions that omits some fields. The canonical way of usin | ||||
g | ||||
* this is: | ||||
* | ||||
* LLVMMCJITCompilerOptions options; | ||||
* LLVMInitializeMCJITCompilerOptions(&options, sizeof(options)); | ||||
* ... fill in those options you care about | ||||
* LLVMCreateMCJITCompilerForModule(&jit, mod, &options, sizeof(options), | ||||
* &error); | ||||
* | ||||
* Note that this is also correct, though possibly suboptimal: | ||||
* | ||||
* LLVMCreateMCJITCompilerForModule(&jit, mod, 0, 0, &error); | ||||
*/ | ||||
LLVMBool LLVMCreateMCJITCompilerForModule( | ||||
LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M, | ||||
struct LLVMMCJITCompilerOptions *Options, size_t SizeOfOptions, | ||||
char **OutError); | ||||
/** Deprecated: Use LLVMCreateExecutionEngineForModule instead. */ | /** Deprecated: Use LLVMCreateExecutionEngineForModule instead. */ | |||
LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE, | LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE, | |||
LLVMModuleProviderRef MP, | LLVMModuleProviderRef MP, | |||
char **OutError); | char **OutError); | |||
/** Deprecated: Use LLVMCreateInterpreterForModule instead. */ | /** Deprecated: Use LLVMCreateInterpreterForModule instead. */ | |||
LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp, | LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp, | |||
LLVMModuleProviderRef MP, | LLVMModuleProviderRef MP, | |||
char **OutError); | char **OutError); | |||
skipping to change at line 126 | skipping to change at line 160 | |||
LLVMModuleRef *OutMod, char **OutError); | LLVMModuleRef *OutMod, char **OutError); | |||
/** Deprecated: Use LLVMRemoveModule instead. */ | /** Deprecated: Use LLVMRemoveModule instead. */ | |||
LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE, | LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE, | |||
LLVMModuleProviderRef MP, | LLVMModuleProviderRef MP, | |||
LLVMModuleRef *OutMod, char **OutError); | LLVMModuleRef *OutMod, char **OutError); | |||
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name, | LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name, | |||
LLVMValueRef *OutFn); | LLVMValueRef *OutFn); | |||
void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, LLVMValueRe | void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, | |||
f Fn); | LLVMValueRef Fn); | |||
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef E E); | LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef E E); | |||
void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global, | void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global, | |||
void* Addr); | void* Addr); | |||
void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global ); | void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global ); | |||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} | } | |||
namespace llvm { | ||||
struct GenericValue; | ||||
class ExecutionEngine; | ||||
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \ | ||||
inline ty *unwrap(ref P) { \ | ||||
return reinterpret_cast<ty*>(P); \ | ||||
} \ | ||||
\ | ||||
inline ref wrap(const ty *P) { \ | ||||
return reinterpret_cast<ref>(const_cast<ty*>(P)); \ | ||||
} | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef | ||||
) | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRe | ||||
f) | ||||
#undef DEFINE_SIMPLE_CONVERSION_FUNCTIONS | ||||
} | ||||
#endif /* defined(__cplusplus) */ | #endif /* defined(__cplusplus) */ | |||
#endif | #endif | |||
End of changes. 6 change blocks. | ||||
24 lines changed or deleted | 39 lines changed or added | |||
FEnv.h | FEnv.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file provides an operating system independent interface to | // This file provides an operating system independent interface to | |||
// floating-point exception interfaces. | // floating-point exception interfaces. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_FENV_H | #ifndef LLVM_SUPPORT_FENV_H | |||
#define LLVM_SYSTEM_FENV_H | #define LLVM_SUPPORT_FENV_H | |||
#include "llvm/Config/config.h" | #include "llvm/Config/config.h" | |||
#include <cerrno> | #include <cerrno> | |||
#ifdef HAVE_FENV_H | #ifdef HAVE_FENV_H | |||
#include <fenv.h> | #include <fenv.h> | |||
#endif | #endif | |||
// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s | // FIXME: Clang's #include handling apparently doesn't work for libstdc++'s | |||
// fenv.h; see PR6907 for details. | // fenv.h; see PR6907 for details. | |||
#if defined(__clang__) && defined(_GLIBCXX_FENV_H) | #if defined(__clang__) && defined(_GLIBCXX_FENV_H) | |||
#undef HAVE_FENV_H | #undef HAVE_FENV_H | |||
#endif | #endif | |||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
/// llvm_fenv_clearexcept - Clear the floating-point exception state. | /// llvm_fenv_clearexcept - Clear the floating-point exception state. | |||
static inline void llvm_fenv_clearexcept() { | static inline void llvm_fenv_clearexcept() { | |||
#ifdef HAVE_FENV_H | #if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT | |||
feclearexcept(FE_ALL_EXCEPT); | feclearexcept(FE_ALL_EXCEPT); | |||
#endif | #endif | |||
errno = 0; | errno = 0; | |||
} | } | |||
/// llvm_fenv_testexcept - Test if a floating-point exception was raised. | /// llvm_fenv_testexcept - Test if a floating-point exception was raised. | |||
static inline bool llvm_fenv_testexcept() { | static inline bool llvm_fenv_testexcept() { | |||
int errno_val = errno; | int errno_val = errno; | |||
if (errno_val == ERANGE || errno_val == EDOM) | if (errno_val == ERANGE || errno_val == EDOM) | |||
return true; | return true; | |||
#ifdef HAVE_FENV_H | #if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT | |||
if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT)) | if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT)) | |||
return true; | return true; | |||
#endif | #endif | |||
return false; | return false; | |||
} | } | |||
} // End sys namespace | } // End sys namespace | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 3 change blocks. | ||||
4 lines changed or deleted | 4 lines changed or added | |||
FastISel.h | FastISel.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the FastISel class. | // This file defines the FastISel class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_FASTISEL_H | #ifndef LLVM_CODEGEN_FASTISEL_H | |||
#define LLVM_CODEGEN_FASTISEL_H | #define LLVM_CODEGEN_FASTISEL_H | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/CodeGen/ValueTypes.h" | ||||
#include "llvm/CodeGen/MachineBasicBlock.h" | #include "llvm/CodeGen/MachineBasicBlock.h" | |||
#include "llvm/CodeGen/ValueTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
class AllocaInst; | class AllocaInst; | |||
class Constant; | class Constant; | |||
class ConstantFP; | class ConstantFP; | |||
class FunctionLoweringInfo; | class FunctionLoweringInfo; | |||
class Instruction; | class Instruction; | |||
class LoadInst; | class LoadInst; | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
skipping to change at line 94 | skipping to change at line 94 | |||
} | } | |||
/// startNewBlock - Set the current block to which generated machine | /// startNewBlock - Set the current block to which generated machine | |||
/// instructions will be appended, and clear the local CSE map. | /// instructions will be appended, and clear the local CSE map. | |||
/// | /// | |||
void startNewBlock(); | void startNewBlock(); | |||
/// getCurDebugLoc() - Return current debug location information. | /// getCurDebugLoc() - Return current debug location information. | |||
DebugLoc getCurDebugLoc() const { return DL; } | DebugLoc getCurDebugLoc() const { return DL; } | |||
/// LowerArguments - Do "fast" instruction selection for function argumen | ||||
ts | ||||
/// and append machine instructions to the current block. Return true if | ||||
/// it is successful. | ||||
bool LowerArguments(); | ||||
/// SelectInstruction - Do "fast" instruction selection for the given | /// SelectInstruction - Do "fast" instruction selection for the given | |||
/// LLVM IR instruction, and append generated machine instructions to | /// LLVM IR instruction, and append generated machine instructions to | |||
/// the current block. Return true if selection was successful. | /// the current block. Return true if selection was successful. | |||
/// | /// | |||
bool SelectInstruction(const Instruction *I); | bool SelectInstruction(const Instruction *I); | |||
/// SelectOperator - Do "fast" instruction selection for the given | /// SelectOperator - Do "fast" instruction selection for the given | |||
/// LLVM IR operator (Instruction or ConstantExpr), and append | /// LLVM IR operator (Instruction or ConstantExpr), and append | |||
/// generated machine instructions to the current block. Return true | /// generated machine instructions to the current block. Return true | |||
/// if selection was successful. | /// if selection was successful. | |||
skipping to change at line 121 | skipping to change at line 126 | |||
/// lookUpRegForValue - Look up the value to see if its value is already | /// 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 | /// cached in a register. It may be defined by instructions across blocks or | |||
/// defined locally. | /// defined locally. | |||
unsigned lookUpRegForValue(const Value *V); | unsigned lookUpRegForValue(const Value *V); | |||
/// getRegForGEPIndex - This is a wrapper around getRegForValue that also | /// getRegForGEPIndex - This is a wrapper around getRegForValue that also | |||
/// takes care of truncating or sign-extending the given getelementptr | /// takes care of truncating or sign-extending the given getelementptr | |||
/// index value. | /// index value. | |||
std::pair<unsigned, bool> getRegForGEPIndex(const Value *V); | std::pair<unsigned, bool> getRegForGEPIndex(const Value *V); | |||
/// TryToFoldLoad - The specified machine instr operand is a vreg, and th | /// \brief We're checking to see if we can fold \p LI into \p FoldInst. | |||
at | /// Note that we could have a sequence where multiple LLVM IR instruction | |||
s | ||||
/// 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. | ||||
/// | ||||
/// 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 possibl e, | /// vreg is being provided by the specified load instruction. If possibl e, | |||
/// try to fold the load as an operand to the instruction, returning true if | /// try to fold the load as an operand to the instruction, returning true if | |||
/// possible. | /// possible. | |||
virtual bool TryToFoldLoad(MachineInstr * /*MI*/, unsigned /*OpNo*/, | /// This method should be implemented by targets. | |||
const LoadInst * /*LI*/) { | virtual bool tryToFoldLoadIntoMI(MachineInstr * /*MI*/, unsigned /*OpNo*/ | |||
, | ||||
const LoadInst * /*LI*/) { | ||||
return false; | return false; | |||
} | } | |||
/// recomputeInsertPt - Reset InsertPt to prepare for inserting instructi ons | /// recomputeInsertPt - Reset InsertPt to prepare for inserting instructi ons | |||
/// into the current block. | /// into the current block. | |||
void recomputeInsertPt(); | void recomputeInsertPt(); | |||
/// removeDeadCode - Remove all dead instructions between the I and E. | ||||
void removeDeadCode(MachineBasicBlock::iterator I, | ||||
MachineBasicBlock::iterator E); | ||||
struct SavePoint { | struct SavePoint { | |||
MachineBasicBlock::iterator InsertPt; | MachineBasicBlock::iterator InsertPt; | |||
DebugLoc DL; | DebugLoc DL; | |||
}; | }; | |||
/// enterLocalValueArea - Prepare InsertPt to begin inserting instruction s | /// enterLocalValueArea - Prepare InsertPt to begin inserting instruction s | |||
/// into the local value area and return the old insert position. | /// into the local value area and return the old insert position. | |||
SavePoint enterLocalValueArea(); | SavePoint enterLocalValueArea(); | |||
/// leaveLocalValueArea - Reset InsertPt to the given old insert position . | /// leaveLocalValueArea - Reset InsertPt to the given old insert position . | |||
skipping to change at line 160 | skipping to change at line 185 | |||
const TargetLibraryInfo *libInfo); | const TargetLibraryInfo *libInfo); | |||
/// TargetSelectInstruction - This method is called by target-independent | /// TargetSelectInstruction - This method is called by target-independent | |||
/// code when the normal FastISel process fails to select an instruction. | /// code when the normal FastISel process fails to select an instruction. | |||
/// This gives targets a chance to emit code for anything that doesn't | /// 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. | /// fit into FastISel's framework. It returns true if it was successful. | |||
/// | /// | |||
virtual bool | virtual bool | |||
TargetSelectInstruction(const Instruction *I) = 0; | 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. | ||||
virtual bool FastLowerArguments(); | ||||
/// FastEmit_r - This method is called by target-independent code | /// FastEmit_r - This method is called by target-independent code | |||
/// to request that an instruction with the given type and opcode | /// to request that an instruction with the given type and opcode | |||
/// be emitted. | /// be emitted. | |||
virtual unsigned FastEmit_(MVT VT, | virtual unsigned FastEmit_(MVT VT, | |||
MVT RetVT, | MVT RetVT, | |||
unsigned Opcode); | unsigned Opcode); | |||
/// FastEmit_r - This method is called by target-independent code | /// FastEmit_r - This method is called by target-independent code | |||
/// to request that an instruction with the given type, opcode, and | /// to request that an instruction with the given type, opcode, and | |||
/// register operand be emitted. | /// register operand be emitted. | |||
skipping to change at line 398 | skipping to change at line 428 | |||
/// be materialized with new instructions. | /// be materialized with new instructions. | |||
unsigned materializeRegForValue(const Value *V, MVT VT); | unsigned materializeRegForValue(const Value *V, MVT VT); | |||
/// flushLocalValueMap - clears LocalValueMap and moves the area for the | /// flushLocalValueMap - clears LocalValueMap and moves the area for the | |||
/// new local variables to the beginning of the block. It helps to avoid | /// new local variables to the beginning of the block. It helps to avoid | |||
/// spilling cached variables across heavy instructions like calls. | /// spilling cached variables across heavy instructions like calls. | |||
void flushLocalValueMap(); | void flushLocalValueMap(); | |||
/// hasTrivialKill - Test whether the given value has exactly one use. | /// hasTrivialKill - Test whether the given value has exactly one use. | |||
bool hasTrivialKill(const Value *V) const; | bool hasTrivialKill(const Value *V) const; | |||
/// removeDeadCode - Remove all dead instructions between the I and E. | ||||
void removeDeadCode(MachineBasicBlock::iterator I, | ||||
MachineBasicBlock::iterator E); | ||||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 8 change blocks. | ||||
9 lines changed or deleted | 38 lines changed or added | |||
FileOutputBuffer.h | FileOutputBuffer.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// Utility for creating a in-memory buffer that will be written to a file. | // Utility for creating a in-memory buffer that will be written to a file. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H | #ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H | |||
#define LLVM_SUPPORT_FILEOUTPUTBUFFER_H | #define LLVM_SUPPORT_FILEOUTPUTBUFFER_H | |||
#include "llvm/ADT/OwningPtr.h" | ||||
#include "llvm/ADT/SmallString.h" | #include "llvm/ADT/SmallString.h" | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/FileSystem.h" | ||||
namespace llvm { | namespace llvm { | |||
class error_code; | class error_code; | |||
template<class T> class OwningPtr; | ||||
/// FileOutputBuffer - This interface provides simple way to create an in-m emory | /// FileOutputBuffer - This interface provides simple way to create an in-m emory | |||
/// buffer which will be written to a file. During the lifetime of these | /// buffer which will be written to a file. During the lifetime of these | |||
/// objects, the content or existence of the specified file is undefined. T hat | /// objects, the content or existence of the specified file is undefined. T hat | |||
/// is, creating an OutputBuffer for a file may immediately remove the file . | /// is, creating an OutputBuffer for a file may immediately remove the file . | |||
/// If the FileOutputBuffer is committed, the target file's content will be come | /// If the FileOutputBuffer is committed, the target file's content will be come | |||
/// the buffer content at the time of the commit. If the FileOutputBuffer is | /// the buffer content at the time of the commit. If the FileOutputBuffer is | |||
/// not committed, the file will be deleted in the FileOutputBuffer destruc tor. | /// not committed, the file will be deleted in the FileOutputBuffer destruc tor. | |||
class FileOutputBuffer { | class FileOutputBuffer { | |||
public: | public: | |||
enum { | enum { | |||
F_executable = 1 /// set the 'x' bit on the resulting file | F_executable = 1 /// set the 'x' bit on the resulting file | |||
}; | }; | |||
/// Factory method to create an OutputBuffer object which manages a read/ write | /// Factory method to create an OutputBuffer object which manages a read/ write | |||
/// buffer of the specified size. When committed, the buffer will be writ ten | /// buffer of the specified size. When committed, the buffer will be writ ten | |||
/// to the file at the specified path. | /// to the file at the specified path. | |||
static error_code create(StringRef FilePath, size_t Size, | static error_code create(StringRef FilePath, size_t Size, | |||
OwningPtr<FileOutputBuffer> &Result, | OwningPtr<FileOutputBuffer> &Result, | |||
unsigned Flags=0); | unsigned Flags = 0); | |||
/// Returns a pointer to the start of the buffer. | /// Returns a pointer to the start of the buffer. | |||
uint8_t *getBufferStart() const { | uint8_t *getBufferStart() { | |||
return BufferStart; | return (uint8_t*)Region->data(); | |||
} | } | |||
/// Returns a pointer to the end of the buffer. | /// Returns a pointer to the end of the buffer. | |||
uint8_t *getBufferEnd() const { | uint8_t *getBufferEnd() { | |||
return BufferEnd; | return (uint8_t*)Region->data() + Region->size(); | |||
} | } | |||
/// Returns size of the buffer. | /// Returns size of the buffer. | |||
size_t getBufferSize() const { | size_t getBufferSize() const { | |||
return BufferEnd - BufferStart; | return Region->size(); | |||
} | } | |||
/// Returns path where file will show up if buffer is committed. | /// Returns path where file will show up if buffer is committed. | |||
StringRef getPath() const { | StringRef getPath() const { | |||
return FinalPath; | return FinalPath; | |||
} | } | |||
/// Flushes the content of the buffer to its file and deallocates the | /// Flushes the content of the buffer to its file and deallocates the | |||
/// buffer. If commit() is not called before this object's destructor | /// buffer. If commit() is not called before this object's destructor | |||
/// is called, the file is deleted in the destructor. The optional parame ter | /// is called, the file is deleted in the destructor. The optional parame ter | |||
skipping to change at line 82 | skipping to change at line 82 | |||
error_code commit(int64_t NewSmallerSize = -1); | error_code commit(int64_t NewSmallerSize = -1); | |||
/// If this object was previously committed, the destructor just deletes | /// If this object was previously committed, the destructor just deletes | |||
/// this object. If this object was not committed, the destructor | /// this object. If this object was not committed, the destructor | |||
/// deallocates the buffer and the target file is never written. | /// deallocates the buffer and the target file is never written. | |||
~FileOutputBuffer(); | ~FileOutputBuffer(); | |||
private: | private: | |||
FileOutputBuffer(const FileOutputBuffer &) LLVM_DELETED_FUNCTION; | FileOutputBuffer(const FileOutputBuffer &) LLVM_DELETED_FUNCTION; | |||
FileOutputBuffer &operator=(const FileOutputBuffer &) LLVM_DELETED_FUNCTI ON; | FileOutputBuffer &operator=(const FileOutputBuffer &) LLVM_DELETED_FUNCTI ON; | |||
protected: | ||||
FileOutputBuffer(uint8_t *Start, uint8_t *End, | ||||
StringRef Path, StringRef TempPath); | ||||
uint8_t *BufferStart; | FileOutputBuffer(llvm::sys::fs::mapped_file_region *R, | |||
uint8_t *BufferEnd; | StringRef Path, StringRef TempPath); | |||
OwningPtr<llvm::sys::fs::mapped_file_region> Region; | ||||
SmallString<128> FinalPath; | SmallString<128> FinalPath; | |||
SmallString<128> TempPath; | SmallString<128> TempPath; | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 11 change blocks. | ||||
14 lines changed or deleted | 12 lines changed or added | |||
FileSystem.h | FileSystem.h | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
// category. However, they shall be equivalent to any error conditions list ed | // category. However, they shall be equivalent to any error conditions list ed | |||
// in each functions respective documentation if the condition applies. [ n ote: | // in each functions respective documentation if the condition applies. [ n ote: | |||
// this does not guarantee that error_code will be in the set of explicitly | // this does not guarantee that error_code will be in the set of explicitly | |||
// listed codes, but it does guarantee that if any of the explicitly listed | // listed codes, but it does guarantee that if any of the explicitly listed | |||
// errors occur, the correct error_code will be used ]. All functions may | // errors occur, the correct error_code will be used ]. All functions may | |||
// return errc::not_enough_memory if there is not enough memory to complete the | // return errc::not_enough_memory if there is not enough memory to complete the | |||
// operation. | // operation. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_FILE_SYSTEM_H | #ifndef LLVM_SUPPORT_FILESYSTEM_H | |||
#define LLVM_SUPPORT_FILE_SYSTEM_H | #define LLVM_SUPPORT_FILESYSTEM_H | |||
#include "llvm/ADT/IntrusiveRefCntPtr.h" | #include "llvm/ADT/IntrusiveRefCntPtr.h" | |||
#include "llvm/ADT/OwningPtr.h" | #include "llvm/ADT/OwningPtr.h" | |||
#include "llvm/ADT/SmallString.h" | #include "llvm/ADT/SmallString.h" | |||
#include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include "llvm/Support/system_error.h" | #include "llvm/Support/system_error.h" | |||
#include <ctime> | #include <ctime> | |||
#include <iterator> | #include <iterator> | |||
skipping to change at line 602 | skipping to change at line 602 | |||
/// Platform specific mapping state. | /// Platform specific mapping state. | |||
mapmode Mode; | mapmode Mode; | |||
uint64_t Size; | uint64_t Size; | |||
void *Mapping; | void *Mapping; | |||
#ifdef LLVM_ON_WIN32 | #ifdef LLVM_ON_WIN32 | |||
int FileDescriptor; | int FileDescriptor; | |||
void *FileHandle; | void *FileHandle; | |||
void *FileMappingHandle; | void *FileMappingHandle; | |||
#endif | #endif | |||
error_code init(int FD, uint64_t Offset); | error_code init(int FD, bool CloseFD, uint64_t Offset); | |||
public: | public: | |||
typedef char char_type; | typedef char char_type; | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
mapped_file_region(mapped_file_region&&); | mapped_file_region(mapped_file_region&&); | |||
mapped_file_region &operator =(mapped_file_region&&); | mapped_file_region &operator =(mapped_file_region&&); | |||
#endif | #endif | |||
/// Construct a mapped_file_region at \a path starting at \a offset of le ngth | /// Construct a mapped_file_region at \a path starting at \a offset of le ngth | |||
/// \a length and with access \a mode. | /// \a length and with access \a mode. | |||
/// | /// | |||
/// \param path Path to the file to map. If it does not exist it will be | /// \param path Path to the file to map. If it does not exist it will be | |||
/// created. | /// created. | |||
/// \param mode How to map the memory. | /// \param mode How to map the memory. | |||
skipping to change at line 633 | skipping to change at line 633 | |||
/// mapped_file_region::alignment(). | /// mapped_file_region::alignment(). | |||
/// \param ec This is set to errc::success if the map was constructed | /// \param ec This is set to errc::success if the map was constructed | |||
/// sucessfully. Otherwise it is set to a platform dependent er ror. | /// sucessfully. Otherwise it is set to a platform dependent er ror. | |||
mapped_file_region(const Twine &path, | mapped_file_region(const Twine &path, | |||
mapmode mode, | mapmode mode, | |||
uint64_t length, | uint64_t length, | |||
uint64_t offset, | uint64_t offset, | |||
error_code &ec); | error_code &ec); | |||
/// \param fd An open file descriptor to map. mapped_file_region takes | /// \param fd An open file descriptor to map. mapped_file_region takes | |||
/// ownership. It must have been opended in the correct mode. | /// ownership if closefd is true. It must have been opended in the corr | |||
ect | ||||
/// mode. | ||||
mapped_file_region(int fd, | mapped_file_region(int fd, | |||
bool closefd, | ||||
mapmode mode, | mapmode mode, | |||
uint64_t length, | uint64_t length, | |||
uint64_t offset, | uint64_t offset, | |||
error_code &ec); | error_code &ec); | |||
~mapped_file_region(); | ~mapped_file_region(); | |||
mapmode flags() const; | mapmode flags() const; | |||
uint64_t size() const; | uint64_t size() const; | |||
char *data() const; | char *data() const; | |||
End of changes. 5 change blocks. | ||||
5 lines changed or deleted | 8 lines changed or added | |||
FoldingSet.h | FoldingSet.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file defines a hash set that can be used to remove duplication of n odes | // This file defines a hash set that can be used to remove duplication of n odes | |||
// in a graph. This code was originally created by Chris Lattner for use w ith | // in a graph. This code was originally created by Chris Lattner for use w ith | |||
// SelectionDAGCSEMap, but was isolated to provide use across the llvm code set. | // SelectionDAGCSEMap, but was isolated to provide use across the llvm code set. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_FOLDINGSET_H | #ifndef LLVM_ADT_FOLDINGSET_H | |||
#define LLVM_ADT_FOLDINGSET_H | #define LLVM_ADT_FOLDINGSET_H | |||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/DataTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
class APFloat; | class APFloat; | |||
class APInt; | class APInt; | |||
class BumpPtrAllocator; | class BumpPtrAllocator; | |||
/// This folding set used for two purposes: | /// This folding set used for two purposes: | |||
/// 1. Given information about a node we want to create, look up the uniq ue | /// 1. Given information about a node we want to create, look up the uniq ue | |||
/// instance of the node in the set. If the node already exists, retu rn | /// instance of the node in the set. If the node already exists, retu rn | |||
/// it, otherwise return the bucket it should be inserted into. | /// it, otherwise return the bucket it should be inserted into. | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
FormattedStream.h | FormattedStream.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file contains raw_ostream implementations for streams to do | // This file contains raw_ostream implementations for streams to do | |||
// things like pretty-print comments. | // things like pretty-print comments. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H | #ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H | |||
#define LLVM_SUPPORT_FORMATTEDSTREAM_H | #define LLVM_SUPPORT_FORMATTEDSTREAM_H | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
namespace llvm | namespace llvm { | |||
{ | ||||
/// formatted_raw_ostream - Formatted raw_fd_ostream to handle | /// formatted_raw_ostream - A raw_ostream that wraps another one and keeps | |||
/// asm-specific constructs. | track | |||
/// | /// of column position, allowing padding out to specific column boundaries. | |||
class formatted_raw_ostream : public raw_ostream { | /// | |||
public: | class formatted_raw_ostream : public raw_ostream { | |||
/// DELETE_STREAM - Tell the destructor to delete the held stream. | public: | |||
/// | /// DELETE_STREAM - Tell the destructor to delete the held stream. | |||
static const bool DELETE_STREAM = true; | /// | |||
static const bool DELETE_STREAM = true; | ||||
/// PRESERVE_STREAM - Tell the destructor to not delete the held | ||||
/// stream. | ||||
/// | ||||
static const bool PRESERVE_STREAM = false; | ||||
private: | ||||
/// TheStream - The real stream we output to. We set it to be | ||||
/// unbuffered, since we're already doing our own buffering. | ||||
/// | ||||
raw_ostream *TheStream; | ||||
/// DeleteStream - Do we need to delete TheStream in the | ||||
/// destructor? | ||||
/// | ||||
bool DeleteStream; | ||||
/// ColumnScanned - The current output column of the data that's | ||||
/// been flushed and the portion of the buffer that's been | ||||
/// scanned. The column scheme is zero-based. | ||||
/// | ||||
unsigned ColumnScanned; | ||||
/// Scanned - This points to one past the last character in the | ||||
/// buffer we've scanned. | ||||
/// | ||||
const char *Scanned; | ||||
virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; | ||||
/// current_pos - Return the current position within the stream, | ||||
/// not counting the bytes currently in the buffer. | ||||
virtual uint64_t current_pos() const LLVM_OVERRIDE { | ||||
// Our current position in the stream is all the contents which have | ||||
been | ||||
// written to the underlying stream (*not* the current position of th | ||||
e | ||||
// underlying stream). | ||||
return TheStream->tell(); | ||||
} | ||||
/// ComputeColumn - Examine the given output buffer and figure out whic | ||||
h | ||||
/// column we end up in after output. | ||||
/// | ||||
void ComputeColumn(const char *Ptr, size_t size); | ||||
public: | ||||
/// formatted_raw_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. | ||||
/// | ||||
/// As a side effect, the given Stream is set to be Unbuffered. | ||||
/// This is because formatted_raw_ostream does its own buffering, | ||||
/// so it doesn't want another layer of buffering to be happening | ||||
/// underneath it. | ||||
/// | ||||
formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) | ||||
: raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) | ||||
{ | ||||
setStream(Stream, Delete); | ||||
} | ||||
explicit formatted_raw_ostream() | ||||
: raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) | ||||
{ | ||||
Scanned = 0; | ||||
} | ||||
~formatted_raw_ostream() { | ||||
flush(); | ||||
releaseStream(); | ||||
} | ||||
void setStream(raw_ostream &Stream, bool Delete = false) { | ||||
releaseStream(); | ||||
TheStream = &Stream; | ||||
DeleteStream = Delete; | ||||
// This formatted_raw_ostream inherits from raw_ostream, so it'll do | ||||
its | ||||
// own buffering, and it doesn't need or want TheStream to do another | ||||
// layer of buffering underneath. Resize the buffer to what TheStream | ||||
// had been using, and tell TheStream not to do its own buffering. | ||||
if (size_t BufferSize = TheStream->GetBufferSize()) | ||||
SetBufferSize(BufferSize); | ||||
else | ||||
SetUnbuffered(); | ||||
TheStream->SetUnbuffered(); | ||||
Scanned = 0; | /// PRESERVE_STREAM - Tell the destructor to not delete the held | |||
} | /// stream. | |||
/// | ||||
static const bool PRESERVE_STREAM = false; | ||||
private: | ||||
/// TheStream - The real stream we output to. We set it to be | ||||
/// unbuffered, since we're already doing our own buffering. | ||||
/// | ||||
raw_ostream *TheStream; | ||||
/// PadToColumn - Align the output to some column number. If the curre | /// DeleteStream - Do we need to delete TheStream in the | |||
nt | /// destructor? | |||
/// column is already equal to or more than NewCol, PadToColumn inserts | /// | |||
one | bool DeleteStream; | |||
/// space. | ||||
/// | /// ColumnScanned - The current output column of the data that's | |||
/// \param NewCol - The column to move to. | /// been flushed and the portion of the buffer that's been | |||
formatted_raw_ostream &PadToColumn(unsigned NewCol); | /// scanned. The column scheme is zero-based. | |||
/// | ||||
private: | unsigned ColumnScanned; | |||
void releaseStream() { | ||||
// Delete the stream if needed. Otherwise, transfer the buffer | /// Scanned - This points to one past the last character in the | |||
// settings from this raw_ostream back to the underlying stream. | /// buffer we've scanned. | |||
if (!TheStream) | /// | |||
return; | const char *Scanned; | |||
if (DeleteStream) | ||||
delete TheStream; | virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; | |||
else if (size_t BufferSize = GetBufferSize()) | ||||
TheStream->SetBufferSize(BufferSize); | /// current_pos - Return the current position within the stream, | |||
else | /// not counting the bytes currently in the buffer. | |||
TheStream->SetUnbuffered(); | virtual uint64_t current_pos() const LLVM_OVERRIDE { | |||
} | // Our current position in the stream is all the contents which have be | |||
}; | en | |||
// written to the underlying stream (*not* the current position of the | ||||
// underlying stream). | ||||
return TheStream->tell(); | ||||
} | ||||
/// ComputeColumn - Examine the given output buffer and figure out which | ||||
/// column we end up in after output. | ||||
/// | ||||
void ComputeColumn(const char *Ptr, size_t size); | ||||
public: | ||||
/// formatted_raw_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. | ||||
/// | ||||
/// As a side effect, the given Stream is set to be Unbuffered. | ||||
/// This is because formatted_raw_ostream does its own buffering, | ||||
/// so it doesn't want another layer of buffering to be happening | ||||
/// underneath it. | ||||
/// | ||||
formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) | ||||
: raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { | ||||
setStream(Stream, Delete); | ||||
} | ||||
explicit formatted_raw_ostream() | ||||
: raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { | ||||
Scanned = 0; | ||||
} | ||||
~formatted_raw_ostream() { | ||||
flush(); | ||||
releaseStream(); | ||||
} | ||||
void setStream(raw_ostream &Stream, bool Delete = false) { | ||||
releaseStream(); | ||||
TheStream = &Stream; | ||||
DeleteStream = Delete; | ||||
// This formatted_raw_ostream inherits from raw_ostream, so it'll do it | ||||
s | ||||
// own buffering, and it doesn't need or want TheStream to do another | ||||
// layer of buffering underneath. Resize the buffer to what TheStream | ||||
// had been using, and tell TheStream not to do its own buffering. | ||||
if (size_t BufferSize = TheStream->GetBufferSize()) | ||||
SetBufferSize(BufferSize); | ||||
else | ||||
SetUnbuffered(); | ||||
TheStream->SetUnbuffered(); | ||||
Scanned = 0; | ||||
} | ||||
/// PadToColumn - Align the output to some column number. If the current | ||||
/// column is already equal to or more than NewCol, PadToColumn inserts o | ||||
ne | ||||
/// space. | ||||
/// | ||||
/// \param NewCol - The column to move to. | ||||
formatted_raw_ostream &PadToColumn(unsigned NewCol); | ||||
private: | ||||
void releaseStream() { | ||||
// Delete the stream if needed. Otherwise, transfer the buffer | ||||
// settings from this raw_ostream back to the underlying stream. | ||||
if (!TheStream) | ||||
return; | ||||
if (DeleteStream) | ||||
delete TheStream; | ||||
else if (size_t BufferSize = GetBufferSize()) | ||||
TheStream->SetBufferSize(BufferSize); | ||||
else | ||||
TheStream->SetUnbuffered(); | ||||
} | ||||
}; | ||||
/// fouts() - This returns a reference to a formatted_raw_ostream for | /// fouts() - This returns a reference to a formatted_raw_ostream for | |||
/// standard output. Use it like: fouts() << "foo" << "bar"; | /// standard output. Use it like: fouts() << "foo" << "bar"; | |||
formatted_raw_ostream &fouts(); | formatted_raw_ostream &fouts(); | |||
/// ferrs() - This returns a reference to a formatted_raw_ostream for | /// ferrs() - This returns a reference to a formatted_raw_ostream for | |||
/// standard error. Use it like: ferrs() << "foo" << "bar"; | /// standard error. Use it like: ferrs() << "foo" << "bar"; | |||
formatted_raw_ostream &ferrs(); | formatted_raw_ostream &ferrs(); | |||
/// fdbgs() - This returns a reference to a formatted_raw_ostream for | /// fdbgs() - This returns a reference to a formatted_raw_ostream for | |||
End of changes. 3 change blocks. | ||||
125 lines changed or deleted | 121 lines changed or added | |||
Function.h | Function.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the declaration of the Function class, which represen ts a | // This file contains the declaration of the Function class, which represen ts a | |||
// single function/procedure in LLVM. | // single function/procedure in LLVM. | |||
// | // | |||
// A function basically consists of a list of basic blocks, a list of argum ents, | // A function basically consists of a list of basic blocks, a list of argum ents, | |||
// and a symbol table. | // and a symbol table. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_FUNCTION_H | #ifndef LLVM_IR_FUNCTION_H | |||
#define LLVM_FUNCTION_H | #define LLVM_IR_FUNCTION_H | |||
#include "llvm/GlobalValue.h" | #include "llvm/IR/Argument.h" | |||
#include "llvm/CallingConv.h" | #include "llvm/IR/Attributes.h" | |||
#include "llvm/BasicBlock.h" | #include "llvm/IR/BasicBlock.h" | |||
#include "llvm/Argument.h" | #include "llvm/IR/CallingConv.h" | |||
#include "llvm/Attributes.h" | #include "llvm/IR/GlobalValue.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
namespace llvm { | namespace llvm { | |||
class FunctionType; | class FunctionType; | |||
class LLVMContext; | class LLVMContext; | |||
// Traits for intrusive list of basic blocks... | // Traits for intrusive list of basic blocks... | |||
template<> struct ilist_traits<BasicBlock> | template<> struct ilist_traits<BasicBlock> | |||
: public SymbolTableListTraits<BasicBlock, Function> { | : public SymbolTableListTraits<BasicBlock, Function> { | |||
skipping to change at line 88 | skipping to change at line 88 | |||
typedef BasicBlockListType::const_iterator const_iterator; | typedef BasicBlockListType::const_iterator const_iterator; | |||
typedef ArgumentListType::iterator arg_iterator; | typedef ArgumentListType::iterator arg_iterator; | |||
typedef ArgumentListType::const_iterator const_arg_iterator; | typedef ArgumentListType::const_iterator const_arg_iterator; | |||
private: | private: | |||
// Important things that make up a function! | // Important things that make up a function! | |||
BasicBlockListType BasicBlocks; ///< The basic blocks | BasicBlockListType BasicBlocks; ///< The basic blocks | |||
mutable ArgumentListType ArgumentList; ///< The formal arguments | mutable ArgumentListType ArgumentList; ///< The formal arguments | |||
ValueSymbolTable *SymTab; ///< Symbol table of args/instruc tions | ValueSymbolTable *SymTab; ///< Symbol table of args/instruc tions | |||
AttrListPtr AttributeList; ///< Parameter attributes | AttributeSet AttributeSets; ///< Parameter attributes | |||
// HasLazyArguments is stored in Value::SubclassData. | // HasLazyArguments is stored in Value::SubclassData. | |||
/*bool HasLazyArguments;*/ | /*bool HasLazyArguments;*/ | |||
// The Calling Convention is stored in Value::SubclassData. | // The Calling Convention is stored in Value::SubclassData. | |||
/*CallingConv::ID CallingConvention;*/ | /*CallingConv::ID CallingConvention;*/ | |||
friend class SymbolTableListTraits<Function, Module>; | friend class SymbolTableListTraits<Function, Module>; | |||
void setParent(Module *parent); | void setParent(Module *parent); | |||
skipping to change at line 116 | skipping to change at line 116 | |||
} | } | |||
void CheckLazyArguments() const { | void CheckLazyArguments() const { | |||
if (hasLazyArguments()) | if (hasLazyArguments()) | |||
BuildLazyArguments(); | BuildLazyArguments(); | |||
} | } | |||
void BuildLazyArguments() const; | void BuildLazyArguments() const; | |||
Function(const Function&) LLVM_DELETED_FUNCTION; | Function(const Function&) LLVM_DELETED_FUNCTION; | |||
void operator=(const Function&) LLVM_DELETED_FUNCTION; | void operator=(const Function&) LLVM_DELETED_FUNCTION; | |||
/// Do the actual lookup of an intrinsic ID when the query could not be | ||||
/// answered from the cache. | ||||
unsigned lookupIntrinsicID() const LLVM_READONLY; | ||||
/// Function ctor - If the (optional) Module argument is specified, the | /// Function ctor - If the (optional) Module argument is specified, the | |||
/// function is automatically inserted into the end of the function list for | /// function is automatically inserted into the end of the function list for | |||
/// the module. | /// the module. | |||
/// | /// | |||
Function(FunctionType *Ty, LinkageTypes Linkage, | Function(FunctionType *Ty, LinkageTypes Linkage, | |||
const Twine &N = "", Module *M = 0); | const Twine &N = "", Module *M = 0); | |||
public: | public: | |||
static Function *Create(FunctionType *Ty, LinkageTypes Linkage, | static Function *Create(FunctionType *Ty, LinkageTypes Linkage, | |||
const Twine &N = "", Module *M = 0) { | const Twine &N = "", Module *M = 0) { | |||
skipping to change at line 144 | skipping to change at line 148 | |||
/// getContext - Return a pointer to the LLVMContext associated with this | /// getContext - Return a pointer to the LLVMContext associated with this | |||
/// function, or NULL if this function is not bound to a context yet. | /// function, or NULL if this function is not bound to a context yet. | |||
LLVMContext &getContext() const; | LLVMContext &getContext() const; | |||
/// isVarArg - Return true if this function takes a variable number of | /// isVarArg - Return true if this function takes a variable number of | |||
/// arguments. | /// arguments. | |||
bool isVarArg() const; | bool isVarArg() const; | |||
/// getIntrinsicID - This method returns the ID number of the specified | /// getIntrinsicID - This method returns the ID number of the specified | |||
/// function, or Intrinsic::not_intrinsic if the function is not an | /// function, or Intrinsic::not_intrinsic if the function is not an | |||
/// instrinsic, or if the pointer is null. This value is always defined to be | /// intrinsic, or if the pointer is null. This value is always defined t o be | |||
/// zero to allow easy checking for whether a function is intrinsic or no t. | /// zero to allow easy checking for whether a function is intrinsic or no t. | |||
/// The particular intrinsic functions which correspond to this value are | /// The particular intrinsic functions which correspond to this value are | |||
/// defined in llvm/Intrinsics.h. | /// defined in llvm/Intrinsics.h. Results are cached in the LLVM context | |||
, | ||||
/// subsequent requests for the same ID return results much faster from t | ||||
he | ||||
/// cache. | ||||
/// | /// | |||
unsigned getIntrinsicID() const LLVM_READONLY; | unsigned getIntrinsicID() const LLVM_READONLY; | |||
bool isIntrinsic() const { return getIntrinsicID() != 0; } | bool isIntrinsic() const { return getName().startswith("llvm."); } | |||
/// getCallingConv()/setCallingConv(CC) - These method get and set the | /// getCallingConv()/setCallingConv(CC) - These method get and set the | |||
/// calling convention of this function. The enum values for the known | /// calling convention of this function. The enum values for the known | |||
/// calling conventions are defined in CallingConv.h. | /// calling conventions are defined in CallingConv.h. | |||
CallingConv::ID getCallingConv() const { | CallingConv::ID getCallingConv() const { | |||
return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 1); | return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 1); | |||
} | } | |||
void setCallingConv(CallingConv::ID CC) { | void setCallingConv(CallingConv::ID CC) { | |||
setValueSubclassData((getSubclassDataFromValue() & 1) | | setValueSubclassData((getSubclassDataFromValue() & 1) | | |||
(static_cast<unsigned>(CC) << 1)); | (static_cast<unsigned>(CC) << 1)); | |||
} | } | |||
/// getAttributes - Return the attribute list for this Function. | /// getAttributes - Return the attribute list for this Function. | |||
/// | /// | |||
const AttrListPtr &getAttributes() const { return AttributeList; } | AttributeSet getAttributes() const { return AttributeSets; } | |||
/// setAttributes - Set the attribute list for this Function. | /// setAttributes - Set the attribute list for this Function. | |||
/// | /// | |||
void setAttributes(const AttrListPtr &attrs) { AttributeList = attrs; } | void setAttributes(AttributeSet attrs) { AttributeSets = attrs; } | |||
/// getFnAttributes - Return the function attributes for querying. | /// addFnAttr - Add function attributes to this function. | |||
/// | /// | |||
Attributes getFnAttributes() const { | void addFnAttr(Attribute::AttrKind N) { | |||
return AttributeList.getFnAttributes(); | setAttributes(AttributeSets.addAttribute(getContext(), | |||
AttributeSet::FunctionIndex, N | ||||
)); | ||||
} | } | |||
/// addFnAttr - Add function attributes to this function. | /// addFnAttr - Add function attributes to this function. | |||
/// | /// | |||
void addFnAttr(Attributes::AttrVal N) { | void addFnAttr(StringRef Kind) { | |||
// Function Attributes are stored at ~0 index | setAttributes( | |||
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), | AttributeSets.addAttribute(getContext(), | |||
N)); | AttributeSet::FunctionIndex, Kind)); | |||
} | } | |||
/// removeFnAttr - Remove function attributes from this function. | /// \brief Return true if the function has the attribute. | |||
/// | bool hasFnAttribute(Attribute::AttrKind Kind) const { | |||
void removeFnAttr(Attributes N) { | return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind); | |||
// Function Attributes are stored at ~0 index | } | |||
removeAttribute(~0U, N); | bool hasFnAttribute(StringRef Kind) const { | |||
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind); | ||||
} | } | |||
/// hasGC/getGC/setGC/clearGC - The name of the garbage collection algori thm | /// hasGC/getGC/setGC/clearGC - The name of the garbage collection algori thm | |||
/// to use during code generation. | /// to use during code generation. | |||
bool hasGC() const; | bool hasGC() const; | |||
const char *getGC() const; | const char *getGC() const; | |||
void setGC(const char *Str); | void setGC(const char *Str); | |||
void clearGC(); | void clearGC(); | |||
/// getRetAttributes - Return the return attributes for querying. | /// @brief adds the attribute to the list of attributes. | |||
Attributes getRetAttributes() const { | void addAttribute(unsigned i, Attribute::AttrKind attr); | |||
return AttributeList.getRetAttributes(); | ||||
} | ||||
/// getParamAttributes - Return the parameter attributes for querying. | ||||
Attributes getParamAttributes(unsigned Idx) const { | ||||
return AttributeList.getParamAttributes(Idx); | ||||
} | ||||
/// addAttribute - adds the attribute to the list of attributes. | /// @brief adds the attributes to the list of attributes. | |||
void addAttribute(unsigned i, Attributes attr); | void addAttributes(unsigned i, AttributeSet attrs); | |||
/// removeAttribute - removes the attribute from the list of attributes. | /// @brief removes the attributes from the list of attributes. | |||
void removeAttribute(unsigned i, Attributes attr); | void removeAttributes(unsigned i, AttributeSet attr); | |||
/// @brief Extract the alignment for a call or parameter (0=unknown). | /// @brief Extract the alignment for a call or parameter (0=unknown). | |||
unsigned getParamAlignment(unsigned i) const { | unsigned getParamAlignment(unsigned i) const { | |||
return AttributeList.getParamAlignment(i); | return AttributeSets.getParamAlignment(i); | |||
} | } | |||
/// @brief Determine if the function does not access memory. | /// @brief Determine if the function does not access memory. | |||
bool doesNotAccessMemory() const { | bool doesNotAccessMemory() const { | |||
return getFnAttributes().hasAttribute(Attributes::ReadNone); | return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, | |||
Attribute::ReadNone); | ||||
} | } | |||
void setDoesNotAccessMemory() { | void setDoesNotAccessMemory() { | |||
addFnAttr(Attributes::ReadNone); | addFnAttr(Attribute::ReadNone); | |||
} | } | |||
/// @brief Determine if the function does not access or only reads memory . | /// @brief Determine if the function does not access or only reads memory . | |||
bool onlyReadsMemory() const { | bool onlyReadsMemory() const { | |||
return doesNotAccessMemory() || | return doesNotAccessMemory() || | |||
getFnAttributes().hasAttribute(Attributes::ReadOnly); | AttributeSets.hasAttribute(AttributeSet::FunctionIndex, | |||
Attribute::ReadOnly); | ||||
} | } | |||
void setOnlyReadsMemory() { | void setOnlyReadsMemory() { | |||
addFnAttr(Attributes::ReadOnly); | addFnAttr(Attribute::ReadOnly); | |||
} | } | |||
/// @brief Determine if the function cannot return. | /// @brief Determine if the function cannot return. | |||
bool doesNotReturn() const { | bool doesNotReturn() const { | |||
return getFnAttributes().hasAttribute(Attributes::NoReturn); | return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, | |||
Attribute::NoReturn); | ||||
} | } | |||
void setDoesNotReturn() { | void setDoesNotReturn() { | |||
addFnAttr(Attributes::NoReturn); | addFnAttr(Attribute::NoReturn); | |||
} | } | |||
/// @brief Determine if the function cannot unwind. | /// @brief Determine if the function cannot unwind. | |||
bool doesNotThrow() const { | bool doesNotThrow() const { | |||
return getFnAttributes().hasAttribute(Attributes::NoUnwind); | return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, | |||
Attribute::NoUnwind); | ||||
} | } | |||
void setDoesNotThrow() { | void setDoesNotThrow() { | |||
addFnAttr(Attributes::NoUnwind); | addFnAttr(Attribute::NoUnwind); | |||
} | ||||
/// @brief Determine if the call cannot be duplicated. | ||||
bool cannotDuplicate() const { | ||||
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, | ||||
Attribute::NoDuplicate); | ||||
} | ||||
void setCannotDuplicate() { | ||||
addFnAttr(Attribute::NoDuplicate); | ||||
} | } | |||
/// @brief True if the ABI mandates (or the user requested) that this | /// @brief True if the ABI mandates (or the user requested) that this | |||
/// function be in a unwind table. | /// function be in a unwind table. | |||
bool hasUWTable() const { | bool hasUWTable() const { | |||
return getFnAttributes().hasAttribute(Attributes::UWTable); | return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, | |||
Attribute::UWTable); | ||||
} | } | |||
void setHasUWTable() { | void setHasUWTable() { | |||
addFnAttr(Attributes::UWTable); | addFnAttr(Attribute::UWTable); | |||
} | } | |||
/// @brief True if this function needs an unwind table. | /// @brief True if this function needs an unwind table. | |||
bool needsUnwindTableEntry() const { | bool needsUnwindTableEntry() const { | |||
return hasUWTable() || !doesNotThrow(); | return hasUWTable() || !doesNotThrow(); | |||
} | } | |||
/// @brief Determine if the function returns a structure through first | /// @brief Determine if the function returns a structure through first | |||
/// pointer argument. | /// pointer argument. | |||
bool hasStructRetAttr() const { | bool hasStructRetAttr() const { | |||
return getParamAttributes(1).hasAttribute(Attributes::StructRet); | return AttributeSets.hasAttribute(1, Attribute::StructRet); | |||
} | } | |||
/// @brief Determine if the parameter does not alias other parameters. | /// @brief Determine if the parameter does not alias other parameters. | |||
/// @param n The parameter to check. 1 is the first parameter, 0 is the r eturn | /// @param n The parameter to check. 1 is the first parameter, 0 is the r eturn | |||
bool doesNotAlias(unsigned n) const { | bool doesNotAlias(unsigned n) const { | |||
return getParamAttributes(n).hasAttribute(Attributes::NoAlias); | return AttributeSets.hasAttribute(n, Attribute::NoAlias); | |||
} | } | |||
void setDoesNotAlias(unsigned n) { | void setDoesNotAlias(unsigned n) { | |||
addAttribute(n, Attributes::get(getContext(), Attributes::NoAlias)); | addAttribute(n, Attribute::NoAlias); | |||
} | } | |||
/// @brief Determine if the parameter can be captured. | /// @brief Determine if the parameter can be captured. | |||
/// @param n The parameter to check. 1 is the first parameter, 0 is the r eturn | /// @param n The parameter to check. 1 is the first parameter, 0 is the r eturn | |||
bool doesNotCapture(unsigned n) const { | bool doesNotCapture(unsigned n) const { | |||
return getParamAttributes(n).hasAttribute(Attributes::NoCapture); | return AttributeSets.hasAttribute(n, Attribute::NoCapture); | |||
} | } | |||
void setDoesNotCapture(unsigned n) { | void setDoesNotCapture(unsigned n) { | |||
addAttribute(n, Attributes::get(getContext(), Attributes::NoCapture)); | addAttribute(n, Attribute::NoCapture); | |||
} | } | |||
/// copyAttributesFrom - copy all additional attributes (those not needed to | /// copyAttributesFrom - copy all additional attributes (those not needed to | |||
/// create a Function) from the Function Src to this one. | /// create a Function) from the Function Src to this one. | |||
void copyAttributesFrom(const GlobalValue *Src); | void copyAttributesFrom(const GlobalValue *Src); | |||
/// deleteBody - This method deletes the body of the function, and conver ts | /// deleteBody - This method deletes the body of the function, and conver ts | |||
/// the linkage to external. | /// the linkage to external. | |||
/// | /// | |||
void deleteBody() { | void deleteBody() { | |||
End of changes. 32 change blocks. | ||||
54 lines changed or deleted | 72 lines changed or added | |||
FunctionLoweringInfo.h | FunctionLoweringInfo.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This implements routines for translating functions from LLVM IR into | // This implements routines for translating functions from LLVM IR into | |||
// Machine IR. | // Machine IR. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H | #ifndef LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H | |||
#define LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H | #define LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H | |||
#include "llvm/InlineAsm.h" | ||||
#include "llvm/Instructions.h" | ||||
#include "llvm/ADT/APInt.h" | #include "llvm/ADT/APInt.h" | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/DenseSet.h" | ||||
#include "llvm/ADT/IndexedMap.h" | #include "llvm/ADT/IndexedMap.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/Analysis/BranchProbabilityInfo.h" | ||||
#include "llvm/CodeGen/ValueTypes.h" | ||||
#include "llvm/CodeGen/ISDOpcodes.h" | ||||
#include "llvm/CodeGen/MachineBasicBlock.h" | #include "llvm/CodeGen/MachineBasicBlock.h" | |||
#include "llvm/Support/CallSite.h" | #include "llvm/CodeGen/ValueTypes.h" | |||
#include "llvm/IR/InlineAsm.h" | ||||
#include "llvm/IR/Instructions.h" | ||||
#include "llvm/Target/TargetRegisterInfo.h" | #include "llvm/Target/TargetRegisterInfo.h" | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class AllocaInst; | class AllocaInst; | |||
class BasicBlock; | class BasicBlock; | |||
class BranchProbabilityInfo; | ||||
class CallInst; | class CallInst; | |||
class Function; | class Function; | |||
class GlobalVariable; | class GlobalVariable; | |||
class Instruction; | class Instruction; | |||
class MachineInstr; | class MachineInstr; | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
class MachineFunction; | class MachineFunction; | |||
class MachineModuleInfo; | class MachineModuleInfo; | |||
class MachineRegisterInfo; | class MachineRegisterInfo; | |||
class TargetLowering; | class TargetLowering; | |||
skipping to change at line 139 | skipping to change at line 136 | |||
/// FunctionLoweringInfo to an empty state, ready to be used for a | /// FunctionLoweringInfo to an empty state, ready to be used for a | |||
/// different function. | /// different function. | |||
void clear(); | void clear(); | |||
/// isExportedInst - Return true if the specified value is an instruction | /// isExportedInst - Return true if the specified value is an instruction | |||
/// exported from its block. | /// exported from its block. | |||
bool isExportedInst(const Value *V) { | bool isExportedInst(const Value *V) { | |||
return ValueMap.count(V); | return ValueMap.count(V); | |||
} | } | |||
unsigned CreateReg(EVT VT); | unsigned CreateReg(MVT VT); | |||
unsigned CreateRegs(Type *Ty); | unsigned CreateRegs(Type *Ty); | |||
unsigned InitializeRegForValue(const Value *V) { | unsigned InitializeRegForValue(const Value *V) { | |||
unsigned &R = ValueMap[V]; | unsigned &R = ValueMap[V]; | |||
assert(R == 0 && "Already initialized this value register!"); | assert(R == 0 && "Already initialized this value register!"); | |||
return R = CreateRegs(V->getType()); | return R = CreateRegs(V->getType()); | |||
} | } | |||
/// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL i f the | /// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL i f the | |||
End of changes. 6 change blocks. | ||||
8 lines changed or deleted | 5 lines changed or added | |||
GCMetadata.h | GCMetadata.h | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
// they are compiled. This accretion is necessary for collectors which must emit | // they are compiled. This accretion is necessary for collectors which must emit | |||
// a stack map for the compilation unit as a whole. Therefore, GCFunctionIn fo | // a stack map for the compilation unit as a whole. Therefore, GCFunctionIn fo | |||
// outlives the MachineFunction from which it is derived and must not refer to | // outlives the MachineFunction from which it is derived and must not refer to | |||
// any code generator data structures. | // any code generator data structures. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_GCMETADATA_H | #ifndef LLVM_CODEGEN_GCMETADATA_H | |||
#define LLVM_CODEGEN_GCMETADATA_H | #define LLVM_CODEGEN_GCMETADATA_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/StringMap.h" | #include "llvm/ADT/StringMap.h" | |||
#include "llvm/Pass.h" | ||||
#include "llvm/Support/DebugLoc.h" | #include "llvm/Support/DebugLoc.h" | |||
namespace llvm { | namespace llvm { | |||
class AsmPrinter; | class AsmPrinter; | |||
class GCStrategy; | class GCStrategy; | |||
class Constant; | class Constant; | |||
class MCSymbol; | class MCSymbol; | |||
namespace GC { | namespace GC { | |||
/// PointKind - The type of a collector-safe point. | /// PointKind - The type of a collector-safe point. | |||
skipping to change at line 181 | skipping to change at line 181 | |||
GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Nam e); | GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Nam e); | |||
public: | public: | |||
typedef list_type::const_iterator iterator; | typedef list_type::const_iterator iterator; | |||
static char ID; | static char ID; | |||
GCModuleInfo(); | GCModuleInfo(); | |||
~GCModuleInfo(); | ~GCModuleInfo(); | |||
/// clear - Resets the pass. The metadata deleter pass calls this. | /// clear - Resets the pass. Any pass, which uses GCModuleInfo, should | |||
/// call it in doFinalization(). | ||||
/// | /// | |||
void clear(); | void clear(); | |||
/// begin/end - Iterators for used strategies. | /// begin/end - Iterators for used strategies. | |||
/// | /// | |||
iterator begin() const { return StrategyList.begin(); } | iterator begin() const { return StrategyList.begin(); } | |||
iterator end() const { return StrategyList.end(); } | iterator end() const { return StrategyList.end(); } | |||
/// get - Look up function metadata. | /// get - Look up function metadata. | |||
/// | /// | |||
End of changes. 3 change blocks. | ||||
2 lines changed or deleted | 3 lines changed or added | |||
GCOV.h | GCOV.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This header provides the interface to read and write coverage files that | // This header provides the interface to read and write coverage files that | |||
// use 'gcov' format. | // use 'gcov' format. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_GCOV_H | #ifndef LLVM_SUPPORT_GCOV_H | |||
#define LLVM_GCOV_H | #define LLVM_SUPPORT_GCOV_H | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/StringMap.h" | #include "llvm/ADT/StringMap.h" | |||
#include "llvm/Support/MemoryBuffer.h" | #include "llvm/Support/MemoryBuffer.h" | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
namespace llvm { | namespace llvm { | |||
class GCOVFunction; | class GCOVFunction; | |||
class GCOVBlock; | class GCOVBlock; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
GCs.h | GCs.h | |||
---|---|---|---|---|
skipping to change at line 30 | skipping to change at line 30 | |||
/// FIXME: Collector instances are not useful on their own. These no long er | /// FIXME: Collector instances are not useful on their own. These no long er | |||
/// serve any purpose except to link in the plugins. | /// serve any purpose except to link in the plugins. | |||
/// Creates an ocaml-compatible garbage collector. | /// Creates an ocaml-compatible garbage collector. | |||
void linkOcamlGC(); | void linkOcamlGC(); | |||
/// Creates an ocaml-compatible metadata printer. | /// Creates an ocaml-compatible metadata printer. | |||
void linkOcamlGCPrinter(); | void linkOcamlGCPrinter(); | |||
/// Creates an erlang-compatible garbage collector. | ||||
void linkErlangGC(); | ||||
/// Creates an erlang-compatible metadata printer. | ||||
void linkErlangGCPrinter(); | ||||
/// Creates a shadow stack garbage collector. This collector requires no code | /// Creates a shadow stack garbage collector. This collector requires no code | |||
/// generator support. | /// generator support. | |||
void linkShadowStackGC(); | void linkShadowStackGC(); | |||
} | } | |||
#endif | #endif | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 6 lines changed or added | |||
GVMaterializer.h | GVMaterializer.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file provides an abstract interface for loading a module from some | // This file provides an abstract interface for loading a module from some | |||
// place. This interface allows incremental or random access loading of | // place. This interface allows incremental or random access loading of | |||
// functions from the file. This is useful for applications like JIT compi lers | // functions from the file. This is useful for applications like JIT compi lers | |||
// or interprocedural optimizers that do not need the entire program in mem ory | // or interprocedural optimizers that do not need the entire program in mem ory | |||
// at the same time. | // at the same time. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef GVMATERIALIZER_H | #ifndef LLVM_GVMATERIALIZER_H | |||
#define GVMATERIALIZER_H | #define LLVM_GVMATERIALIZER_H | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class Function; | class Function; | |||
class GlobalValue; | class GlobalValue; | |||
class Module; | class Module; | |||
class GVMaterializer { | class GVMaterializer { | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
GenericValue.h | GenericValue.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// The GenericValue class is used to represent an LLVM value of arbitrary t ype. | // The GenericValue class is used to represent an LLVM value of arbitrary t ype. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef GENERIC_VALUE_H | #ifndef LLVM_EXECUTIONENGINE_GENERICVALUE_H | |||
#define GENERIC_VALUE_H | #define LLVM_EXECUTIONENGINE_GENERICVALUE_H | |||
#include "llvm/ADT/APInt.h" | #include "llvm/ADT/APInt.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
typedef void* PointerTy; | typedef void* PointerTy; | |||
class APInt; | class APInt; | |||
struct GenericValue { | struct GenericValue { | |||
struct IntPair { | ||||
unsigned int first; | ||||
unsigned int second; | ||||
}; | ||||
union { | union { | |||
double DoubleVal; | double DoubleVal; | |||
float FloatVal; | float FloatVal; | |||
PointerTy PointerVal; | PointerTy PointerVal; | |||
struct { unsigned int first; unsigned int second; } UIntPairVal; | struct IntPair UIntPairVal; | |||
unsigned char Untyped[8]; | unsigned char Untyped[8]; | |||
}; | }; | |||
APInt IntVal; // also used for long doubles | APInt IntVal; // also used for long doubles. | |||
// For aggregate data types. | ||||
GenericValue() : DoubleVal(0.0), IntVal(1,0) {} | std::vector<GenericValue> AggregateVal; | |||
// to make code faster, set GenericValue to zero could be omitted, but it | ||||
is | ||||
// potentially can cause problems, since GenericValue to store garbage | ||||
// instead of zero. | ||||
GenericValue() : IntVal(1,0) {UIntPairVal.first = 0; UIntPairVal.second = | ||||
0;} | ||||
explicit GenericValue(void *V) : PointerVal(V), IntVal(1,0) { } | explicit GenericValue(void *V) : PointerVal(V), IntVal(1,0) { } | |||
}; | }; | |||
inline GenericValue PTOGV(void *P) { return GenericValue(P); } | inline GenericValue PTOGV(void *P) { return GenericValue(P); } | |||
inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; } | inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; } | |||
} // End llvm namespace | } // End llvm namespace. | |||
#endif | #endif | |||
End of changes. 5 change blocks. | ||||
7 lines changed or deleted | 18 lines changed or added | |||
GetElementPtrTypeIterator.h | GetElementPtrTypeIterator.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements an iterator for walking through the types indexed b y | // This file implements an iterator for walking through the types indexed b y | |||
// getelementptr instructions. | // getelementptr instructions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H | #ifndef LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H | |||
#define LLVM_SUPPORT_GETELEMENTPTRTYPE_H | #define LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H | |||
#include "llvm/User.h" | #include "llvm/IR/DerivedTypes.h" | |||
#include "llvm/DerivedTypes.h" | #include "llvm/IR/User.h" | |||
namespace llvm { | namespace llvm { | |||
template<typename ItTy = User::const_op_iterator> | template<typename ItTy = User::const_op_iterator> | |||
class generic_gep_type_iterator | class generic_gep_type_iterator | |||
: public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> { | : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> { | |||
typedef std::iterator<std::forward_iterator_tag, | typedef std::iterator<std::forward_iterator_tag, | |||
Type *, ptrdiff_t> super; | Type *, ptrdiff_t> super; | |||
ItTy OpIt; | ItTy OpIt; | |||
Type *CurTy; | Type *CurTy; | |||
skipping to change at line 86 | skipping to change at line 86 | |||
} | } | |||
generic_gep_type_iterator operator++(int) { // Postincrement | generic_gep_type_iterator operator++(int) { // Postincrement | |||
generic_gep_type_iterator tmp = *this; ++*this; return tmp; | generic_gep_type_iterator tmp = *this; ++*this; return tmp; | |||
} | } | |||
}; | }; | |||
typedef generic_gep_type_iterator<> gep_type_iterator; | typedef generic_gep_type_iterator<> gep_type_iterator; | |||
inline gep_type_iterator gep_type_begin(const User *GEP) { | inline gep_type_iterator gep_type_begin(const User *GEP) { | |||
return gep_type_iterator::begin(GEP->getOperand(0)->getType(), | return gep_type_iterator::begin | |||
GEP->op_begin()+1); | (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1); | |||
} | } | |||
inline gep_type_iterator gep_type_end(const User *GEP) { | inline gep_type_iterator gep_type_end(const User *GEP) { | |||
return gep_type_iterator::end(GEP->op_end()); | return gep_type_iterator::end(GEP->op_end()); | |||
} | } | |||
inline gep_type_iterator gep_type_begin(const User &GEP) { | inline gep_type_iterator gep_type_begin(const User &GEP) { | |||
return gep_type_iterator::begin(GEP.getOperand(0)->getType(), | return gep_type_iterator::begin | |||
GEP.op_begin()+1); | (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1); | |||
} | } | |||
inline gep_type_iterator gep_type_end(const User &GEP) { | inline gep_type_iterator gep_type_end(const User &GEP) { | |||
return gep_type_iterator::end(GEP.op_end()); | return gep_type_iterator::end(GEP.op_end()); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline generic_gep_type_iterator<const T *> | inline generic_gep_type_iterator<const T *> | |||
gep_type_begin(Type *Op0, ArrayRef<T> A) { | gep_type_begin(Type *Op0, ArrayRef<T> A) { | |||
return generic_gep_type_iterator<const T *>::begin(Op0, A.begin()); | return generic_gep_type_iterator<const T *>::begin(Op0, A.begin()); | |||
} | } | |||
End of changes. 4 change blocks. | ||||
8 lines changed or deleted | 8 lines changed or added | |||
GlobalAlias.h | GlobalAlias.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the declaration of the GlobalAlias class, which | // This file contains the declaration of the GlobalAlias class, which | |||
// represents a single function or variable alias in the IR. | // represents a single function or variable alias in the IR. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_GLOBAL_ALIAS_H | #ifndef LLVM_IR_GLOBALALIAS_H | |||
#define LLVM_GLOBAL_ALIAS_H | #define LLVM_IR_GLOBALALIAS_H | |||
#include "llvm/GlobalValue.h" | ||||
#include "llvm/OperandTraits.h" | ||||
#include "llvm/ADT/ilist_node.h" | ||||
#include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | |||
#include "llvm/ADT/ilist_node.h" | ||||
#include "llvm/IR/GlobalValue.h" | ||||
#include "llvm/IR/OperandTraits.h" | ||||
namespace llvm { | namespace llvm { | |||
class Module; | class Module; | |||
template<typename ValueSubClass, typename ItemParentClass> | template<typename ValueSubClass, typename ItemParentClass> | |||
class SymbolTableListTraits; | class SymbolTableListTraits; | |||
class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> { | class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> { | |||
friend class SymbolTableListTraits<GlobalAlias, Module>; | friend class SymbolTableListTraits<GlobalAlias, Module>; | |||
void operator=(const GlobalAlias &) LLVM_DELETED_FUNCTION; | void operator=(const GlobalAlias &) LLVM_DELETED_FUNCTION; | |||
End of changes. 3 change blocks. | ||||
5 lines changed or deleted | 5 lines changed or added | |||
GlobalValue.h | GlobalValue.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file is a common base class of all globally definable objects. As such, | // This file is a common base class of all globally definable objects. As such, | |||
// it is subclassed by GlobalVariable, GlobalAlias and by Function. This i s | // it is subclassed by GlobalVariable, GlobalAlias and by Function. This i s | |||
// used because you can do certain things with these global objects that yo u | // used because you can do certain things with these global objects that yo u | |||
// can't do to anything else. For example, use the address of one as a | // can't do to anything else. For example, use the address of one as a | |||
// constant. | // constant. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_GLOBALVALUE_H | #ifndef LLVM_IR_GLOBALVALUE_H | |||
#define LLVM_GLOBALVALUE_H | #define LLVM_IR_GLOBALVALUE_H | |||
#include "llvm/Constant.h" | #include "llvm/IR/Constant.h" | |||
#include "llvm/IR/DerivedTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
class PointerType; | class PointerType; | |||
class Module; | class Module; | |||
class GlobalValue : public Constant { | class GlobalValue : public Constant { | |||
GlobalValue(const GlobalValue &) LLVM_DELETED_FUNCTION; | GlobalValue(const GlobalValue &) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
/// @brief An enumeration for the kinds of linkage for global values. | /// @brief An enumeration for the kinds of linkage for global values. | |||
skipping to change at line 108 | skipping to change at line 109 | |||
/// If the usage is empty (except transitively dead constants), then this | /// If the usage is empty (except transitively dead constants), then this | |||
/// global value can be safely deleted since the destructor will | /// global value can be safely deleted since the destructor will | |||
/// delete the dead constants as well. | /// delete the dead constants as well. | |||
/// @brief Determine if the usage of this global value is empty except | /// @brief Determine if the usage of this global value is empty except | |||
/// for transitively dead constants. | /// for transitively dead constants. | |||
bool use_empty_except_constants(); | bool use_empty_except_constants(); | |||
/// getType - Global values are always pointers. | /// getType - Global values are always pointers. | |||
inline PointerType *getType() const { | inline PointerType *getType() const { | |||
return reinterpret_cast<PointerType*>(User::getType()); | return cast<PointerType>(User::getType()); | |||
} | } | |||
static LinkageTypes getLinkOnceLinkage(bool ODR) { | static LinkageTypes getLinkOnceLinkage(bool ODR) { | |||
return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage; | return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage; | |||
} | } | |||
static LinkageTypes getWeakLinkage(bool ODR) { | static LinkageTypes getWeakLinkage(bool ODR) { | |||
return ODR ? WeakODRLinkage : WeakAnyLinkage; | return ODR ? WeakODRLinkage : WeakAnyLinkage; | |||
} | } | |||
static bool isExternalLinkage(LinkageTypes Linkage) { | static bool isExternalLinkage(LinkageTypes Linkage) { | |||
End of changes. 3 change blocks. | ||||
4 lines changed or deleted | 5 lines changed or added | |||
GlobalVariable.h | GlobalVariable.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file contains the declaration of the GlobalVariable class, which | // This file contains the declaration of the GlobalVariable class, which | |||
// represents a single global variable (or constant) in the VM. | // represents a single global variable (or constant) in the VM. | |||
// | // | |||
// Global variables are constant pointers that refer to hunks of space that are | // Global variables are constant pointers that refer to hunks of space that are | |||
// allocated by either the VM, or by the linker in a static compiler. A gl obal | // allocated by either the VM, or by the linker in a static compiler. A gl obal | |||
// variable may have an initial value, which is copied into the executables .data | // variable may have an initial value, which is copied into the executables .data | |||
// area. Global Constants are required to have initializers. | // area. Global Constants are required to have initializers. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_GLOBAL_VARIABLE_H | #ifndef LLVM_IR_GLOBALVARIABLE_H | |||
#define LLVM_GLOBAL_VARIABLE_H | #define LLVM_IR_GLOBALVARIABLE_H | |||
#include "llvm/GlobalValue.h" | ||||
#include "llvm/OperandTraits.h" | ||||
#include "llvm/ADT/ilist_node.h" | ||||
#include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | |||
#include "llvm/ADT/ilist_node.h" | ||||
#include "llvm/IR/GlobalValue.h" | ||||
#include "llvm/IR/OperandTraits.h" | ||||
namespace llvm { | namespace llvm { | |||
class Module; | class Module; | |||
class Constant; | class Constant; | |||
template<typename ValueSubClass, typename ItemParentClass> | template<typename ValueSubClass, typename ItemParentClass> | |||
class SymbolTableListTraits; | class SymbolTableListTraits; | |||
class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable > { | class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable > { | |||
friend class SymbolTableListTraits<GlobalVariable, Module>; | friend class SymbolTableListTraits<GlobalVariable, Module>; | |||
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; | void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; | |||
void operator=(const GlobalVariable &) LLVM_DELETED_FUNCTION; | void operator=(const GlobalVariable &) LLVM_DELETED_FUNCTION; | |||
GlobalVariable(const GlobalVariable &) LLVM_DELETED_FUNCTION; | GlobalVariable(const GlobalVariable &) LLVM_DELETED_FUNCTION; | |||
void setParent(Module *parent); | void setParent(Module *parent); | |||
bool isConstantGlobal : 1; // Is this a global constant? | bool isConstantGlobal : 1; // Is this a global constant | |||
unsigned threadLocalMode : 3; // Is this symbol "Thread Local", | ? | |||
// if so, what is the desired model? | unsigned threadLocalMode : 3; // Is this symbol "Thread Lo | |||
cal", | ||||
// if so, what is the desire | ||||
d | ||||
// model? | ||||
bool isExternallyInitializedConstant : 1; // Is this a global whose va | ||||
lue | ||||
// can change from its initi | ||||
al | ||||
// value before global | ||||
// initializers are run? | ||||
public: | public: | |||
// allocate space for exactly one operand | // allocate space for exactly one operand | |||
void *operator new(size_t s) { | void *operator new(size_t s) { | |||
return User::operator new(s, 1); | return User::operator new(s, 1); | |||
} | } | |||
enum ThreadLocalMode { | enum ThreadLocalMode { | |||
NotThreadLocal = 0, | NotThreadLocal = 0, | |||
GeneralDynamicTLSModel, | GeneralDynamicTLSModel, | |||
LocalDynamicTLSModel, | LocalDynamicTLSModel, | |||
InitialExecTLSModel, | InitialExecTLSModel, | |||
LocalExecTLSModel | LocalExecTLSModel | |||
}; | }; | |||
/// GlobalVariable ctor - If a parent module is specified, the global is | /// GlobalVariable ctor - If a parent module is specified, the global is | |||
/// automatically inserted into the end of the specified modules global l ist. | /// automatically inserted into the end of the specified modules global l ist. | |||
GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage, | GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage, | |||
Constant *Initializer = 0, const Twine &Name = "", | Constant *Initializer = 0, const Twine &Name = "", | |||
ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = | ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = | |||
0); | 0, | |||
bool isExternallyInitialized = false); | ||||
/// GlobalVariable ctor - This creates a global and inserts it before the | /// GlobalVariable ctor - This creates a global and inserts it before the | |||
/// specified other global. | /// specified other global. | |||
GlobalVariable(Module &M, Type *Ty, bool isConstant, | GlobalVariable(Module &M, Type *Ty, bool isConstant, | |||
LinkageTypes Linkage, Constant *Initializer, | LinkageTypes Linkage, Constant *Initializer, | |||
const Twine &Name = "", | const Twine &Name = "", GlobalVariable *InsertBefore = 0, | |||
GlobalVariable *InsertBefore = 0, | ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = | |||
ThreadLocalMode = NotThreadLocal, | 0, | |||
unsigned AddressSpace = 0); | bool isExternallyInitialized = false); | |||
~GlobalVariable() { | ~GlobalVariable() { | |||
NumOperands = 1; // FIXME: needed by operator delete | NumOperands = 1; // FIXME: needed by operator delete | |||
} | } | |||
/// Provide fast operand accessors | /// Provide fast operand accessors | |||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | |||
/// hasInitializer - Unless a global variable isExternal(), it has an | /// hasInitializer - Unless a global variable isExternal(), it has an | |||
/// initializer. The initializer for the global variable/constant is hel d by | /// initializer. The initializer for the global variable/constant is hel d by | |||
skipping to change at line 108 | skipping to change at line 113 | |||
/// | /// | |||
/// @b = global weak SomeType* null - Initializer is neither definitive n or | /// @b = global weak SomeType* null - Initializer is neither definitive n or | |||
/// unique. | /// unique. | |||
/// | /// | |||
/// @c = global weak_odr SomeType* null - Initializer is definitive, but not | /// @c = global weak_odr SomeType* null - Initializer is definitive, but not | |||
/// unique. | /// unique. | |||
inline bool hasDefinitiveInitializer() const { | inline bool hasDefinitiveInitializer() const { | |||
return hasInitializer() && | return hasInitializer() && | |||
// The initializer of a global variable with weak linkage may change at | // The initializer of a global variable with weak linkage may change at | |||
// link time. | // link time. | |||
!mayBeOverridden(); | !mayBeOverridden() && | |||
// The initializer of a global variable with the externally_initializ | ||||
ed | ||||
// marker may change at runtime before C++ initializers are evaluated | ||||
. | ||||
!isExternallyInitialized(); | ||||
} | } | |||
/// hasUniqueInitializer - Whether the global variable has an initializer , and | /// hasUniqueInitializer - Whether the global variable has an initializer , and | |||
/// any changes made to the initializer will turn up in the final executa ble. | /// any changes made to the initializer will turn up in the final executa ble. | |||
inline bool hasUniqueInitializer() const { | inline bool hasUniqueInitializer() const { | |||
return hasInitializer() && | return hasInitializer() && | |||
// It's not safe to modify initializers of global variables with weak | // It's not safe to modify initializers of global variables with weak | |||
// linkage, because the linker might choose to discard the initialize r and | // linkage, because the linker might choose to discard the initialize r and | |||
// use the initializer from another instance of the global variable | // use the initializer from another instance of the global variable | |||
// instead. It is wrong to modify the initializer of a global variabl e | // instead. It is wrong to modify the initializer of a global variabl e | |||
// with *_odr linkage because then different instances of the global may | // with *_odr linkage because then different instances of the global may | |||
// have different initializers, breaking the One Definition Rule. | // have different initializers, breaking the One Definition Rule. | |||
!isWeakForLinker(); | !isWeakForLinker() && | |||
// It is not safe to modify initializers of global variables with the | ||||
// external_initializer marker since the value may be changed at runt | ||||
ime | ||||
// before C++ initializers are evaluated. | ||||
!isExternallyInitialized(); | ||||
} | } | |||
/// getInitializer - Return the initializer for this global variable. It is | /// getInitializer - Return the initializer for this global variable. It is | |||
/// illegal to call this method if the global is external, because we can not | /// illegal to call this method if the global is external, because we can not | |||
/// tell what the value is initialized to! | /// tell what the value is initialized to! | |||
/// | /// | |||
inline const Constant *getInitializer() const { | inline const Constant *getInitializer() const { | |||
assert(hasInitializer() && "GV doesn't have initializer!"); | assert(hasInitializer() && "GV doesn't have initializer!"); | |||
return static_cast<Constant*>(Op<0>().get()); | return static_cast<Constant*>(Op<0>().get()); | |||
} | } | |||
skipping to change at line 158 | skipping to change at line 170 | |||
/// If the value is "Thread Local", its value isn't shared by the threads . | /// If the value is "Thread Local", its value isn't shared by the threads . | |||
bool isThreadLocal() const { return threadLocalMode != NotThreadLocal; } | bool isThreadLocal() const { return threadLocalMode != NotThreadLocal; } | |||
void setThreadLocal(bool Val) { | void setThreadLocal(bool Val) { | |||
threadLocalMode = Val ? GeneralDynamicTLSModel : NotThreadLocal; | threadLocalMode = Val ? GeneralDynamicTLSModel : NotThreadLocal; | |||
} | } | |||
void setThreadLocalMode(ThreadLocalMode Val) { threadLocalMode = Val; } | void setThreadLocalMode(ThreadLocalMode Val) { threadLocalMode = Val; } | |||
ThreadLocalMode getThreadLocalMode() const { | ThreadLocalMode getThreadLocalMode() const { | |||
return static_cast<ThreadLocalMode>(threadLocalMode); | return static_cast<ThreadLocalMode>(threadLocalMode); | |||
} | } | |||
bool isExternallyInitialized() const { | ||||
return isExternallyInitializedConstant; | ||||
} | ||||
void setExternallyInitialized(bool Val) { | ||||
isExternallyInitializedConstant = Val; | ||||
} | ||||
/// copyAttributesFrom - copy all additional attributes (those not needed to | /// copyAttributesFrom - copy all additional attributes (those not needed to | |||
/// create a GlobalVariable) from the GlobalVariable Src to this one. | /// create a GlobalVariable) from the GlobalVariable Src to this one. | |||
void copyAttributesFrom(const GlobalValue *Src); | void copyAttributesFrom(const GlobalValue *Src); | |||
/// removeFromParent - This method unlinks 'this' from the containing mod ule, | /// removeFromParent - This method unlinks 'this' from the containing mod ule, | |||
/// but does not delete it. | /// but does not delete it. | |||
/// | /// | |||
virtual void removeFromParent(); | virtual void removeFromParent(); | |||
/// eraseFromParent - This method unlinks 'this' from the containing modu le | /// eraseFromParent - This method unlinks 'this' from the containing modu le | |||
End of changes. 9 change blocks. | ||||
16 lines changed or deleted | 44 lines changed or added | |||
Graph.h | Graph.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// PBQP Graph class. | // PBQP Graph class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_PBQP_GRAPH_H | #ifndef LLVM_CODEGEN_PBQP_GRAPH_H | |||
#define LLVM_CODEGEN_PBQP_GRAPH_H | #define LLVM_CODEGEN_PBQP_GRAPH_H | |||
#include "Math.h" | #include "Math.h" | |||
#include "llvm/ADT/ilist.h" | ||||
#include "llvm/ADT/ilist_node.h" | ||||
#include <list> | #include <list> | |||
#include <map> | #include <map> | |||
#include <llvm/ADT/ilist.h> | ||||
namespace PBQP { | namespace PBQP { | |||
/// PBQP Graph class. | /// PBQP Graph class. | |||
/// Instances of this class describe PBQP problems. | /// Instances of this class describe PBQP problems. | |||
class Graph { | class Graph { | |||
private: | private: | |||
// ----- TYPEDEFS ----- | // ----- TYPEDEFS ----- | |||
class NodeEntry; | class NodeEntry; | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
GraphWriter.h | GraphWriter.h | |||
---|---|---|---|---|
skipping to change at line 26 | skipping to change at line 26 | |||
// Graphs do not need to implement any interface past what is already requi red | // Graphs do not need to implement any interface past what is already requi red | |||
// by the GraphTraits template, but they can choose to implement specializa tions | // by the GraphTraits template, but they can choose to implement specializa tions | |||
// of the DOTGraphTraits template if they want to customize the graphs outp ut in | // of the DOTGraphTraits template if they want to customize the graphs outp ut in | |||
// any way. | // any way. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_GRAPHWRITER_H | #ifndef LLVM_SUPPORT_GRAPHWRITER_H | |||
#define LLVM_SUPPORT_GRAPHWRITER_H | #define LLVM_SUPPORT_GRAPHWRITER_H | |||
#include "llvm/Support/DOTGraphTraits.h" | ||||
#include "llvm/Support/raw_ostream.h" | ||||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/Support/DOTGraphTraits.h" | ||||
#include "llvm/Support/Path.h" | #include "llvm/Support/Path.h" | |||
#include <vector> | #include "llvm/Support/raw_ostream.h" | |||
#include <cassert> | #include <cassert> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
namespace DOT { // Private functions... | namespace DOT { // Private functions... | |||
std::string EscapeString(const std::string &Label); | std::string EscapeString(const std::string &Label); | |||
/// \brief Get a color string for this node number. Simply round-robin se | ||||
lects | ||||
/// from a reasonable number of colors. | ||||
StringRef getColorString(unsigned NodeNumber); | ||||
} | } | |||
namespace GraphProgram { | namespace GraphProgram { | |||
enum Name { | enum Name { | |||
DOT, | DOT, | |||
FDP, | FDP, | |||
NEATO, | NEATO, | |||
TWOPI, | TWOPI, | |||
CIRCO | CIRCO | |||
}; | }; | |||
skipping to change at line 176 | skipping to change at line 180 | |||
O << "\tNode" << static_cast<const void*>(Node) << " [shape=record,"; | O << "\tNode" << static_cast<const void*>(Node) << " [shape=record,"; | |||
if (!NodeAttributes.empty()) O << NodeAttributes << ","; | if (!NodeAttributes.empty()) O << NodeAttributes << ","; | |||
O << "label=\"{"; | O << "label=\"{"; | |||
if (!DTraits.renderGraphFromBottomUp()) { | if (!DTraits.renderGraphFromBottomUp()) { | |||
O << DOT::EscapeString(DTraits.getNodeLabel(Node, G)); | O << DOT::EscapeString(DTraits.getNodeLabel(Node, G)); | |||
// If we should include the address of the node in the label, do so n ow. | // If we should include the address of the node in the label, do so n ow. | |||
if (DTraits.hasNodeAddressLabel(Node, G)) | if (DTraits.hasNodeAddressLabel(Node, G)) | |||
O << "|" << static_cast<const void*>(Node); | O << "|" << static_cast<const void*>(Node); | |||
std::string NodeDesc = DTraits.getNodeDescription(Node, G); | ||||
if (!NodeDesc.empty()) | ||||
O << "|" << DOT::EscapeString(NodeDesc); | ||||
} | } | |||
std::string edgeSourceLabels; | std::string edgeSourceLabels; | |||
raw_string_ostream EdgeSourceLabels(edgeSourceLabels); | raw_string_ostream EdgeSourceLabels(edgeSourceLabels); | |||
bool hasEdgeSourceLabels = getEdgeSourceLabels(EdgeSourceLabels, Node); | bool hasEdgeSourceLabels = getEdgeSourceLabels(EdgeSourceLabels, Node); | |||
if (hasEdgeSourceLabels) { | if (hasEdgeSourceLabels) { | |||
if (!DTraits.renderGraphFromBottomUp()) O << "|"; | if (!DTraits.renderGraphFromBottomUp()) O << "|"; | |||
O << "{" << EdgeSourceLabels.str() << "}"; | O << "{" << EdgeSourceLabels.str() << "}"; | |||
if (DTraits.renderGraphFromBottomUp()) O << "|"; | if (DTraits.renderGraphFromBottomUp()) O << "|"; | |||
} | } | |||
if (DTraits.renderGraphFromBottomUp()) { | if (DTraits.renderGraphFromBottomUp()) { | |||
O << DOT::EscapeString(DTraits.getNodeLabel(Node, G)); | O << DOT::EscapeString(DTraits.getNodeLabel(Node, G)); | |||
// If we should include the address of the node in the label, do so n ow. | // If we should include the address of the node in the label, do so n ow. | |||
if (DTraits.hasNodeAddressLabel(Node, G)) | if (DTraits.hasNodeAddressLabel(Node, G)) | |||
O << "|" << static_cast<const void*>(Node); | O << "|" << static_cast<const void*>(Node); | |||
std::string NodeDesc = DTraits.getNodeDescription(Node, G); | ||||
if (!NodeDesc.empty()) | ||||
O << "|" << DOT::EscapeString(NodeDesc); | ||||
} | } | |||
if (DTraits.hasEdgeDestLabels()) { | if (DTraits.hasEdgeDestLabels()) { | |||
O << "|{"; | O << "|{"; | |||
unsigned i = 0, e = DTraits.numEdgeDestLabels(Node); | unsigned i = 0, e = DTraits.numEdgeDestLabels(Node); | |||
for (; i != e && i != 64; ++i) { | for (; i != e && i != 64; ++i) { | |||
if (i) O << "|"; | if (i) O << "|"; | |||
O << "<d" << i << ">" | O << "<d" << i << ">" | |||
<< DOT::EscapeString(DTraits.getEdgeDestLabel(Node, i)); | << DOT::EscapeString(DTraits.getEdgeDestLabel(Node, i)); | |||
End of changes. 7 change blocks. | ||||
3 lines changed or deleted | 16 lines changed or added | |||
Hashing.h | Hashing.h | |||
---|---|---|---|---|
skipping to change at line 152 | skipping to change at line 152 | |||
// All of the implementation details of actually computing the various hash | // All of the implementation details of actually computing the various hash | |||
// code values are held within this namespace. These routines are included in | // code values are held within this namespace. These routines are included in | |||
// the header file mainly to allow inlining and constant propagation. | // the header file mainly to allow inlining and constant propagation. | |||
namespace hashing { | namespace hashing { | |||
namespace detail { | namespace detail { | |||
inline uint64_t fetch64(const char *p) { | inline uint64_t fetch64(const char *p) { | |||
uint64_t result; | uint64_t result; | |||
memcpy(&result, p, sizeof(result)); | memcpy(&result, p, sizeof(result)); | |||
if (sys::isBigEndianHost()) | if (sys::IsBigEndianHost) | |||
return sys::SwapByteOrder(result); | return sys::SwapByteOrder(result); | |||
return result; | return result; | |||
} | } | |||
inline uint32_t fetch32(const char *p) { | inline uint32_t fetch32(const char *p) { | |||
uint32_t result; | uint32_t result; | |||
memcpy(&result, p, sizeof(result)); | memcpy(&result, p, sizeof(result)); | |||
if (sys::isBigEndianHost()) | if (sys::IsBigEndianHost) | |||
return sys::SwapByteOrder(result); | return sys::SwapByteOrder(result); | |||
return result; | return result; | |||
} | } | |||
/// Some primes between 2^63 and 2^64 for various uses. | /// Some primes between 2^63 and 2^64 for various uses. | |||
static const uint64_t k0 = 0xc3a5c85c97cb3127ULL; | static const uint64_t k0 = 0xc3a5c85c97cb3127ULL; | |||
static const uint64_t k1 = 0xb492b66fbe98f273ULL; | static const uint64_t k1 = 0xb492b66fbe98f273ULL; | |||
static const uint64_t k2 = 0x9ae16a3b2f90404fULL; | static const uint64_t k2 = 0x9ae16a3b2f90404fULL; | |||
static const uint64_t k3 = 0xc949d7c7509e6557ULL; | static const uint64_t k3 = 0xc949d7c7509e6557ULL; | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
HeuristicSolver.h | HeuristicSolver.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// nodes of degree 0, 1 or 2. For nodes of degree >2 a plugable heuristic i s | // nodes of degree 0, 1 or 2. For nodes of degree >2 a plugable heuristic i s | |||
// used to select a node for reduction. | // used to select a node for reduction. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H | #ifndef LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H | |||
#define LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H | #define LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H | |||
#include "Graph.h" | #include "Graph.h" | |||
#include "Solution.h" | #include "Solution.h" | |||
#include <vector> | ||||
#include <limits> | #include <limits> | |||
#include <vector> | ||||
namespace PBQP { | namespace PBQP { | |||
/// \brief Heuristic PBQP solver implementation. | /// \brief Heuristic PBQP solver implementation. | |||
/// | /// | |||
/// This class should usually be created (and destroyed) indirectly via a call | /// This class should usually be created (and destroyed) indirectly via a call | |||
/// to HeuristicSolver<HImpl>::solve(Graph&). | /// to HeuristicSolver<HImpl>::solve(Graph&). | |||
/// See the comments for HeuristicSolver. | /// See the comments for HeuristicSolver. | |||
/// | /// | |||
/// HeuristicSolverImpl provides the R0, R1 and R2 reduction rules, | /// HeuristicSolverImpl provides the R0, R1 and R2 reduction rules, | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Host.h | Host.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// Methods for querying the nature of the host machine. | // Methods for querying the nature of the host machine. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_HOST_H | #ifndef LLVM_SUPPORT_HOST_H | |||
#define LLVM_SYSTEM_HOST_H | #define LLVM_SUPPORT_HOST_H | |||
#include "llvm/ADT/StringMap.h" | #include "llvm/ADT/StringMap.h" | |||
#if defined(__linux__) | ||||
#include <endian.h> | ||||
#else | ||||
#ifndef LLVM_ON_WIN32 | ||||
#include <machine/endian.h> | ||||
#endif | ||||
#endif | ||||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
inline bool isLittleEndianHost() { | #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN | |||
union { | static const bool IsBigEndianHost = true; | |||
int i; | #else | |||
char c; | static const bool IsBigEndianHost = false; | |||
}; | #endif | |||
i = 1; | ||||
return c; | static const bool IsLittleEndianHost = !IsBigEndianHost; | |||
} | ||||
inline bool isBigEndianHost() { | ||||
return !isLittleEndianHost(); | ||||
} | ||||
/// getDefaultTargetTriple() - Return the default target triple the compi ler | /// getDefaultTargetTriple() - Return the default target triple the compi ler | |||
/// has been configured to produce code for. | /// has been configured to produce code for. | |||
/// | /// | |||
/// The target triple is a string in the format of: | /// The target triple is a string in the format of: | |||
/// CPU_TYPE-VENDOR-OPERATING_SYSTEM | /// CPU_TYPE-VENDOR-OPERATING_SYSTEM | |||
/// or | /// or | |||
/// CPU_TYPE-VENDOR-KERNEL-OPERATING_SYSTEM | /// CPU_TYPE-VENDOR-KERNEL-OPERATING_SYSTEM | |||
std::string getDefaultTargetTriple(); | std::string getDefaultTargetTriple(); | |||
/// getProcessTriple() - Return an appropriate target triple for generati | ||||
ng | ||||
/// code to be loaded into the current process, e.g. when using the JIT. | ||||
std::string getProcessTriple(); | ||||
/// getHostCPUName - Get the LLVM name for the host CPU. The particular f ormat | /// getHostCPUName - Get the LLVM name for the host CPU. The particular f ormat | |||
/// of the name is target dependent, and suitable for passing as -mcpu to the | /// of the name is target dependent, and suitable for passing as -mcpu to the | |||
/// target which matches the host. | /// target which matches the host. | |||
/// | /// | |||
/// \return - The host CPU name, or empty if the CPU could not be determi ned. | /// \return - The host CPU name, or empty if the CPU could not be determi ned. | |||
std::string getHostCPUName(); | std::string getHostCPUName(); | |||
/// getHostCPUFeatures - Get the LLVM names for the host CPU features. | /// getHostCPUFeatures - Get the LLVM names for the host CPU features. | |||
/// The particular format of the names are target dependent, and suitable for | /// The particular format of the names are target dependent, and suitable for | |||
/// passing as -mattr to the target which matches the host. | /// passing as -mattr to the target which matches the host. | |||
End of changes. 4 change blocks. | ||||
14 lines changed or deleted | 23 lines changed or added | |||
IPO.h | IPO.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This header file defines prototypes for accessor functions that expose p asses | // This header file defines prototypes for accessor functions that expose p asses | |||
// in the IPO transformations library. | // in the IPO transformations library. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_IPO_H | #ifndef LLVM_TRANSFORMS_IPO_H | |||
#define LLVM_TRANSFORMS_IPO_H | #define LLVM_TRANSFORMS_IPO_H | |||
#include <vector> | #include "llvm/ADT/ArrayRef.h" | |||
namespace llvm { | namespace llvm { | |||
class ModulePass; | class ModulePass; | |||
class Pass; | class Pass; | |||
class Function; | class Function; | |||
class BasicBlock; | class BasicBlock; | |||
class GlobalValue; | class GlobalValue; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
skipping to change at line 109 | skipping to change at line 109 | |||
/// | /// | |||
Pass *createPruneEHPass(); | Pass *createPruneEHPass(); | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// createInternalizePass - This pass loops over all of the functions in th e | /// createInternalizePass - This pass loops over all of the functions in th e | |||
/// input module, internalizing all globals (functions and variables) not i n the | /// input module, internalizing all globals (functions and variables) not i n the | |||
/// given exportList. | /// given exportList. | |||
/// | /// | |||
/// Note that commandline options that are used with the above function are not | /// Note that commandline options that are used with the above function are not | |||
/// used now! | /// used now! | |||
ModulePass *createInternalizePass(const std::vector<const char *> &exportLi st); | ModulePass *createInternalizePass(ArrayRef<const char *> exportList); | |||
/// createInternalizePass - Same as above, but with an empty exportList. | /// createInternalizePass - Same as above, but with an empty exportList. | |||
ModulePass *createInternalizePass(); | ModulePass *createInternalizePass(); | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// createDeadArgEliminationPass - This pass removes arguments from functio ns | /// createDeadArgEliminationPass - This pass removes arguments from functio ns | |||
/// which are not used by the body of the function. | /// which are not used by the body of the function. | |||
/// | /// | |||
ModulePass *createDeadArgEliminationPass(); | ModulePass *createDeadArgEliminationPass(); | |||
/// DeadArgHacking pass - Same as DAE, but delete arguments of external | /// DeadArgHacking pass - Same as DAE, but delete arguments of external | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
IRBuilder.h | IRBuilder.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the IRBuilder class, which is used as a convenient way | // This file defines the IRBuilder class, which is used as a convenient way | |||
// to create LLVM instructions with a consistent and simplified interface. | // to create LLVM instructions with a consistent and simplified interface. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_IRBUILDER_H | #ifndef LLVM_IR_IRBUILDER_H | |||
#define LLVM_IRBUILDER_H | #define LLVM_IR_IRBUILDER_H | |||
#include "llvm/Instructions.h" | ||||
#include "llvm/BasicBlock.h" | ||||
#include "llvm/DataLayout.h" | ||||
#include "llvm/LLVMContext.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | |||
#include "llvm/IR/BasicBlock.h" | ||||
#include "llvm/IR/DataLayout.h" | ||||
#include "llvm/IR/Instructions.h" | ||||
#include "llvm/IR/LLVMContext.h" | ||||
#include "llvm/IR/Operator.h" | ||||
#include "llvm/Support/CBindingWrapping.h" | ||||
#include "llvm/Support/ConstantFolder.h" | #include "llvm/Support/ConstantFolder.h" | |||
namespace llvm { | namespace llvm { | |||
class MDNode; | class MDNode; | |||
/// IRBuilderDefaultInserter - This provides the default implementation of | /// \brief This provides the default implementation of the IRBuilder | |||
the | /// 'InsertHelper' method that is called whenever an instruction is created | |||
/// IRBuilder 'InsertHelper' method that is called whenever an instruction | by | |||
is | /// IRBuilder and needs to be inserted. | |||
/// created by IRBuilder and needs to be inserted. By default, this insert | /// | |||
s the | /// By default, this inserts the instruction at the insertion point. | |||
/// instruction at the insertion point. | ||||
template <bool preserveNames = true> | template <bool preserveNames = true> | |||
class IRBuilderDefaultInserter { | class IRBuilderDefaultInserter { | |||
protected: | protected: | |||
void InsertHelper(Instruction *I, const Twine &Name, | void InsertHelper(Instruction *I, const Twine &Name, | |||
BasicBlock *BB, BasicBlock::iterator InsertPt) const { | BasicBlock *BB, BasicBlock::iterator InsertPt) const { | |||
if (BB) BB->getInstList().insert(InsertPt, I); | if (BB) BB->getInstList().insert(InsertPt, I); | |||
if (preserveNames) | if (preserveNames) | |||
I->setName(Name); | I->setName(Name); | |||
} | } | |||
}; | }; | |||
/// IRBuilderBase - Common base class shared among various IRBuilders. | /// \brief Common base class shared among various IRBuilders. | |||
class IRBuilderBase { | class IRBuilderBase { | |||
DebugLoc CurDbgLocation; | DebugLoc CurDbgLocation; | |||
protected: | protected: | |||
/// Save the current debug location here while we are suppressing | ||||
/// line table entries. | ||||
llvm::DebugLoc SavedDbgLocation; | ||||
BasicBlock *BB; | BasicBlock *BB; | |||
BasicBlock::iterator InsertPt; | BasicBlock::iterator InsertPt; | |||
LLVMContext &Context; | LLVMContext &Context; | |||
public: | public: | |||
IRBuilderBase(LLVMContext &context) | IRBuilderBase(LLVMContext &context) | |||
: Context(context) { | : Context(context) { | |||
ClearInsertionPoint(); | ClearInsertionPoint(); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Builder configuration methods | // Builder configuration methods | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// ClearInsertionPoint - Clear the insertion point: created instructions | /// \brief Clear the insertion point: created instructions will not be | |||
will | /// inserted into a block. | |||
/// not be inserted into a block. | ||||
void ClearInsertionPoint() { | void ClearInsertionPoint() { | |||
BB = 0; | BB = 0; | |||
} | } | |||
BasicBlock *GetInsertBlock() const { return BB; } | BasicBlock *GetInsertBlock() const { return BB; } | |||
BasicBlock::iterator GetInsertPoint() const { return InsertPt; } | BasicBlock::iterator GetInsertPoint() const { return InsertPt; } | |||
LLVMContext &getContext() const { return Context; } | LLVMContext &getContext() const { return Context; } | |||
/// SetInsertPoint - This specifies that created instructions should be | /// \brief This specifies that created instructions should be appended to | |||
/// appended to the end of the specified block. | the | |||
/// end of the specified block. | ||||
void SetInsertPoint(BasicBlock *TheBB) { | void SetInsertPoint(BasicBlock *TheBB) { | |||
BB = TheBB; | BB = TheBB; | |||
InsertPt = BB->end(); | InsertPt = BB->end(); | |||
} | } | |||
/// SetInsertPoint - This specifies that created instructions should be | /// \brief This specifies that created instructions should be inserted be | |||
/// inserted before the specified instruction. | fore | |||
/// the specified instruction. | ||||
void SetInsertPoint(Instruction *I) { | void SetInsertPoint(Instruction *I) { | |||
BB = I->getParent(); | BB = I->getParent(); | |||
InsertPt = I; | InsertPt = I; | |||
SetCurrentDebugLocation(I->getDebugLoc()); | SetCurrentDebugLocation(I->getDebugLoc()); | |||
} | } | |||
/// SetInsertPoint - This specifies that created instructions should be | /// \brief This specifies that created instructions should be inserted at | |||
/// inserted at the specified point. | the | |||
/// specified point. | ||||
void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { | void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { | |||
BB = TheBB; | BB = TheBB; | |||
InsertPt = IP; | InsertPt = IP; | |||
} | } | |||
/// SetInsertPoint(Use) - Find the nearest point that dominates this use, | /// \brief Find the nearest point that dominates this use, and specify th | |||
and | at | |||
/// specify that created instructions should be inserted at this point. | /// created instructions should be inserted at this point. | |||
void SetInsertPoint(Use &U) { | void SetInsertPoint(Use &U) { | |||
Instruction *UseInst = cast<Instruction>(U.getUser()); | Instruction *UseInst = cast<Instruction>(U.getUser()); | |||
if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) { | if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) { | |||
BasicBlock *PredBB = Phi->getIncomingBlock(U); | BasicBlock *PredBB = Phi->getIncomingBlock(U); | |||
assert(U != PredBB->getTerminator() && "critical edge not split"); | assert(U != PredBB->getTerminator() && "critical edge not split"); | |||
SetInsertPoint(PredBB, PredBB->getTerminator()); | SetInsertPoint(PredBB, PredBB->getTerminator()); | |||
return; | return; | |||
} | } | |||
SetInsertPoint(UseInst); | SetInsertPoint(UseInst); | |||
} | } | |||
/// SetCurrentDebugLocation - Set location information used by debugging | /// \brief Set location information used by debugging information. | |||
/// information. | ||||
void SetCurrentDebugLocation(const DebugLoc &L) { | void SetCurrentDebugLocation(const DebugLoc &L) { | |||
CurDbgLocation = L; | CurDbgLocation = L; | |||
} | } | |||
/// getCurrentDebugLocation - Get location information used by debugging | /// \brief Temporarily suppress DebugLocations from being attached | |||
/// information. | /// 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; } | DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; } | |||
/// SetInstDebugLocation - If this builder has a current debug location, | /// \brief If this builder has a current debug location, set it on the | |||
set | /// specified instruction. | |||
/// it on the specified instruction. | ||||
void SetInstDebugLocation(Instruction *I) const { | void SetInstDebugLocation(Instruction *I) const { | |||
if (!CurDbgLocation.isUnknown()) | if (!CurDbgLocation.isUnknown()) | |||
I->setDebugLoc(CurDbgLocation); | I->setDebugLoc(CurDbgLocation); | |||
} | } | |||
/// getCurrentFunctionReturnType - Get the return type of the current fun | /// \brief Get the return type of the current function that we're emittin | |||
ction | g | |||
/// that we're emitting into. | /// into. | |||
Type *getCurrentFunctionReturnType() const; | Type *getCurrentFunctionReturnType() const; | |||
/// InsertPoint - A saved insertion point. | /// InsertPoint - A saved insertion point. | |||
class InsertPoint { | class InsertPoint { | |||
BasicBlock *Block; | BasicBlock *Block; | |||
BasicBlock::iterator Point; | BasicBlock::iterator Point; | |||
public: | public: | |||
/// Creates a new insertion point which doesn't point to anything. | /// \brief Creates a new insertion point which doesn't point to anythin g. | |||
InsertPoint() : Block(0) {} | InsertPoint() : Block(0) {} | |||
/// Creates a new insertion point at the given location. | /// \brief Creates a new insertion point at the given location. | |||
InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint) | InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint) | |||
: Block(InsertBlock), Point(InsertPoint) {} | : Block(InsertBlock), Point(InsertPoint) {} | |||
/// isSet - Returns true if this insert point is set. | /// \brief Returns true if this insert point is set. | |||
bool isSet() const { return (Block != 0); } | bool isSet() const { return (Block != 0); } | |||
llvm::BasicBlock *getBlock() const { return Block; } | llvm::BasicBlock *getBlock() const { return Block; } | |||
llvm::BasicBlock::iterator getPoint() const { return Point; } | llvm::BasicBlock::iterator getPoint() const { return Point; } | |||
}; | }; | |||
/// saveIP - Returns the current insert point. | /// \brief Returns the current insert point. | |||
InsertPoint saveIP() const { | InsertPoint saveIP() const { | |||
return InsertPoint(GetInsertBlock(), GetInsertPoint()); | return InsertPoint(GetInsertBlock(), GetInsertPoint()); | |||
} | } | |||
/// saveAndClearIP - Returns the current insert point, clearing it | /// \brief Returns the current insert point, clearing it in the process. | |||
/// in the process. | ||||
InsertPoint saveAndClearIP() { | InsertPoint saveAndClearIP() { | |||
InsertPoint IP(GetInsertBlock(), GetInsertPoint()); | InsertPoint IP(GetInsertBlock(), GetInsertPoint()); | |||
ClearInsertionPoint(); | ClearInsertionPoint(); | |||
return IP; | return IP; | |||
} | } | |||
/// restoreIP - Sets the current insert point to a previously-saved | /// \brief Sets the current insert point to a previously-saved location. | |||
/// location. | ||||
void restoreIP(InsertPoint IP) { | void restoreIP(InsertPoint IP) { | |||
if (IP.isSet()) | if (IP.isSet()) | |||
SetInsertPoint(IP.getBlock(), IP.getPoint()); | SetInsertPoint(IP.getBlock(), IP.getPoint()); | |||
else | else | |||
ClearInsertionPoint(); | ClearInsertionPoint(); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Miscellaneous creation methods. | // Miscellaneous creation methods. | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// CreateGlobalString - Make a new global variable with an initializer t | /// \brief Make a new global variable with initializer type i8* | |||
hat | /// | |||
/// has array of i8 type filled in with the nul terminated string value | /// Make a new global variable with an initializer that has array of i8 t | |||
/// specified. The new global variable will be marked mergable with any | ype | |||
/// others of the same contents. If Name is specified, it is the name of | /// filled in with the null terminated string value specified. The new g | |||
the | lobal | |||
/// global variable created. | /// variable will be marked mergable with any others of the same contents | |||
. If | ||||
/// Name is specified, it is the name of the global variable created. | ||||
Value *CreateGlobalString(StringRef Str, const Twine &Name = ""); | Value *CreateGlobalString(StringRef Str, const Twine &Name = ""); | |||
/// getInt1 - Get a constant value representing either true or false. | /// \brief Get a constant value representing either true or false. | |||
ConstantInt *getInt1(bool V) { | ConstantInt *getInt1(bool V) { | |||
return ConstantInt::get(getInt1Ty(), V); | return ConstantInt::get(getInt1Ty(), V); | |||
} | } | |||
/// getTrue - Get the constant value for i1 true. | /// \brief Get the constant value for i1 true. | |||
ConstantInt *getTrue() { | ConstantInt *getTrue() { | |||
return ConstantInt::getTrue(Context); | return ConstantInt::getTrue(Context); | |||
} | } | |||
/// getFalse - Get the constant value for i1 false. | /// \brief Get the constant value for i1 false. | |||
ConstantInt *getFalse() { | ConstantInt *getFalse() { | |||
return ConstantInt::getFalse(Context); | return ConstantInt::getFalse(Context); | |||
} | } | |||
/// getInt8 - Get a constant 8-bit value. | /// \brief Get a constant 8-bit value. | |||
ConstantInt *getInt8(uint8_t C) { | ConstantInt *getInt8(uint8_t C) { | |||
return ConstantInt::get(getInt8Ty(), C); | return ConstantInt::get(getInt8Ty(), C); | |||
} | } | |||
/// getInt16 - Get a constant 16-bit value. | /// \brief Get a constant 16-bit value. | |||
ConstantInt *getInt16(uint16_t C) { | ConstantInt *getInt16(uint16_t C) { | |||
return ConstantInt::get(getInt16Ty(), C); | return ConstantInt::get(getInt16Ty(), C); | |||
} | } | |||
/// getInt32 - Get a constant 32-bit value. | /// \brief Get a constant 32-bit value. | |||
ConstantInt *getInt32(uint32_t C) { | ConstantInt *getInt32(uint32_t C) { | |||
return ConstantInt::get(getInt32Ty(), C); | return ConstantInt::get(getInt32Ty(), C); | |||
} | } | |||
/// getInt64 - Get a constant 64-bit value. | /// \brief Get a constant 64-bit value. | |||
ConstantInt *getInt64(uint64_t C) { | ConstantInt *getInt64(uint64_t C) { | |||
return ConstantInt::get(getInt64Ty(), C); | return ConstantInt::get(getInt64Ty(), C); | |||
} | } | |||
/// getInt - Get a constant integer value. | /// \brief Get a constant integer value. | |||
ConstantInt *getInt(const APInt &AI) { | ConstantInt *getInt(const APInt &AI) { | |||
return ConstantInt::get(Context, AI); | return ConstantInt::get(Context, AI); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Type creation methods | // Type creation methods | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// getInt1Ty - Fetch the type representing a single bit | /// \brief Fetch the type representing a single bit | |||
IntegerType *getInt1Ty() { | IntegerType *getInt1Ty() { | |||
return Type::getInt1Ty(Context); | return Type::getInt1Ty(Context); | |||
} | } | |||
/// getInt8Ty - Fetch the type representing an 8-bit integer. | /// \brief Fetch the type representing an 8-bit integer. | |||
IntegerType *getInt8Ty() { | IntegerType *getInt8Ty() { | |||
return Type::getInt8Ty(Context); | return Type::getInt8Ty(Context); | |||
} | } | |||
/// getInt16Ty - Fetch the type representing a 16-bit integer. | /// \brief Fetch the type representing a 16-bit integer. | |||
IntegerType *getInt16Ty() { | IntegerType *getInt16Ty() { | |||
return Type::getInt16Ty(Context); | return Type::getInt16Ty(Context); | |||
} | } | |||
/// getInt32Ty - Fetch the type resepresenting a 32-bit integer. | /// \brief Fetch the type representing a 32-bit integer. | |||
IntegerType *getInt32Ty() { | IntegerType *getInt32Ty() { | |||
return Type::getInt32Ty(Context); | return Type::getInt32Ty(Context); | |||
} | } | |||
/// getInt64Ty - Fetch the type representing a 64-bit integer. | /// \brief Fetch the type representing a 64-bit integer. | |||
IntegerType *getInt64Ty() { | IntegerType *getInt64Ty() { | |||
return Type::getInt64Ty(Context); | return Type::getInt64Ty(Context); | |||
} | } | |||
/// getFloatTy - Fetch the type representing a 32-bit floating point valu e. | /// \brief Fetch the type representing a 32-bit floating point value. | |||
Type *getFloatTy() { | Type *getFloatTy() { | |||
return Type::getFloatTy(Context); | return Type::getFloatTy(Context); | |||
} | } | |||
/// getDoubleTy - Fetch the type representing a 64-bit floating point val ue. | /// \brief Fetch the type representing a 64-bit floating point value. | |||
Type *getDoubleTy() { | Type *getDoubleTy() { | |||
return Type::getDoubleTy(Context); | return Type::getDoubleTy(Context); | |||
} | } | |||
/// getVoidTy - Fetch the type representing void. | /// \brief Fetch the type representing void. | |||
Type *getVoidTy() { | Type *getVoidTy() { | |||
return Type::getVoidTy(Context); | return Type::getVoidTy(Context); | |||
} | } | |||
/// \brief Fetch the type representing a pointer to an 8-bit integer valu e. | ||||
PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { | PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { | |||
return Type::getInt8PtrTy(Context, AddrSpace); | return Type::getInt8PtrTy(Context, AddrSpace); | |||
} | } | |||
/// \brief Fetch the type representing a pointer to an integer value. | ||||
IntegerType* getIntPtrTy(DataLayout *DL, unsigned AddrSpace = 0) { | IntegerType* getIntPtrTy(DataLayout *DL, unsigned AddrSpace = 0) { | |||
return DL->getIntPtrType(Context, AddrSpace); | return DL->getIntPtrType(Context, AddrSpace); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Intrinsic creation methods | // Intrinsic creation methods | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// CreateMemSet - Create and insert a memset to the specified pointer an | /// \brief Create and insert a memset to the specified pointer and the | |||
d the | /// specified value. | |||
/// specified value. If the pointer isn't an i8*, it will be converted. | /// | |||
If a | /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is | |||
/// TBAA tag is specified, it will be added to the instruction. | /// specified, it will be added to the instruction. | |||
CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Al ign, | CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Al ign, | |||
bool isVolatile = false, MDNode *TBAATag = 0) { | bool isVolatile = false, MDNode *TBAATag = 0) { | |||
return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATa g); | return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATa g); | |||
} | } | |||
CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Alig n, | CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Alig n, | |||
bool isVolatile = false, MDNode *TBAATag = 0); | bool isVolatile = false, MDNode *TBAATag = 0); | |||
/// CreateMemCpy - Create and insert a memcpy between the specified point | /// \brief Create and insert a memcpy between the specified pointers. | |||
ers. | /// | |||
/// If the pointers aren't i8*, they will be converted. If a TBAA tag is | /// If the pointers aren't i8*, they will be converted. If a TBAA tag is | |||
/// specified, it will be added to the instruction. | /// specified, it will be added to the instruction. | |||
CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Al ign, | CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Al ign, | |||
bool isVolatile = false, MDNode *TBAATag = 0, | bool isVolatile = false, MDNode *TBAATag = 0, | |||
MDNode *TBAAStructTag = 0) { | MDNode *TBAAStructTag = 0) { | |||
return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATa g, | return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATa g, | |||
TBAAStructTag); | TBAAStructTag); | |||
} | } | |||
CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Alig n, | CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Alig n, | |||
bool isVolatile = false, MDNode *TBAATag = 0, | bool isVolatile = false, MDNode *TBAATag = 0, | |||
MDNode *TBAAStructTag = 0); | MDNode *TBAAStructTag = 0); | |||
/// CreateMemMove - Create and insert a memmove between the specified | /// \brief Create and insert a memmove between the specified | |||
/// pointers. If the pointers aren't i8*, they will be converted. If a | /// pointers. | |||
TBAA | /// | |||
/// tag is specified, it will be added to the instruction. | /// If the pointers aren't i8*, they will be converted. If a TBAA tag is | |||
/// specified, it will be added to the instruction. | ||||
CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned A lign, | CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned A lign, | |||
bool isVolatile = false, MDNode *TBAATag = 0) { | bool isVolatile = false, MDNode *TBAATag = 0) { | |||
return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAAT ag); | return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAAT ag); | |||
} | } | |||
CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Ali gn, | CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Ali gn, | |||
bool isVolatile = false, MDNode *TBAATag = 0); | bool isVolatile = false, MDNode *TBAATag = 0); | |||
/// CreateLifetimeStart - Create a lifetime.start intrinsic. If the poin | /// \brief Create a lifetime.start intrinsic. | |||
ter | /// | |||
/// isn't i8* it will be converted. | /// If the pointer isn't i8* it will be converted. | |||
CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = 0); | CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = 0); | |||
/// CreateLifetimeEnd - Create a lifetime.end intrinsic. If the pointer | /// \brief Create a lifetime.end intrinsic. | |||
isn't | /// | |||
/// i8* it will be converted. | /// If the pointer isn't i8* it will be converted. | |||
CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = 0); | CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = 0); | |||
private: | private: | |||
Value *getCastedInt8PtrValue(Value *Ptr); | Value *getCastedInt8PtrValue(Value *Ptr); | |||
}; | }; | |||
/// IRBuilder - This provides a uniform API for creating instructions and | /// \brief This provides a uniform API for creating instructions and insert | |||
/// inserting them into a basic block: either at the end of a BasicBlock, o | ing | |||
r | /// them into a basic block: either at the end of a BasicBlock, or at a spe | |||
/// at a specific iterator location in a block. | cific | |||
/// iterator location in a block. | ||||
/// | /// | |||
/// Note that the builder does not expose the full generality of LLVM | /// Note that the builder does not expose the full generality of LLVM | |||
/// instructions. For access to extra instruction properties, use the muta tors | /// instructions. For access to extra instruction properties, use the muta tors | |||
/// (e.g. setVolatile) on the instructions after they have been created. | /// (e.g. setVolatile) on the instructions after they have been | |||
/// created. Convenience state exists to specify fast-math flags and fp-mat | ||||
h | ||||
/// tags. | ||||
/// | ||||
/// The first template argument handles whether or not to preserve names in the | /// The first template argument handles whether or not to preserve names in the | |||
/// final instruction output. This defaults to on. The second template arg ument | /// final instruction output. This defaults to on. The second template arg ument | |||
/// specifies a class to use for creating constants. This defaults to crea ting | /// specifies a class to use for creating constants. This defaults to crea ting | |||
/// minimally folded constants. The fourth template argument allows client s to | /// minimally folded constants. The fourth template argument allows client s to | |||
/// specify custom insertion hooks that are called on every newly created | /// specify custom insertion hooks that are called on every newly created | |||
/// insertion. | /// insertion. | |||
template<bool preserveNames = true, typename T = ConstantFolder, | template<bool preserveNames = true, typename T = ConstantFolder, | |||
typename Inserter = IRBuilderDefaultInserter<preserveNames> > | typename Inserter = IRBuilderDefaultInserter<preserveNames> > | |||
class IRBuilder : public IRBuilderBase, public Inserter { | class IRBuilder : public IRBuilderBase, public Inserter { | |||
T Folder; | T Folder; | |||
MDNode *DefaultFPMathTag; | MDNode *DefaultFPMathTag; | |||
FastMathFlags FMF; | ||||
public: | public: | |||
IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(), | IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(), | |||
MDNode *FPMathTag = 0) | MDNode *FPMathTag = 0) | |||
: IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag) | : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag) | |||
{ | , | |||
FMF() { | ||||
} | } | |||
explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) : IRBuilderBase | explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) | |||
(C), | : IRBuilderBase(C), Folder(), DefaultFPMathTag(FPMathTag), FMF() { | |||
Folder(), DefaultFPMathTag(FPMathTag) { | ||||
} | } | |||
explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0) | explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0) | |||
: IRBuilderBase(TheBB->getContext()), Folder(F), | : IRBuilderBase(TheBB->getContext()), Folder(F), | |||
DefaultFPMathTag(FPMathTag) { | DefaultFPMathTag(FPMathTag), FMF() { | |||
SetInsertPoint(TheBB); | SetInsertPoint(TheBB); | |||
} | } | |||
explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0) | explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0) | |||
: IRBuilderBase(TheBB->getContext()), Folder(), | : IRBuilderBase(TheBB->getContext()), Folder(), | |||
DefaultFPMathTag(FPMathTag) { | DefaultFPMathTag(FPMathTag), FMF() { | |||
SetInsertPoint(TheBB); | SetInsertPoint(TheBB); | |||
} | } | |||
explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0) | explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0) | |||
: IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag | : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag | |||
) { | ), | |||
FMF() { | ||||
SetInsertPoint(IP); | SetInsertPoint(IP); | |||
SetCurrentDebugLocation(IP->getDebugLoc()); | SetCurrentDebugLocation(IP->getDebugLoc()); | |||
} | } | |||
explicit IRBuilder(Use &U, MDNode *FPMathTag = 0) | explicit IRBuilder(Use &U, MDNode *FPMathTag = 0) | |||
: IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag) | : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag) | |||
{ | , | |||
FMF() { | ||||
SetInsertPoint(U); | SetInsertPoint(U); | |||
SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc()); | SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc()); | |||
} | } | |||
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F, | IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F, | |||
MDNode *FPMathTag = 0) | MDNode *FPMathTag = 0) | |||
: IRBuilderBase(TheBB->getContext()), Folder(F), | : IRBuilderBase(TheBB->getContext()), Folder(F), | |||
DefaultFPMathTag(FPMathTag) { | DefaultFPMathTag(FPMathTag), FMF() { | |||
SetInsertPoint(TheBB, IP); | SetInsertPoint(TheBB, IP); | |||
} | } | |||
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0) | IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0) | |||
: IRBuilderBase(TheBB->getContext()), Folder(), | : IRBuilderBase(TheBB->getContext()), Folder(), | |||
DefaultFPMathTag(FPMathTag) { | DefaultFPMathTag(FPMathTag), FMF() { | |||
SetInsertPoint(TheBB, IP); | SetInsertPoint(TheBB, IP); | |||
} | } | |||
/// getFolder - Get the constant folder being used. | /// \brief Get the constant folder being used. | |||
const T &getFolder() { return Folder; } | const T &getFolder() { return Folder; } | |||
/// getDefaultFPMathTag - Get the floating point math metadata being used . | /// \brief Get the floating point math metadata being used. | |||
MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; } | MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; } | |||
/// SetDefaultFPMathTag - Set the floating point math metadata to be used | /// \brief Get the flags to be applied to created floating point ops | |||
. | FastMathFlags getFastMathFlags() const { return FMF; } | |||
/// \brief Clear the fast-math flags. | ||||
void clearFastMathFlags() { FMF.clear(); } | ||||
/// \brief SetDefaultFPMathTag - Set the floating point math metadata to | ||||
be used. | ||||
void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTa g; } | void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTa g; } | |||
/// isNamePreserving - Return true if this builder is configured to actua | /// \brief Set the fast-math flags to be used with generated fp-math oper | |||
lly | ators | |||
/// add the requested names to IR created through it. | void SetFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; } | |||
/// \brief Return true if this builder is configured to actually add the | ||||
/// requested names to IR created through it. | ||||
bool isNamePreserving() const { return preserveNames; } | bool isNamePreserving() const { return preserveNames; } | |||
/// Insert - Insert and return the specified instruction. | /// \brief Insert and return the specified instruction. | |||
template<typename InstTy> | template<typename InstTy> | |||
InstTy *Insert(InstTy *I, const Twine &Name = "") const { | InstTy *Insert(InstTy *I, const Twine &Name = "") const { | |||
this->InsertHelper(I, Name, BB, InsertPt); | this->InsertHelper(I, Name, BB, InsertPt); | |||
if (!getCurrentDebugLocation().isUnknown()) | this->SetInstDebugLocation(I); | |||
this->SetInstDebugLocation(I); | ||||
return I; | return I; | |||
} | } | |||
/// Insert - No-op overload to handle constants. | /// \brief No-op overload to handle constants. | |||
Constant *Insert(Constant *C, const Twine& = "") const { | Constant *Insert(Constant *C, const Twine& = "") const { | |||
return C; | return C; | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Instruction creation methods: Terminators | // Instruction creation methods: Terminators | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
private: | private: | |||
/// \brief Helper to add branch weight metadata onto an instruction. | /// \brief Helper to add branch weight metadata onto an instruction. | |||
/// \returns The annotated instruction. | /// \returns The annotated instruction. | |||
template <typename InstTy> | template <typename InstTy> | |||
InstTy *addBranchWeights(InstTy *I, MDNode *Weights) { | InstTy *addBranchWeights(InstTy *I, MDNode *Weights) { | |||
if (Weights) | if (Weights) | |||
I->setMetadata(LLVMContext::MD_prof, Weights); | I->setMetadata(LLVMContext::MD_prof, Weights); | |||
return I; | return I; | |||
} | } | |||
public: | public: | |||
/// CreateRetVoid - Create a 'ret void' instruction. | /// \brief Create a 'ret void' instruction. | |||
ReturnInst *CreateRetVoid() { | ReturnInst *CreateRetVoid() { | |||
return Insert(ReturnInst::Create(Context)); | return Insert(ReturnInst::Create(Context)); | |||
} | } | |||
/// @verbatim | /// \brief Create a 'ret <val>' instruction. | |||
/// CreateRet - Create a 'ret <val>' instruction. | ||||
/// @endverbatim | ||||
ReturnInst *CreateRet(Value *V) { | ReturnInst *CreateRet(Value *V) { | |||
return Insert(ReturnInst::Create(Context, V)); | return Insert(ReturnInst::Create(Context, V)); | |||
} | } | |||
/// CreateAggregateRet - Create a sequence of N insertvalue instructions, | /// \brief Create a sequence of N insertvalue instructions, | |||
/// with one Value from the retVals array each, that build a aggregate | /// with one Value from the retVals array each, that build a aggregate | |||
/// return value one value at a time, and a ret instruction to return | /// return value one value at a time, and a ret instruction to return | |||
/// the resulting aggregate value. This is a convenience function for | /// the resulting aggregate value. | |||
/// code that uses aggregate return values as a vehicle for having | ||||
/// multiple return values. | ||||
/// | /// | |||
/// This is a convenience function for code that uses aggregate return va | ||||
lues | ||||
/// as a vehicle for having multiple return values. | ||||
ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) { | ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) { | |||
Value *V = UndefValue::get(getCurrentFunctionReturnType()); | Value *V = UndefValue::get(getCurrentFunctionReturnType()); | |||
for (unsigned i = 0; i != N; ++i) | for (unsigned i = 0; i != N; ++i) | |||
V = CreateInsertValue(V, retVals[i], i, "mrv"); | V = CreateInsertValue(V, retVals[i], i, "mrv"); | |||
return Insert(ReturnInst::Create(Context, V)); | return Insert(ReturnInst::Create(Context, V)); | |||
} | } | |||
/// CreateBr - Create an unconditional 'br label X' instruction. | /// \brief Create an unconditional 'br label X' instruction. | |||
BranchInst *CreateBr(BasicBlock *Dest) { | BranchInst *CreateBr(BasicBlock *Dest) { | |||
return Insert(BranchInst::Create(Dest)); | return Insert(BranchInst::Create(Dest)); | |||
} | } | |||
/// CreateCondBr - Create a conditional 'br Cond, TrueDest, FalseDest' | /// \brief Create a conditional 'br Cond, TrueDest, FalseDest' | |||
/// instruction. | /// instruction. | |||
BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False , | BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False , | |||
MDNode *BranchWeights = 0) { | MDNode *BranchWeights = 0) { | |||
return Insert(addBranchWeights(BranchInst::Create(True, False, Cond), | return Insert(addBranchWeights(BranchInst::Create(True, False, Cond), | |||
BranchWeights)); | BranchWeights)); | |||
} | } | |||
/// CreateSwitch - Create a switch instruction with the specified value, | /// \brief Create a switch instruction with the specified value, default | |||
/// default dest, and with a hint for the number of cases that will be ad | dest, | |||
ded | /// and with a hint for the number of cases that will be added (for effic | |||
/// (for efficient allocation). | ient | |||
/// allocation). | ||||
SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10, | SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10, | |||
MDNode *BranchWeights = 0) { | MDNode *BranchWeights = 0) { | |||
return Insert(addBranchWeights(SwitchInst::Create(V, Dest, NumCases), | return Insert(addBranchWeights(SwitchInst::Create(V, Dest, NumCases), | |||
BranchWeights)); | BranchWeights)); | |||
} | } | |||
/// CreateIndirectBr - Create an indirect branch instruction with the | /// \brief Create an indirect branch instruction with the specified addre | |||
/// specified address operand, with an optional hint for the number of | ss | |||
/// destinations that will be added (for efficient allocation). | /// operand, with an optional hint for the number of destinations that wi | |||
ll be | ||||
/// added (for efficient allocation). | ||||
IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) { | IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) { | |||
return Insert(IndirectBrInst::Create(Addr, NumDests)); | return Insert(IndirectBrInst::Create(Addr, NumDests)); | |||
} | } | |||
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, | InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, | |||
BasicBlock *UnwindDest, const Twine &Name = "") { | BasicBlock *UnwindDest, const Twine &Name = "") { | |||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, | return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, | |||
ArrayRef<Value *>()), | ArrayRef<Value *>()), | |||
Name); | Name); | |||
} | } | |||
skipping to change at line 508 | skipping to change at line 551 | |||
Name); | Name); | |||
} | } | |||
InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest, | InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest, | |||
BasicBlock *UnwindDest, Value *Arg1, | BasicBlock *UnwindDest, Value *Arg1, | |||
Value *Arg2, Value *Arg3, | Value *Arg2, Value *Arg3, | |||
const Twine &Name = "") { | const Twine &Name = "") { | |||
Value *Args[] = { Arg1, Arg2, Arg3 }; | Value *Args[] = { Arg1, Arg2, Arg3 }; | |||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args), | return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args), | |||
Name); | Name); | |||
} | } | |||
/// CreateInvoke - Create an invoke instruction. | /// \brief Create an invoke instruction. | |||
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, | InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, | |||
BasicBlock *UnwindDest, ArrayRef<Value *> Args, | BasicBlock *UnwindDest, ArrayRef<Value *> Args, | |||
const Twine &Name = "") { | const Twine &Name = "") { | |||
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args), | return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args), | |||
Name); | Name); | |||
} | } | |||
ResumeInst *CreateResume(Value *Exn) { | ResumeInst *CreateResume(Value *Exn) { | |||
return Insert(ResumeInst::Create(Exn)); | return Insert(ResumeInst::Create(Exn)); | |||
} | } | |||
skipping to change at line 538 | skipping to change at line 581 | |||
BinaryOperator *CreateInsertNUWNSWBinOp(BinaryOperator::BinaryOps Opc, | BinaryOperator *CreateInsertNUWNSWBinOp(BinaryOperator::BinaryOps Opc, | |||
Value *LHS, Value *RHS, | Value *LHS, Value *RHS, | |||
const Twine &Name, | const Twine &Name, | |||
bool HasNUW, bool HasNSW) { | bool HasNUW, bool HasNSW) { | |||
BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name ); | BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name ); | |||
if (HasNUW) BO->setHasNoUnsignedWrap(); | if (HasNUW) BO->setHasNoUnsignedWrap(); | |||
if (HasNSW) BO->setHasNoSignedWrap(); | if (HasNSW) BO->setHasNoSignedWrap(); | |||
return BO; | return BO; | |||
} | } | |||
Instruction *AddFPMathTag(Instruction *I, MDNode *FPMathTag) const { | Instruction *AddFPMathAttributes(Instruction *I, | |||
MDNode *FPMathTag, | ||||
FastMathFlags FMF) const { | ||||
if (!FPMathTag) | if (!FPMathTag) | |||
FPMathTag = DefaultFPMathTag; | FPMathTag = DefaultFPMathTag; | |||
if (FPMathTag) | if (FPMathTag) | |||
I->setMetadata(LLVMContext::MD_fpmath, FPMathTag); | I->setMetadata(LLVMContext::MD_fpmath, FPMathTag); | |||
I->setFastMathFlags(FMF); | ||||
return I; | return I; | |||
} | } | |||
public: | public: | |||
Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", | Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", | |||
bool HasNUW = false, bool HasNSW = false) { | bool HasNUW = false, bool HasNSW = false) { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name); | return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name); | |||
return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name, | return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name, | |||
HasNUW, HasNSW); | HasNUW, HasNSW); | |||
skipping to change at line 565 | skipping to change at line 611 | |||
return CreateAdd(LHS, RHS, Name, false, true); | return CreateAdd(LHS, RHS, Name, false, true); | |||
} | } | |||
Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { | Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
return CreateAdd(LHS, RHS, Name, true, false); | return CreateAdd(LHS, RHS, Name, true, false); | |||
} | } | |||
Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "", | Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "", | |||
MDNode *FPMathTag = 0) { | MDNode *FPMathTag = 0) { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateFAdd(LC, RC), Name); | return Insert(Folder.CreateFAdd(LC, RC), Name); | |||
return Insert(AddFPMathTag(BinaryOperator::CreateFAdd(LHS, RHS), | return Insert(AddFPMathAttributes(BinaryOperator::CreateFAdd(LHS, RHS), | |||
FPMathTag), Name); | FPMathTag, FMF), Name); | |||
} | } | |||
Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "", | Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "", | |||
bool HasNUW = false, bool HasNSW = false) { | bool HasNUW = false, bool HasNSW = false) { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateSub(LC, RC), Name); | return Insert(Folder.CreateSub(LC, RC), Name); | |||
return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name, | return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name, | |||
HasNUW, HasNSW); | HasNUW, HasNSW); | |||
} | } | |||
Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") { | Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
return CreateSub(LHS, RHS, Name, false, true); | return CreateSub(LHS, RHS, Name, false, true); | |||
} | } | |||
Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") { | Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
return CreateSub(LHS, RHS, Name, true, false); | return CreateSub(LHS, RHS, Name, true, false); | |||
} | } | |||
Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "", | Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "", | |||
MDNode *FPMathTag = 0) { | MDNode *FPMathTag = 0) { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateFSub(LC, RC), Name); | return Insert(Folder.CreateFSub(LC, RC), Name); | |||
return Insert(AddFPMathTag(BinaryOperator::CreateFSub(LHS, RHS), | return Insert(AddFPMathAttributes(BinaryOperator::CreateFSub(LHS, RHS), | |||
FPMathTag), Name); | FPMathTag, FMF), Name); | |||
} | } | |||
Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "", | Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "", | |||
bool HasNUW = false, bool HasNSW = false) { | bool HasNUW = false, bool HasNSW = false) { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateMul(LC, RC), Name); | return Insert(Folder.CreateMul(LC, RC), Name); | |||
return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name, | return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name, | |||
HasNUW, HasNSW); | HasNUW, HasNSW); | |||
} | } | |||
Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") { | Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
return CreateMul(LHS, RHS, Name, false, true); | return CreateMul(LHS, RHS, Name, false, true); | |||
} | } | |||
Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") { | Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
return CreateMul(LHS, RHS, Name, true, false); | return CreateMul(LHS, RHS, Name, true, false); | |||
} | } | |||
Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "", | Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "", | |||
MDNode *FPMathTag = 0) { | MDNode *FPMathTag = 0) { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateFMul(LC, RC), Name); | return Insert(Folder.CreateFMul(LC, RC), Name); | |||
return Insert(AddFPMathTag(BinaryOperator::CreateFMul(LHS, RHS), | return Insert(AddFPMathAttributes(BinaryOperator::CreateFMul(LHS, RHS), | |||
FPMathTag), Name); | FPMathTag, FMF), Name); | |||
} | } | |||
Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "", | Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "", | |||
bool isExact = false) { | bool isExact = false) { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateUDiv(LC, RC, isExact), Name); | return Insert(Folder.CreateUDiv(LC, RC, isExact), Name); | |||
if (!isExact) | if (!isExact) | |||
return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name); | return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name); | |||
return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name); | return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name); | |||
} | } | |||
skipping to change at line 641 | skipping to change at line 687 | |||
return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name); | return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name); | |||
} | } | |||
Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") { | Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
return CreateSDiv(LHS, RHS, Name, true); | return CreateSDiv(LHS, RHS, Name, true); | |||
} | } | |||
Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "", | Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "", | |||
MDNode *FPMathTag = 0) { | MDNode *FPMathTag = 0) { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateFDiv(LC, RC), Name); | return Insert(Folder.CreateFDiv(LC, RC), Name); | |||
return Insert(AddFPMathTag(BinaryOperator::CreateFDiv(LHS, RHS), | return Insert(AddFPMathAttributes(BinaryOperator::CreateFDiv(LHS, RHS), | |||
FPMathTag), Name); | FPMathTag, FMF), Name); | |||
} | } | |||
Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") { | Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateURem(LC, RC), Name); | return Insert(Folder.CreateURem(LC, RC), Name); | |||
return Insert(BinaryOperator::CreateURem(LHS, RHS), Name); | return Insert(BinaryOperator::CreateURem(LHS, RHS), Name); | |||
} | } | |||
Value *CreateSRem(Value *LHS, Value *RHS, const Twine &Name = "") { | Value *CreateSRem(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateSRem(LC, RC), Name); | return Insert(Folder.CreateSRem(LC, RC), Name); | |||
return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name); | return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name); | |||
} | } | |||
Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "", | Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "", | |||
MDNode *FPMathTag = 0) { | MDNode *FPMathTag = 0) { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateFRem(LC, RC), Name); | return Insert(Folder.CreateFRem(LC, RC), Name); | |||
return Insert(AddFPMathTag(BinaryOperator::CreateFRem(LHS, RHS), | return Insert(AddFPMathAttributes(BinaryOperator::CreateFRem(LHS, RHS), | |||
FPMathTag), Name); | FPMathTag, FMF), Name); | |||
} | } | |||
Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "", | Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "", | |||
bool HasNUW = false, bool HasNSW = false) { | bool HasNUW = false, bool HasNSW = false) { | |||
if (Constant *LC = dyn_cast<Constant>(LHS)) | if (Constant *LC = dyn_cast<Constant>(LHS)) | |||
if (Constant *RC = dyn_cast<Constant>(RHS)) | if (Constant *RC = dyn_cast<Constant>(RHS)) | |||
return Insert(Folder.CreateShl(LC, RC, HasNUW, HasNSW), Name); | return Insert(Folder.CreateShl(LC, RC, HasNUW, HasNSW), Name); | |||
return CreateInsertNUWNSWBinOp(Instruction::Shl, LHS, RHS, Name, | return CreateInsertNUWNSWBinOp(Instruction::Shl, LHS, RHS, Name, | |||
HasNUW, HasNSW); | HasNUW, HasNSW); | |||
} | } | |||
skipping to change at line 791 | skipping to change at line 837 | |||
} | } | |||
Value *CreateNSWNeg(Value *V, const Twine &Name = "") { | Value *CreateNSWNeg(Value *V, const Twine &Name = "") { | |||
return CreateNeg(V, Name, false, true); | return CreateNeg(V, Name, false, true); | |||
} | } | |||
Value *CreateNUWNeg(Value *V, const Twine &Name = "") { | Value *CreateNUWNeg(Value *V, const Twine &Name = "") { | |||
return CreateNeg(V, Name, true, false); | return CreateNeg(V, Name, true, false); | |||
} | } | |||
Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = 0 ) { | Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = 0 ) { | |||
if (Constant *VC = dyn_cast<Constant>(V)) | if (Constant *VC = dyn_cast<Constant>(V)) | |||
return Insert(Folder.CreateFNeg(VC), Name); | return Insert(Folder.CreateFNeg(VC), Name); | |||
return Insert(AddFPMathTag(BinaryOperator::CreateFNeg(V), FPMathTag), N | return Insert(AddFPMathAttributes(BinaryOperator::CreateFNeg(V), | |||
ame); | FPMathTag, FMF), Name); | |||
} | } | |||
Value *CreateNot(Value *V, const Twine &Name = "") { | Value *CreateNot(Value *V, const Twine &Name = "") { | |||
if (Constant *VC = dyn_cast<Constant>(V)) | if (Constant *VC = dyn_cast<Constant>(V)) | |||
return Insert(Folder.CreateNot(VC), Name); | return Insert(Folder.CreateNot(VC), Name); | |||
return Insert(BinaryOperator::CreateNot(V), Name); | return Insert(BinaryOperator::CreateNot(V), Name); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Instruction creation methods: Memory Instructions | // Instruction creation methods: Memory Instructions | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = 0, | AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = 0, | |||
const Twine &Name = "") { | const Twine &Name = "") { | |||
return Insert(new AllocaInst(Ty, ArraySize), Name); | return Insert(new AllocaInst(Ty, ArraySize), Name); | |||
} | } | |||
// Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of | // \brief Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of | |||
// converting the string to 'bool' for the isVolatile parameter. | // converting the string to 'bool' for the isVolatile parameter. | |||
LoadInst *CreateLoad(Value *Ptr, const char *Name) { | LoadInst *CreateLoad(Value *Ptr, const char *Name) { | |||
return Insert(new LoadInst(Ptr), Name); | return Insert(new LoadInst(Ptr), Name); | |||
} | } | |||
LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") { | LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") { | |||
return Insert(new LoadInst(Ptr), Name); | return Insert(new LoadInst(Ptr), Name); | |||
} | } | |||
LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") { | LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") { | |||
return Insert(new LoadInst(Ptr, 0, isVolatile), Name); | return Insert(new LoadInst(Ptr, 0, isVolatile), Name); | |||
} | } | |||
StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { | StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { | |||
return Insert(new StoreInst(Val, Ptr, isVolatile)); | return Insert(new StoreInst(Val, Ptr, isVolatile)); | |||
} | } | |||
// Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' correctly, | // \brief Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' | |||
// instead of converting the string to 'bool' for the isVolatile paramete | // correctly, instead of converting the string to 'bool' for the isVolati | |||
r. | le | |||
// parameter. | ||||
LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) { | LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) { | |||
LoadInst *LI = CreateLoad(Ptr, Name); | LoadInst *LI = CreateLoad(Ptr, Name); | |||
LI->setAlignment(Align); | LI->setAlignment(Align); | |||
return LI; | return LI; | |||
} | } | |||
LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, | LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, | |||
const Twine &Name = "") { | const Twine &Name = "") { | |||
LoadInst *LI = CreateLoad(Ptr, Name); | LoadInst *LI = CreateLoad(Ptr, Name); | |||
LI->setAlignment(Align); | LI->setAlignment(Align); | |||
return LI; | return LI; | |||
skipping to change at line 984 | skipping to change at line 1032 | |||
if (Constant *PC = dyn_cast<Constant>(Ptr)) | if (Constant *PC = dyn_cast<Constant>(Ptr)) | |||
return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name); | return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name); | |||
return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name); | return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name); | |||
} | } | |||
Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { | Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { | |||
return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name); | return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name); | |||
} | } | |||
/// CreateGlobalStringPtr - Same as CreateGlobalString, but return a poin | /// \brief Same as CreateGlobalString, but return a pointer with "i8*" ty | |||
ter | pe | |||
/// with "i8*" type instead of a pointer to array of i8. | /// instead of a pointer to array of i8. | |||
Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") { | Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") { | |||
Value *gv = CreateGlobalString(Str, Name); | Value *gv = CreateGlobalString(Str, Name); | |||
Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0); | Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0); | |||
Value *Args[] = { zero, zero }; | Value *Args[] = { zero, zero }; | |||
return CreateInBoundsGEP(gv, Args, Name); | return CreateInBoundsGEP(gv, Args, Name); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Instruction creation methods: Cast/Conversion Operators | // Instruction creation methods: Cast/Conversion Operators | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
Value *CreateTrunc(Value *V, Type *DestTy, const Twine &Name = "") { | Value *CreateTrunc(Value *V, Type *DestTy, const Twine &Name = "") { | |||
return CreateCast(Instruction::Trunc, V, DestTy, Name); | return CreateCast(Instruction::Trunc, V, DestTy, Name); | |||
} | } | |||
Value *CreateZExt(Value *V, Type *DestTy, const Twine &Name = "") { | Value *CreateZExt(Value *V, Type *DestTy, const Twine &Name = "") { | |||
return CreateCast(Instruction::ZExt, V, DestTy, Name); | return CreateCast(Instruction::ZExt, V, DestTy, Name); | |||
} | } | |||
Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") { | Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") { | |||
return CreateCast(Instruction::SExt, V, DestTy, Name); | return CreateCast(Instruction::SExt, V, DestTy, Name); | |||
} | } | |||
/// CreateZExtOrTrunc - Create a ZExt or Trunc from the integer value V t | /// \brief Create a ZExt or Trunc from the integer value V to DestTy. Ret | |||
o | urn | |||
/// DestTy. Return the value untouched if the type of V is already DestTy | /// the value untouched if the type of V is already DestTy. | |||
. | Value *CreateZExtOrTrunc(Value *V, Type *DestTy, | |||
Value *CreateZExtOrTrunc(Value *V, IntegerType *DestTy, | ||||
const Twine &Name = "") { | const Twine &Name = "") { | |||
assert(isa<IntegerType>(V->getType()) && "Can only zero extend integers | assert(V->getType()->isIntOrIntVectorTy() && | |||
!"); | DestTy->isIntOrIntVectorTy() && | |||
IntegerType *IntTy = cast<IntegerType>(V->getType()); | "Can only zero extend/truncate integers!"); | |||
if (IntTy->getBitWidth() < DestTy->getBitWidth()) | Type *VTy = V->getType(); | |||
if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits()) | ||||
return CreateZExt(V, DestTy, Name); | return CreateZExt(V, DestTy, Name); | |||
if (IntTy->getBitWidth() > DestTy->getBitWidth()) | if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits()) | |||
return CreateTrunc(V, DestTy, Name); | return CreateTrunc(V, DestTy, Name); | |||
return V; | return V; | |||
} | } | |||
/// CreateSExtOrTrunc - Create a SExt or Trunc from the integer value V t | /// \brief Create a SExt or Trunc from the integer value V to DestTy. Ret | |||
o | urn | |||
/// DestTy. Return the value untouched if the type of V is already DestTy | /// the value untouched if the type of V is already DestTy. | |||
. | Value *CreateSExtOrTrunc(Value *V, Type *DestTy, | |||
Value *CreateSExtOrTrunc(Value *V, IntegerType *DestTy, | ||||
const Twine &Name = "") { | const Twine &Name = "") { | |||
assert(isa<IntegerType>(V->getType()) && "Can only sign extend integers | assert(V->getType()->isIntOrIntVectorTy() && | |||
!"); | DestTy->isIntOrIntVectorTy() && | |||
IntegerType *IntTy = cast<IntegerType>(V->getType()); | "Can only sign extend/truncate integers!"); | |||
if (IntTy->getBitWidth() < DestTy->getBitWidth()) | Type *VTy = V->getType(); | |||
if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits()) | ||||
return CreateSExt(V, DestTy, Name); | return CreateSExt(V, DestTy, Name); | |||
if (IntTy->getBitWidth() > DestTy->getBitWidth()) | if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits()) | |||
return CreateTrunc(V, DestTy, Name); | return CreateTrunc(V, DestTy, Name); | |||
return V; | return V; | |||
} | } | |||
Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){ | Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){ | |||
return CreateCast(Instruction::FPToUI, V, DestTy, Name); | return CreateCast(Instruction::FPToUI, V, DestTy, Name); | |||
} | } | |||
Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = ""){ | Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = ""){ | |||
return CreateCast(Instruction::FPToSI, V, DestTy, Name); | return CreateCast(Instruction::FPToSI, V, DestTy, Name); | |||
} | } | |||
Value *CreateUIToFP(Value *V, Type *DestTy, const Twine &Name = ""){ | Value *CreateUIToFP(Value *V, Type *DestTy, const Twine &Name = ""){ | |||
skipping to change at line 1110 | skipping to change at line 1162 | |||
} | } | |||
Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned, | Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned, | |||
const Twine &Name = "") { | const Twine &Name = "") { | |||
if (V->getType() == DestTy) | if (V->getType() == DestTy) | |||
return V; | return V; | |||
if (Constant *VC = dyn_cast<Constant>(V)) | if (Constant *VC = dyn_cast<Constant>(V)) | |||
return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name); | return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name); | |||
return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name); | return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name); | |||
} | } | |||
private: | private: | |||
// Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a compile | // \brief Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a | |||
time | // compile time error, instead of converting the string to bool for the | |||
// error, instead of converting the string to bool for the isSigned param | // isSigned parameter. | |||
eter. | ||||
Value *CreateIntCast(Value *, Type *, const char *) LLVM_DELETED_FUNCTION ; | Value *CreateIntCast(Value *, Type *, const char *) LLVM_DELETED_FUNCTION ; | |||
public: | public: | |||
Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") { | Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") { | |||
if (V->getType() == DestTy) | if (V->getType() == DestTy) | |||
return V; | return V; | |||
if (Constant *VC = dyn_cast<Constant>(V)) | if (Constant *VC = dyn_cast<Constant>(V)) | |||
return Insert(Folder.CreateFPCast(VC, DestTy), Name); | return Insert(Folder.CreateFPCast(VC, DestTy), Name); | |||
return Insert(CastInst::CreateFPCast(V, DestTy), Name); | return Insert(CastInst::CreateFPCast(V, DestTy), Name); | |||
} | } | |||
skipping to change at line 1314 | skipping to change at line 1367 | |||
ArrayRef<unsigned> Idxs, | ArrayRef<unsigned> Idxs, | |||
const Twine &Name = "") { | const Twine &Name = "") { | |||
if (Constant *AggC = dyn_cast<Constant>(Agg)) | if (Constant *AggC = dyn_cast<Constant>(Agg)) | |||
if (Constant *ValC = dyn_cast<Constant>(Val)) | if (Constant *ValC = dyn_cast<Constant>(Val)) | |||
return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name); | return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name); | |||
return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name); | return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name); | |||
} | } | |||
LandingPadInst *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumCla uses, | LandingPadInst *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumCla uses, | |||
const Twine &Name = "") { | const Twine &Name = "") { | |||
return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses, Name)); | return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses), Name); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Utility creation methods | // Utility creation methods | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// CreateIsNull - Return an i1 value testing if \p Arg is null. | /// \brief Return an i1 value testing if \p Arg is null. | |||
Value *CreateIsNull(Value *Arg, const Twine &Name = "") { | Value *CreateIsNull(Value *Arg, const Twine &Name = "") { | |||
return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()), | return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()), | |||
Name); | Name); | |||
} | } | |||
/// CreateIsNotNull - Return an i1 value testing if \p Arg is not null. | /// \brief Return an i1 value testing if \p Arg is not null. | |||
Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") { | Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") { | |||
return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()), | return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()), | |||
Name); | Name); | |||
} | } | |||
/// CreatePtrDiff - Return the i64 difference between two pointer values, | /// \brief Return the i64 difference between two pointer values, dividing | |||
/// dividing out the size of the pointed-to objects. This is intended to | out | |||
/// implement C-style pointer subtraction. As such, the pointers must be | /// the size of the pointed-to objects. | |||
/// appropriately aligned for their element types and pointing into the | /// | |||
/// same object. | /// This is intended to implement C-style pointer subtraction. As such, t | |||
he | ||||
/// pointers must be appropriately aligned for their element types and | ||||
/// pointing into the same object. | ||||
Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") { | Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") { | |||
assert(LHS->getType() == RHS->getType() && | assert(LHS->getType() == RHS->getType() && | |||
"Pointer subtraction operand types must match!"); | "Pointer subtraction operand types must match!"); | |||
PointerType *ArgType = cast<PointerType>(LHS->getType()); | PointerType *ArgType = cast<PointerType>(LHS->getType()); | |||
Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context)); | Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context)); | |||
Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context)); | Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context)); | |||
Value *Difference = CreateSub(LHS_int, RHS_int); | Value *Difference = CreateSub(LHS_int, RHS_int); | |||
return CreateExactSDiv(Difference, | return CreateExactSDiv(Difference, | |||
ConstantExpr::getSizeOf(ArgType->getElementType( )), | ConstantExpr::getSizeOf(ArgType->getElementType( )), | |||
Name); | Name); | |||
} | } | |||
/// \brief Return a vector value that contains \arg V broadcasted to \p | ||||
/// NumElts elements. | ||||
Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = | ||||
"") { | ||||
assert(NumElts > 0 && "Cannot splat to an empty vector!"); | ||||
// First insert it into an undef vector so we can shuffle it. | ||||
Type *I32Ty = getInt32Ty(); | ||||
Value *Undef = UndefValue::get(VectorType::get(V->getType(), NumElts)); | ||||
V = CreateInsertElement(Undef, V, ConstantInt::get(I32Ty, 0), | ||||
Name + ".splatinsert"); | ||||
// Shuffle the value across the desired number of elements. | ||||
Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, NumElt | ||||
s)); | ||||
return CreateShuffleVector(V, Undef, Zeros, Name + ".splat"); | ||||
} | ||||
}; | }; | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef) | ||||
} | } | |||
#endif | #endif | |||
End of changes. 97 change blocks. | ||||
183 lines changed or deleted | 252 lines changed or added | |||
IRReader.h | IRReader.h | |||
---|---|---|---|---|
//===---- llvm/Support/IRReader.h - Reader for LLVM IR files ----*- C++ -*- ===// | //===---- llvm/IRReader/IRReader.h - Reader for LLVM IR files ---*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines functions for reading LLVM IR. They support both | // This file defines functions for reading LLVM IR. They support both | |||
// Bitcode and Assembly, automatically detecting the input format. | // Bitcode and Assembly, automatically detecting the input format. | |||
// | // | |||
// These functions must be defined in a header file in order to avoid | ||||
// library dependencies, since they reference both Bitcode and Assembly | ||||
// functions. | ||||
// | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_IRREADER_H | #ifndef LLVM_IRREADER_IRREADER_H | |||
#define LLVM_SUPPORT_IRREADER_H | #define LLVM_IRREADER_IRREADER_H | |||
#include "llvm/ADT/OwningPtr.h" | #include <string> | |||
#include "llvm/Assembly/Parser.h" | ||||
#include "llvm/Bitcode/ReaderWriter.h" | ||||
#include "llvm/Support/MemoryBuffer.h" | ||||
#include "llvm/Support/SourceMgr.h" | ||||
#include "llvm/Support/system_error.h" | ||||
namespace llvm { | namespace llvm { | |||
/// If the given MemoryBuffer holds a bitcode image, return a Module for | class Module; | |||
it | class MemoryBuffer; | |||
/// which does lazy deserialization of function bodies. Otherwise, attem | class SMDiagnostic; | |||
pt to | class LLVMContext; | |||
/// parse it as LLVM Assembly and return a fully populated Module. This | ||||
/// function *always* takes ownership of the given MemoryBuffer. | /// If the given MemoryBuffer holds a bitcode image, return a Module for it | |||
inline Module *getLazyIRModule(MemoryBuffer *Buffer, | /// which does lazy deserialization of function bodies. Otherwise, attempt | |||
SMDiagnostic &Err, | to | |||
LLVMContext &Context) { | /// parse it as LLVM Assembly and return a fully populated Module. This | |||
if (isBitcode((const unsigned char *)Buffer->getBufferStart(), | /// function *always* takes ownership of the given MemoryBuffer. | |||
(const unsigned char *)Buffer->getBufferEnd())) { | Module *getLazyIRModule(MemoryBuffer *Buffer, SMDiagnostic &Err, | |||
std::string ErrMsg; | LLVMContext &Context); | |||
Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg); | ||||
if (M == 0) { | /// If the given file holds a bitcode image, return a Module | |||
Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Err | /// for it which does lazy deserialization of function bodies. Otherwise, | |||
or, | /// attempt to parse it as LLVM Assembly and return a fully populated | |||
ErrMsg); | /// Module. | |||
// ParseBitcodeFile does not take ownership of the Buffer in the | Module *getLazyIRFileModule(const std::string &Filename, SMDiagnostic &Err, | |||
// case of an error. | LLVMContext &Context); | |||
delete Buffer; | ||||
} | /// If the given MemoryBuffer holds a bitcode image, return a Module | |||
return M; | /// for it. Otherwise, attempt to parse it as LLVM Assembly and return | |||
} | /// a Module for it. This function *always* takes ownership of the given | |||
/// MemoryBuffer. | ||||
return ParseAssembly(Buffer, 0, Err, Context); | Module *ParseIR(MemoryBuffer *Buffer, SMDiagnostic &Err, LLVMContext &Conte | |||
} | xt); | |||
/// If the given file holds a bitcode image, return a Module | /// If the given file holds a bitcode image, return a Module for it. | |||
/// for it which does lazy deserialization of function bodies. Otherwise | /// Otherwise, attempt to parse it as LLVM Assembly and return a Module | |||
, | /// for it. | |||
/// attempt to parse it as LLVM Assembly and return a fully populated | Module *ParseIRFile(const std::string &Filename, SMDiagnostic &Err, | |||
/// Module. | LLVMContext &Context); | |||
inline Module *getLazyIRFileModule(const std::string &Filename, | ||||
SMDiagnostic &Err, | ||||
LLVMContext &Context) { | ||||
OwningPtr<MemoryBuffer> File; | ||||
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File | ||||
)) { | ||||
Err = SMDiagnostic(Filename, SourceMgr::DK_Error, | ||||
"Could not open input file: " + ec.message()); | ||||
return 0; | ||||
} | ||||
return getLazyIRModule(File.take(), Err, Context); | ||||
} | ||||
/// If the given MemoryBuffer holds a bitcode image, return a Module | ||||
/// for it. Otherwise, attempt to parse it as LLVM Assembly and return | ||||
/// a Module for it. This function *always* takes ownership of the given | ||||
/// MemoryBuffer. | ||||
inline Module *ParseIR(MemoryBuffer *Buffer, | ||||
SMDiagnostic &Err, | ||||
LLVMContext &Context) { | ||||
if (isBitcode((const unsigned char *)Buffer->getBufferStart(), | ||||
(const unsigned char *)Buffer->getBufferEnd())) { | ||||
std::string ErrMsg; | ||||
Module *M = ParseBitcodeFile(Buffer, Context, &ErrMsg); | ||||
if (M == 0) | ||||
Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Err | ||||
or, | ||||
ErrMsg); | ||||
// ParseBitcodeFile does not take ownership of the Buffer. | ||||
delete Buffer; | ||||
return M; | ||||
} | ||||
return ParseAssembly(Buffer, 0, Err, Context); | ||||
} | ||||
/// If the given file holds a bitcode image, return a Module for it. | ||||
/// Otherwise, attempt to parse it as LLVM Assembly and return a Module | ||||
/// for it. | ||||
inline Module *ParseIRFile(const std::string &Filename, | ||||
SMDiagnostic &Err, | ||||
LLVMContext &Context) { | ||||
OwningPtr<MemoryBuffer> File; | ||||
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File | ||||
)) { | ||||
Err = SMDiagnostic(Filename, SourceMgr::DK_Error, | ||||
"Could not open input file: " + ec.message()); | ||||
return 0; | ||||
} | ||||
return ParseIR(File.take(), Err, Context); | ||||
} | ||||
} | } | |||
#endif | #endif | |||
End of changes. 5 change blocks. | ||||
98 lines changed or deleted | 36 lines changed or added | |||
ISDOpcodes.h | ISDOpcodes.h | |||
---|---|---|---|---|
skipping to change at line 314 | skipping to change at line 314 | |||
MULHU, MULHS, | MULHU, MULHS, | |||
/// Bitwise operators - logical and, logical or, logical xor. | /// Bitwise operators - logical and, logical or, logical xor. | |||
AND, OR, XOR, | AND, OR, XOR, | |||
/// Shift and rotation operations. After legalization, the type of the | /// Shift and rotation operations. After legalization, the type of the | |||
/// shift amount is known to be TLI.getShiftAmountTy(). Before legaliz ation | /// shift amount is known to be TLI.getShiftAmountTy(). Before legaliz ation | |||
/// the shift amount can be any type, but care must be taken to ensure it is | /// the shift amount can be any type, but care must be taken to ensure it is | |||
/// large enough. TLI.getShiftAmountTy() is i8 on some targets, but be fore | /// large enough. TLI.getShiftAmountTy() is i8 on some targets, but be fore | |||
/// legalization, types like i1024 can occur and i8 doesn't have enough bits | /// legalization, types like i1024 can occur and i8 doesn't have enough bits | |||
/// to represent the shift amount. By convention, DAGCombine and | /// to represent the shift amount. | |||
/// SelectionDAGBuilder forces these shift amounts to i32 for simplicit | /// When the 1st operand is a vector, the shift amount must be in the s | |||
y. | ame | |||
/// type. (TLI.getShiftAmountTy() will return the same type when the in | ||||
put | ||||
/// type is a vector.) | ||||
SHL, SRA, SRL, ROTL, ROTR, | SHL, SRA, SRL, ROTL, ROTR, | |||
/// Byte Swap and Counting operators. | /// Byte Swap and Counting operators. | |||
BSWAP, CTTZ, CTLZ, CTPOP, | BSWAP, CTTZ, CTLZ, CTPOP, | |||
/// Bit counting operators with an undefined result for zero inputs. | /// Bit counting operators with an undefined result for zero inputs. | |||
CTTZ_ZERO_UNDEF, CTLZ_ZERO_UNDEF, | CTTZ_ZERO_UNDEF, CTLZ_ZERO_UNDEF, | |||
/// Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND i s not | /// Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND i s not | |||
/// i1 then the high bits must conform to getBooleanContents. | /// i1 then the high bits must conform to getBooleanContents. | |||
skipping to change at line 459 | skipping to change at line 461 | |||
FP16_TO_FP32, FP32_TO_FP16, | FP16_TO_FP32, FP32_TO_FP16, | |||
/// FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, | /// FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, | |||
/// FLOG, FLOG2, FLOG10, FEXP, FEXP2, | /// FLOG, FLOG2, FLOG10, FEXP, FEXP2, | |||
/// FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary | /// FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary | |||
/// floating point operations. These are inspired by libm. | /// floating point operations. These are inspired by libm. | |||
FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, | FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, | |||
FLOG, FLOG2, FLOG10, FEXP, FEXP2, | FLOG, FLOG2, FLOG10, FEXP, FEXP2, | |||
FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR, | FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR, | |||
/// FSINCOS - Compute both fsin and fcos as a single operation. | ||||
FSINCOS, | ||||
/// LOAD and STORE have token chains as their first operand, then the s ame | /// LOAD and STORE have token chains as their first operand, then the s ame | |||
/// operands as an LLVM load/store instruction, then an offset node tha t | /// operands as an LLVM load/store instruction, then an offset node tha t | |||
/// is added / subtracted from the base pointer to form the address (fo r | /// is added / subtracted from the base pointer to form the address (fo r | |||
/// indexed memory ops). | /// indexed memory ops). | |||
LOAD, STORE, | LOAD, STORE, | |||
/// DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack ali gned | /// DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack ali gned | |||
/// to a specified boundary. This node always has two return values: a new | /// to a specified boundary. This node always has two return values: a new | |||
/// stack pointer value and a chain. The first operand is the token cha in, | /// stack pointer value and a chain. The first operand is the token cha in, | |||
/// the second is the number of bytes to allocate, and the third is the | /// the second is the number of bytes to allocate, and the third is the | |||
skipping to change at line 600 | skipping to change at line 605 | |||
/// DEBUGTRAP - Trap intended to get the attention of a debugger. | /// DEBUGTRAP - Trap intended to get the attention of a debugger. | |||
DEBUGTRAP, | DEBUGTRAP, | |||
/// PREFETCH - This corresponds to a prefetch intrinsic. The first oper and | /// PREFETCH - This corresponds to a prefetch intrinsic. The first oper and | |||
/// is the chain. The other operands are the address to prefetch, | /// is the chain. The other operands are the address to prefetch, | |||
/// read / write specifier, locality specifier and instruction / data c ache | /// read / write specifier, locality specifier and instruction / data c ache | |||
/// specifier. | /// specifier. | |||
PREFETCH, | PREFETCH, | |||
/// OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load, | ||||
/// store-store, device) | ||||
/// This corresponds to the memory.barrier intrinsic. | ||||
/// it takes an input chain, 4 operands to specify the type of barrier, | ||||
an | ||||
/// operand specifying if the barrier applies to device and uncached me | ||||
mory | ||||
/// and produces an output chain. | ||||
MEMBARRIER, | ||||
/// OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) | /// OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) | |||
/// This corresponds to the fence instruction. It takes an input chain, and | /// This corresponds to the fence instruction. It takes an input chain, and | |||
/// two integer constants: an AtomicOrdering and a SynchronizationScope . | /// two integer constants: an AtomicOrdering and a SynchronizationScope . | |||
ATOMIC_FENCE, | ATOMIC_FENCE, | |||
/// Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) | /// Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) | |||
/// This corresponds to "load atomic" instruction. | /// This corresponds to "load atomic" instruction. | |||
ATOMIC_LOAD, | ATOMIC_LOAD, | |||
/// OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr, val) | /// OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr, val) | |||
End of changes. 3 change blocks. | ||||
13 lines changed or deleted | 9 lines changed or added | |||
IVUsers.h | IVUsers.h | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
#include "llvm/Analysis/LoopPass.h" | #include "llvm/Analysis/LoopPass.h" | |||
#include "llvm/Analysis/ScalarEvolutionNormalization.h" | #include "llvm/Analysis/ScalarEvolutionNormalization.h" | |||
#include "llvm/Support/ValueHandle.h" | #include "llvm/Support/ValueHandle.h" | |||
namespace llvm { | namespace llvm { | |||
class DominatorTree; | class DominatorTree; | |||
class Instruction; | class Instruction; | |||
class Value; | class Value; | |||
class IVUsers; | ||||
class ScalarEvolution; | class ScalarEvolution; | |||
class SCEV; | class SCEV; | |||
class IVUsers; | class IVUsers; | |||
class DataLayout; | class DataLayout; | |||
/// IVStrideUse - Keep track of one use of a strided induction variable. | /// IVStrideUse - Keep track of one use of a strided induction variable. | |||
/// The Expr member keeps track of the expression, User is the actual user | /// The Expr member keeps track of the expression, User is the actual user | |||
/// instruction of the operand, and 'OperandValToReplace' is the operand of | /// instruction of the operand, and 'OperandValToReplace' is the operand of | |||
/// the User that is the use. | /// the User that is the use. | |||
class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { | class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 0 lines changed or added | |||
ImmutableIntervalMap.h | ImmutableIntervalMap.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the ImmutableIntervalMap class. | // This file defines the ImmutableIntervalMap class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H | #ifndef LLVM_ADT_IMMUTABLEINTERVALMAP_H | |||
#define LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H | #define LLVM_ADT_IMMUTABLEINTERVALMAP_H | |||
#include "llvm/ADT/ImmutableMap.h" | #include "llvm/ADT/ImmutableMap.h" | |||
namespace llvm { | namespace llvm { | |||
class Interval { | class Interval { | |||
private: | private: | |||
int64_t Start; | int64_t Start; | |||
int64_t End; | int64_t End; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
ImmutableList.h | ImmutableList.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the ImmutableList class. | // This file defines the ImmutableList class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_IMLIST_H | #ifndef LLVM_ADT_IMMUTABLELIST_H | |||
#define LLVM_ADT_IMLIST_H | #define LLVM_ADT_IMMUTABLELIST_H | |||
#include "llvm/Support/Allocator.h" | ||||
#include "llvm/ADT/FoldingSet.h" | #include "llvm/ADT/FoldingSet.h" | |||
#include "llvm/Support/Allocator.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
template <typename T> class ImmutableListFactory; | template <typename T> class ImmutableListFactory; | |||
template <typename T> | template <typename T> | |||
class ImmutableListImpl : public FoldingSetNode { | class ImmutableListImpl : public FoldingSetNode { | |||
T Head; | T Head; | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
ImmutableMap.h | ImmutableMap.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the ImmutableMap class. | // This file defines the ImmutableMap class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_IMMAP_H | #ifndef LLVM_ADT_IMMUTABLEMAP_H | |||
#define LLVM_ADT_IMMAP_H | #define LLVM_ADT_IMMUTABLEMAP_H | |||
#include "llvm/ADT/ImmutableSet.h" | #include "llvm/ADT/ImmutableSet.h" | |||
namespace llvm { | namespace llvm { | |||
/// ImutKeyValueInfo -Traits class used by ImmutableMap. While both the fi rst | /// ImutKeyValueInfo -Traits class used by ImmutableMap. While both the fi rst | |||
/// and second elements in a pair are used to generate profile information, | /// and second elements in a pair are used to generate profile information, | |||
/// only the first element (the key) is used by isEqual and isLess. | /// only the first element (the key) is used by isEqual and isLess. | |||
template <typename T, typename S> | template <typename T, typename S> | |||
struct ImutKeyValueInfo { | struct ImutKeyValueInfo { | |||
skipping to change at line 213 | skipping to change at line 213 | |||
//===--------------------------------------------------===// | //===--------------------------------------------------===// | |||
class iterator { | class iterator { | |||
typename TreeTy::iterator itr; | typename TreeTy::iterator itr; | |||
iterator() {} | iterator() {} | |||
iterator(TreeTy* t) : itr(t) {} | iterator(TreeTy* t) : itr(t) {} | |||
friend class ImmutableMap; | friend class ImmutableMap; | |||
public: | public: | |||
value_type_ref operator*() const { return itr->getValue(); } | typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type value_type | |||
value_type* operator->() const { return &itr->getValue(); } | ; | |||
typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type_ref refere | ||||
nce; | ||||
typedef typename iterator::value_type *pointer; | ||||
typedef std::bidirectional_iterator_tag iterator_category; | ||||
typename iterator::reference operator*() const { return itr->getValue() | ||||
; } | ||||
typename iterator::pointer operator->() const { return &itr->getValue | ||||
(); } | ||||
key_type_ref getKey() const { return itr->getValue().first; } | key_type_ref getKey() const { return itr->getValue().first; } | |||
data_type_ref getData() const { return itr->getValue().second; } | data_type_ref getData() const { return itr->getValue().second; } | |||
iterator& operator++() { ++itr; return *this; } | iterator& operator++() { ++itr; return *this; } | |||
iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } | iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } | |||
iterator& operator--() { --itr; return *this; } | iterator& operator--() { --itr; return *this; } | |||
iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } | iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } | |||
bool operator==(const iterator& RHS) const { return RHS.itr == itr; } | bool operator==(const iterator& RHS) const { return RHS.itr == itr; } | |||
bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } | bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } | |||
}; | }; | |||
iterator begin() const { return iterator(Root); } | iterator begin() const { return iterator(Root); } | |||
iterator end() const { return iterator(); } | iterator end() const { return iterator(); } | |||
data_type* lookup(key_type_ref K) const { | data_type* lookup(key_type_ref K) const { | |||
if (Root) { | if (Root) { | |||
TreeTy* T = Root->find(K); | TreeTy* T = Root->find(K); | |||
skipping to change at line 290 | skipping to change at line 296 | |||
/// Constructs a map from a pointer to a tree root. In general one | /// Constructs a map from a pointer to a tree root. In general one | |||
/// should use a Factory object to create maps instead of directly | /// should use a Factory object to create maps instead of directly | |||
/// invoking the constructor, but there are cases where make this | /// invoking the constructor, but there are cases where make this | |||
/// constructor public is useful. | /// constructor public is useful. | |||
explicit ImmutableMapRef(const TreeTy* R, FactoryTy *F) | explicit ImmutableMapRef(const TreeTy* R, FactoryTy *F) | |||
: Root(const_cast<TreeTy*>(R)), | : Root(const_cast<TreeTy*>(R)), | |||
Factory(F) { | Factory(F) { | |||
if (Root) { Root->retain(); } | if (Root) { Root->retain(); } | |||
} | } | |||
explicit ImmutableMapRef(const ImmutableMap<KeyT, ValT> &X, | ||||
typename ImmutableMap<KeyT, ValT>::Factory &F) | ||||
: Root(X.getRootWithoutRetain()), | ||||
Factory(F.getTreeFactory()) { | ||||
if (Root) { Root->retain(); } | ||||
} | ||||
ImmutableMapRef(const ImmutableMapRef &X) | ImmutableMapRef(const ImmutableMapRef &X) | |||
: Root(X.Root), | : Root(X.Root), | |||
Factory(X.Factory) { | Factory(X.Factory) { | |||
if (Root) { Root->retain(); } | if (Root) { Root->retain(); } | |||
} | } | |||
ImmutableMapRef &operator=(const ImmutableMapRef &X) { | ImmutableMapRef &operator=(const ImmutableMapRef &X) { | |||
if (Root != X.Root) { | if (Root != X.Root) { | |||
if (X.Root) | if (X.Root) | |||
X.Root->retain(); | X.Root->retain(); | |||
skipping to change at line 319 | skipping to change at line 332 | |||
~ImmutableMapRef() { | ~ImmutableMapRef() { | |||
if (Root) | if (Root) | |||
Root->release(); | Root->release(); | |||
} | } | |||
static inline ImmutableMapRef getEmptyMap(FactoryTy *F) { | static inline ImmutableMapRef getEmptyMap(FactoryTy *F) { | |||
return ImmutableMapRef(0, F); | return ImmutableMapRef(0, F); | |||
} | } | |||
ImmutableMapRef add(key_type_ref K, data_type_ref D) { | void manualRetain() { | |||
if (Root) Root->retain(); | ||||
} | ||||
void manualRelease() { | ||||
if (Root) Root->release(); | ||||
} | ||||
ImmutableMapRef add(key_type_ref K, data_type_ref D) const { | ||||
TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D)) ; | TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D)) ; | |||
return ImmutableMapRef(NewT, Factory); | return ImmutableMapRef(NewT, Factory); | |||
} | } | |||
ImmutableMapRef remove(key_type_ref K) { | ImmutableMapRef remove(key_type_ref K) const { | |||
TreeTy *NewT = Factory->remove(Root, K); | TreeTy *NewT = Factory->remove(Root, K); | |||
return ImmutableMapRef(NewT, Factory); | return ImmutableMapRef(NewT, Factory); | |||
} | } | |||
bool contains(key_type_ref K) const { | bool contains(key_type_ref K) const { | |||
return Root ? Root->contains(K) : false; | return Root ? Root->contains(K) : false; | |||
} | } | |||
ImmutableMap<KeyT, ValT> asImmutableMap() const { | ImmutableMap<KeyT, ValT> asImmutableMap() const { | |||
return ImmutableMap<KeyT, ValT>(Factory->getCanonicalTree(Root)); | return ImmutableMap<KeyT, ValT>(Factory->getCanonicalTree(Root)); | |||
End of changes. 6 change blocks. | ||||
6 lines changed or deleted | 31 lines changed or added | |||
ImmutableSet.h | ImmutableSet.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the ImutAVLTree and ImmutableSet classes. | // This file defines the ImutAVLTree and ImmutableSet classes. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_IMSET_H | #ifndef LLVM_ADT_IMMUTABLESET_H | |||
#define LLVM_ADT_IMSET_H | #define LLVM_ADT_IMMUTABLESET_H | |||
#include "llvm/Support/Allocator.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/FoldingSet.h" | #include "llvm/ADT/FoldingSet.h" | |||
#include "llvm/Support/Allocator.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include <cassert> | #include <cassert> | |||
#include <functional> | #include <functional> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Immutable AVL-Tree Definition. | // Immutable AVL-Tree Definition. | |||
skipping to change at line 1054 | skipping to change at line 1054 | |||
template <typename Callback> | template <typename Callback> | |||
void foreach() { if (Root) { Callback C; Root->foreach(C); } } | void foreach() { if (Root) { Callback C; Root->foreach(C); } } | |||
//===--------------------------------------------------===// | //===--------------------------------------------------===// | |||
// Iterators. | // Iterators. | |||
//===--------------------------------------------------===// | //===--------------------------------------------------===// | |||
class iterator { | class iterator { | |||
typename TreeTy::iterator itr; | typename TreeTy::iterator itr; | |||
iterator() {} | ||||
iterator(TreeTy* t) : itr(t) {} | iterator(TreeTy* t) : itr(t) {} | |||
friend class ImmutableSet<ValT,ValInfo>; | friend class ImmutableSet<ValT,ValInfo>; | |||
public: | public: | |||
iterator() {} | typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type; | |||
inline value_type_ref operator*() const { return itr->getValue(); } | typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference; | |||
inline iterator& operator++() { ++itr; return *this; } | typedef typename iterator::value_type *pointer; | |||
inline iterator operator++(int) { iterator tmp(*this); ++itr; return t | typedef std::bidirectional_iterator_tag iterator_category; | |||
mp; } | ||||
inline iterator& operator--() { --itr; return *this; } | typename iterator::reference operator*() const { return itr->getValue() | |||
inline iterator operator--(int) { iterator tmp(*this); --itr; return t | ; } | |||
mp; } | typename iterator::pointer operator->() const { return &(operator*()) | |||
inline bool operator==(const iterator& RHS) const { return RHS.itr == i | ; } | |||
tr; } | ||||
inline bool operator!=(const iterator& RHS) const { return RHS.itr != i | iterator& operator++() { ++itr; return *this; } | |||
tr; } | iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } | |||
inline value_type *operator->() const { return &(operator*()); } | iterator& operator--() { --itr; return *this; } | |||
iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } | ||||
bool operator==(const iterator& RHS) const { return RHS.itr == itr; } | ||||
bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } | ||||
}; | }; | |||
iterator begin() const { return iterator(Root); } | iterator begin() const { return iterator(Root); } | |||
iterator end() const { return iterator(); } | iterator end() const { return iterator(); } | |||
//===--------------------------------------------------===// | //===--------------------------------------------------===// | |||
// Utility methods. | // Utility methods. | |||
//===--------------------------------------------------===// | //===--------------------------------------------------===// | |||
unsigned getHeight() const { return Root ? Root->getHeight() : 0; } | unsigned getHeight() const { return Root ? Root->getHeight() : 0; } | |||
End of changes. 6 change blocks. | ||||
16 lines changed or deleted | 23 lines changed or added | |||
IncludeFile.h | IncludeFile.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_F OR | // This file defines the FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_F OR | |||
// macros. | // macros. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_INCLUDEFILE_H | #ifndef LLVM_SUPPORT_INCLUDEFILE_H | |||
#define LLVM_SYSTEM_INCLUDEFILE_H | #define LLVM_SUPPORT_INCLUDEFILE_H | |||
/// This macro is the public interface that IncludeFile.h exports. This giv es | /// This macro is the public interface that IncludeFile.h exports. This giv es | |||
/// us the option to implement the "link the definition" capability in any | /// us the option to implement the "link the definition" capability in any | |||
/// manner that we choose. All header files that depend on a specific .cpp | /// manner that we choose. All header files that depend on a specific .cpp | |||
/// file being linked at run time should use this macro instead of the | /// file being linked at run time should use this macro instead of the | |||
/// IncludeFile class directly. | /// IncludeFile class directly. | |||
/// | /// | |||
/// For example, foo.h would use:<br/> | /// For example, foo.h would use:<br/> | |||
/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/> | /// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/> | |||
/// | /// | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Initialization.h | Initialization.h | |||
---|---|---|---|---|
skipping to change at line 37 | skipping to change at line 37 | |||
* @ingroup LLVMC | * @ingroup LLVMC | |||
* | * | |||
* This module contains routines used to initialize the LLVM system. | * This module contains routines used to initialize the LLVM system. | |||
* | * | |||
* @{ | * @{ | |||
*/ | */ | |||
void LLVMInitializeCore(LLVMPassRegistryRef R); | void LLVMInitializeCore(LLVMPassRegistryRef R); | |||
void LLVMInitializeTransformUtils(LLVMPassRegistryRef R); | void LLVMInitializeTransformUtils(LLVMPassRegistryRef R); | |||
void LLVMInitializeScalarOpts(LLVMPassRegistryRef R); | void LLVMInitializeScalarOpts(LLVMPassRegistryRef R); | |||
void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R); | ||||
void LLVMInitializeVectorization(LLVMPassRegistryRef R); | void LLVMInitializeVectorization(LLVMPassRegistryRef R); | |||
void LLVMInitializeInstCombine(LLVMPassRegistryRef R); | void LLVMInitializeInstCombine(LLVMPassRegistryRef R); | |||
void LLVMInitializeIPO(LLVMPassRegistryRef R); | void LLVMInitializeIPO(LLVMPassRegistryRef R); | |||
void LLVMInitializeInstrumentation(LLVMPassRegistryRef R); | void LLVMInitializeInstrumentation(LLVMPassRegistryRef R); | |||
void LLVMInitializeAnalysis(LLVMPassRegistryRef R); | void LLVMInitializeAnalysis(LLVMPassRegistryRef R); | |||
void LLVMInitializeIPA(LLVMPassRegistryRef R); | void LLVMInitializeIPA(LLVMPassRegistryRef R); | |||
void LLVMInitializeCodeGen(LLVMPassRegistryRef R); | void LLVMInitializeCodeGen(LLVMPassRegistryRef R); | |||
void LLVMInitializeTarget(LLVMPassRegistryRef R); | void LLVMInitializeTarget(LLVMPassRegistryRef R); | |||
/** | /** | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 1 lines changed or added | |||
InitializePasses.h | InitializePasses.h | |||
---|---|---|---|---|
skipping to change at line 34 | skipping to change at line 34 | |||
void initializeCore(PassRegistry&); | void initializeCore(PassRegistry&); | |||
/// initializeTransformUtils - Initialize all passes linked into the | /// initializeTransformUtils - Initialize all passes linked into the | |||
/// TransformUtils library. | /// TransformUtils library. | |||
void initializeTransformUtils(PassRegistry&); | void initializeTransformUtils(PassRegistry&); | |||
/// initializeScalarOpts - Initialize all passes linked into the | /// initializeScalarOpts - Initialize all passes linked into the | |||
/// ScalarOpts library. | /// ScalarOpts library. | |||
void initializeScalarOpts(PassRegistry&); | void initializeScalarOpts(PassRegistry&); | |||
/// initializeObjCARCOpts - Initialize all passes linked into the ObjCARCOp | ||||
ts | ||||
/// library. | ||||
void initializeObjCARCOpts(PassRegistry&); | ||||
/// initializeVectorization - Initialize all passes linked into the | /// initializeVectorization - Initialize all passes linked into the | |||
/// Vectorize library. | /// Vectorize library. | |||
void initializeVectorization(PassRegistry&); | void initializeVectorization(PassRegistry&); | |||
/// initializeInstCombine - Initialize all passes linked into the | /// initializeInstCombine - Initialize all passes linked into the | |||
/// ScalarOpts library. | /// ScalarOpts library. | |||
void initializeInstCombine(PassRegistry&); | void initializeInstCombine(PassRegistry&); | |||
/// initializeIPO - Initialize all passes linked into the IPO library. | /// initializeIPO - Initialize all passes linked into the IPO library. | |||
void initializeIPO(PassRegistry&); | void initializeIPO(PassRegistry&); | |||
skipping to change at line 72 | skipping to change at line 76 | |||
void initializeADCEPass(PassRegistry&); | void initializeADCEPass(PassRegistry&); | |||
void initializeAliasAnalysisAnalysisGroup(PassRegistry&); | void initializeAliasAnalysisAnalysisGroup(PassRegistry&); | |||
void initializeAliasAnalysisCounterPass(PassRegistry&); | void initializeAliasAnalysisCounterPass(PassRegistry&); | |||
void initializeAliasDebuggerPass(PassRegistry&); | void initializeAliasDebuggerPass(PassRegistry&); | |||
void initializeAliasSetPrinterPass(PassRegistry&); | void initializeAliasSetPrinterPass(PassRegistry&); | |||
void initializeAlwaysInlinerPass(PassRegistry&); | void initializeAlwaysInlinerPass(PassRegistry&); | |||
void initializeArgPromotionPass(PassRegistry&); | void initializeArgPromotionPass(PassRegistry&); | |||
void initializeBarrierNoopPass(PassRegistry&); | void initializeBarrierNoopPass(PassRegistry&); | |||
void initializeBasicAliasAnalysisPass(PassRegistry&); | void initializeBasicAliasAnalysisPass(PassRegistry&); | |||
void initializeBasicCallGraphPass(PassRegistry&); | void initializeBasicCallGraphPass(PassRegistry&); | |||
void initializeBasicTTIPass(PassRegistry&); | ||||
void initializeBlockExtractorPassPass(PassRegistry&); | void initializeBlockExtractorPassPass(PassRegistry&); | |||
void initializeBlockFrequencyInfoPass(PassRegistry&); | void initializeBlockFrequencyInfoPass(PassRegistry&); | |||
void initializeBlockPlacementPass(PassRegistry&); | void initializeBlockPlacementPass(PassRegistry&); | |||
void initializeBoundsCheckingPass(PassRegistry&); | void initializeBoundsCheckingPass(PassRegistry&); | |||
void initializeBranchFolderPassPass(PassRegistry&); | void initializeBranchFolderPassPass(PassRegistry&); | |||
void initializeBranchProbabilityInfoPass(PassRegistry&); | void initializeBranchProbabilityInfoPass(PassRegistry&); | |||
void initializeBreakCriticalEdgesPass(PassRegistry&); | void initializeBreakCriticalEdgesPass(PassRegistry&); | |||
void initializeCallGraphPrinterPass(PassRegistry&); | ||||
void initializeCallGraphViewerPass(PassRegistry&); | ||||
void initializeCFGOnlyPrinterPass(PassRegistry&); | void initializeCFGOnlyPrinterPass(PassRegistry&); | |||
void initializeCFGOnlyViewerPass(PassRegistry&); | void initializeCFGOnlyViewerPass(PassRegistry&); | |||
void initializeCFGPrinterPass(PassRegistry&); | void initializeCFGPrinterPass(PassRegistry&); | |||
void initializeCFGSimplifyPassPass(PassRegistry&); | void initializeCFGSimplifyPassPass(PassRegistry&); | |||
void initializeCFGViewerPass(PassRegistry&); | void initializeCFGViewerPass(PassRegistry&); | |||
void initializeCalculateSpillWeightsPass(PassRegistry&); | void initializeCalculateSpillWeightsPass(PassRegistry&); | |||
void initializeCallGraphAnalysisGroup(PassRegistry&); | void initializeCallGraphAnalysisGroup(PassRegistry&); | |||
void initializeCodeGenPreparePass(PassRegistry&); | void initializeCodeGenPreparePass(PassRegistry&); | |||
void initializeCodePlacementOptPass(PassRegistry&); | ||||
void initializeConstantMergePass(PassRegistry&); | void initializeConstantMergePass(PassRegistry&); | |||
void initializeConstantPropagationPass(PassRegistry&); | void initializeConstantPropagationPass(PassRegistry&); | |||
void initializeMachineCopyPropagationPass(PassRegistry&); | void initializeMachineCopyPropagationPass(PassRegistry&); | |||
void initializeCostModelAnalysisPass(PassRegistry&); | void initializeCostModelAnalysisPass(PassRegistry&); | |||
void initializeCorrelatedValuePropagationPass(PassRegistry&); | void initializeCorrelatedValuePropagationPass(PassRegistry&); | |||
void initializeDAEPass(PassRegistry&); | void initializeDAEPass(PassRegistry&); | |||
void initializeDAHPass(PassRegistry&); | void initializeDAHPass(PassRegistry&); | |||
void initializeDCEPass(PassRegistry&); | void initializeDCEPass(PassRegistry&); | |||
void initializeDSEPass(PassRegistry&); | void initializeDSEPass(PassRegistry&); | |||
void initializeDeadInstEliminationPass(PassRegistry&); | void initializeDeadInstEliminationPass(PassRegistry&); | |||
skipping to change at line 113 | skipping to change at line 119 | |||
void initializeDomViewerPass(PassRegistry&); | void initializeDomViewerPass(PassRegistry&); | |||
void initializeDominanceFrontierPass(PassRegistry&); | void initializeDominanceFrontierPass(PassRegistry&); | |||
void initializeDominatorTreePass(PassRegistry&); | void initializeDominatorTreePass(PassRegistry&); | |||
void initializeEarlyIfConverterPass(PassRegistry&); | void initializeEarlyIfConverterPass(PassRegistry&); | |||
void initializeEdgeBundlesPass(PassRegistry&); | void initializeEdgeBundlesPass(PassRegistry&); | |||
void initializeEdgeProfilerPass(PassRegistry&); | void initializeEdgeProfilerPass(PassRegistry&); | |||
void initializeExpandPostRAPass(PassRegistry&); | void initializeExpandPostRAPass(PassRegistry&); | |||
void initializePathProfilerPass(PassRegistry&); | void initializePathProfilerPass(PassRegistry&); | |||
void initializeGCOVProfilerPass(PassRegistry&); | void initializeGCOVProfilerPass(PassRegistry&); | |||
void initializeAddressSanitizerPass(PassRegistry&); | void initializeAddressSanitizerPass(PassRegistry&); | |||
void initializeAddressSanitizerModulePass(PassRegistry&); | ||||
void initializeMemorySanitizerPass(PassRegistry&); | ||||
void initializeThreadSanitizerPass(PassRegistry&); | void initializeThreadSanitizerPass(PassRegistry&); | |||
void initializeEarlyCSEPass(PassRegistry&); | void initializeEarlyCSEPass(PassRegistry&); | |||
void initializeExpandISelPseudosPass(PassRegistry&); | void initializeExpandISelPseudosPass(PassRegistry&); | |||
void initializeFindUsedTypesPass(PassRegistry&); | void initializeFindUsedTypesPass(PassRegistry&); | |||
void initializeFunctionAttrsPass(PassRegistry&); | void initializeFunctionAttrsPass(PassRegistry&); | |||
void initializeGCInfoDeleterPass(PassRegistry&); | ||||
void initializeGCMachineCodeAnalysisPass(PassRegistry&); | void initializeGCMachineCodeAnalysisPass(PassRegistry&); | |||
void initializeGCModuleInfoPass(PassRegistry&); | void initializeGCModuleInfoPass(PassRegistry&); | |||
void initializeGVNPass(PassRegistry&); | void initializeGVNPass(PassRegistry&); | |||
void initializeGlobalDCEPass(PassRegistry&); | void initializeGlobalDCEPass(PassRegistry&); | |||
void initializeGlobalOptPass(PassRegistry&); | void initializeGlobalOptPass(PassRegistry&); | |||
void initializeGlobalsModRefPass(PassRegistry&); | void initializeGlobalsModRefPass(PassRegistry&); | |||
void initializeIPCPPass(PassRegistry&); | void initializeIPCPPass(PassRegistry&); | |||
void initializeIPSCCPPass(PassRegistry&); | void initializeIPSCCPPass(PassRegistry&); | |||
void initializeIVUsersPass(PassRegistry&); | void initializeIVUsersPass(PassRegistry&); | |||
void initializeIfConverterPass(PassRegistry&); | void initializeIfConverterPass(PassRegistry&); | |||
void initializeIndVarSimplifyPass(PassRegistry&); | void initializeIndVarSimplifyPass(PassRegistry&); | |||
void initializeInlineCostAnalysisPass(PassRegistry&); | ||||
void initializeInstCombinerPass(PassRegistry&); | void initializeInstCombinerPass(PassRegistry&); | |||
void initializeInstCountPass(PassRegistry&); | void initializeInstCountPass(PassRegistry&); | |||
void initializeInstNamerPass(PassRegistry&); | void initializeInstNamerPass(PassRegistry&); | |||
void initializeInternalizePassPass(PassRegistry&); | void initializeInternalizePassPass(PassRegistry&); | |||
void initializeIntervalPartitionPass(PassRegistry&); | void initializeIntervalPartitionPass(PassRegistry&); | |||
void initializeJumpThreadingPass(PassRegistry&); | void initializeJumpThreadingPass(PassRegistry&); | |||
void initializeLCSSAPass(PassRegistry&); | void initializeLCSSAPass(PassRegistry&); | |||
void initializeLICMPass(PassRegistry&); | void initializeLICMPass(PassRegistry&); | |||
void initializeLazyValueInfoPass(PassRegistry&); | void initializeLazyValueInfoPass(PassRegistry&); | |||
void initializeLibCallAliasAnalysisPass(PassRegistry&); | void initializeLibCallAliasAnalysisPass(PassRegistry&); | |||
skipping to change at line 175 | skipping to change at line 183 | |||
void initializeLowerSwitchPass(PassRegistry&); | void initializeLowerSwitchPass(PassRegistry&); | |||
void initializeMachineBlockFrequencyInfoPass(PassRegistry&); | void initializeMachineBlockFrequencyInfoPass(PassRegistry&); | |||
void initializeMachineBlockPlacementPass(PassRegistry&); | void initializeMachineBlockPlacementPass(PassRegistry&); | |||
void initializeMachineBlockPlacementStatsPass(PassRegistry&); | void initializeMachineBlockPlacementStatsPass(PassRegistry&); | |||
void initializeMachineBranchProbabilityInfoPass(PassRegistry&); | void initializeMachineBranchProbabilityInfoPass(PassRegistry&); | |||
void initializeMachineCSEPass(PassRegistry&); | void initializeMachineCSEPass(PassRegistry&); | |||
void initializeMachineDominatorTreePass(PassRegistry&); | void initializeMachineDominatorTreePass(PassRegistry&); | |||
void initializeMachinePostDominatorTreePass(PassRegistry&); | void initializeMachinePostDominatorTreePass(PassRegistry&); | |||
void initializeMachineLICMPass(PassRegistry&); | void initializeMachineLICMPass(PassRegistry&); | |||
void initializeMachineLoopInfoPass(PassRegistry&); | void initializeMachineLoopInfoPass(PassRegistry&); | |||
void initializeMachineLoopRangesPass(PassRegistry&); | ||||
void initializeMachineModuleInfoPass(PassRegistry&); | void initializeMachineModuleInfoPass(PassRegistry&); | |||
void initializeMachineSchedulerPass(PassRegistry&); | void initializeMachineSchedulerPass(PassRegistry&); | |||
void initializeMachineSinkingPass(PassRegistry&); | void initializeMachineSinkingPass(PassRegistry&); | |||
void initializeMachineTraceMetricsPass(PassRegistry&); | void initializeMachineTraceMetricsPass(PassRegistry&); | |||
void initializeMachineVerifierPassPass(PassRegistry&); | void initializeMachineVerifierPassPass(PassRegistry&); | |||
void initializeMemCpyOptPass(PassRegistry&); | void initializeMemCpyOptPass(PassRegistry&); | |||
void initializeMemDepPrinterPass(PassRegistry&); | void initializeMemDepPrinterPass(PassRegistry&); | |||
void initializeMemoryDependenceAnalysisPass(PassRegistry&); | void initializeMemoryDependenceAnalysisPass(PassRegistry&); | |||
void initializeMetaRenamerPass(PassRegistry&); | void initializeMetaRenamerPass(PassRegistry&); | |||
void initializeMergeFunctionsPass(PassRegistry&); | void initializeMergeFunctionsPass(PassRegistry&); | |||
skipping to change at line 208 | skipping to change at line 215 | |||
void initializePHIEliminationPass(PassRegistry&); | void initializePHIEliminationPass(PassRegistry&); | |||
void initializePartialInlinerPass(PassRegistry&); | void initializePartialInlinerPass(PassRegistry&); | |||
void initializePeepholeOptimizerPass(PassRegistry&); | void initializePeepholeOptimizerPass(PassRegistry&); | |||
void initializePostDomOnlyPrinterPass(PassRegistry&); | void initializePostDomOnlyPrinterPass(PassRegistry&); | |||
void initializePostDomOnlyViewerPass(PassRegistry&); | void initializePostDomOnlyViewerPass(PassRegistry&); | |||
void initializePostDomPrinterPass(PassRegistry&); | void initializePostDomPrinterPass(PassRegistry&); | |||
void initializePostDomViewerPass(PassRegistry&); | void initializePostDomViewerPass(PassRegistry&); | |||
void initializePostDominatorTreePass(PassRegistry&); | void initializePostDominatorTreePass(PassRegistry&); | |||
void initializePostRASchedulerPass(PassRegistry&); | void initializePostRASchedulerPass(PassRegistry&); | |||
void initializePreVerifierPass(PassRegistry&); | void initializePreVerifierPass(PassRegistry&); | |||
void initializePrintDbgInfoPass(PassRegistry&); | ||||
void initializePrintFunctionPassPass(PassRegistry&); | void initializePrintFunctionPassPass(PassRegistry&); | |||
void initializePrintModulePassPass(PassRegistry&); | void initializePrintModulePassPass(PassRegistry&); | |||
void initializePrintBasicBlockPassPass(PassRegistry&); | ||||
void initializeProcessImplicitDefsPass(PassRegistry&); | void initializeProcessImplicitDefsPass(PassRegistry&); | |||
void initializeProfileEstimatorPassPass(PassRegistry&); | void initializeProfileEstimatorPassPass(PassRegistry&); | |||
void initializeProfileInfoAnalysisGroup(PassRegistry&); | void initializeProfileInfoAnalysisGroup(PassRegistry&); | |||
void initializePathProfileInfoAnalysisGroup(PassRegistry&); | void initializePathProfileInfoAnalysisGroup(PassRegistry&); | |||
void initializePathProfileVerifierPass(PassRegistry&); | void initializePathProfileVerifierPass(PassRegistry&); | |||
void initializeProfileVerifierPassPass(PassRegistry&); | void initializeProfileVerifierPassPass(PassRegistry&); | |||
void initializePromotePassPass(PassRegistry&); | void initializePromotePassPass(PassRegistry&); | |||
void initializePruneEHPass(PassRegistry&); | void initializePruneEHPass(PassRegistry&); | |||
void initializeReassociatePass(PassRegistry&); | void initializeReassociatePass(PassRegistry&); | |||
void initializeRegToMemPass(PassRegistry&); | void initializeRegToMemPass(PassRegistry&); | |||
skipping to change at line 252 | skipping to change at line 259 | |||
void initializeStripDeadDebugInfoPass(PassRegistry&); | void initializeStripDeadDebugInfoPass(PassRegistry&); | |||
void initializeStripDeadPrototypesPassPass(PassRegistry&); | void initializeStripDeadPrototypesPassPass(PassRegistry&); | |||
void initializeStripDebugDeclarePass(PassRegistry&); | void initializeStripDebugDeclarePass(PassRegistry&); | |||
void initializeStripNonDebugSymbolsPass(PassRegistry&); | void initializeStripNonDebugSymbolsPass(PassRegistry&); | |||
void initializeStripSymbolsPass(PassRegistry&); | void initializeStripSymbolsPass(PassRegistry&); | |||
void initializeStrongPHIEliminationPass(PassRegistry&); | void initializeStrongPHIEliminationPass(PassRegistry&); | |||
void initializeTailCallElimPass(PassRegistry&); | void initializeTailCallElimPass(PassRegistry&); | |||
void initializeTailDuplicatePassPass(PassRegistry&); | void initializeTailDuplicatePassPass(PassRegistry&); | |||
void initializeTargetPassConfigPass(PassRegistry&); | void initializeTargetPassConfigPass(PassRegistry&); | |||
void initializeDataLayoutPass(PassRegistry&); | void initializeDataLayoutPass(PassRegistry&); | |||
void initializeTargetTransformInfoPass(PassRegistry&); | void initializeTargetTransformInfoAnalysisGroup(PassRegistry&); | |||
void initializeNoTTIPass(PassRegistry&); | ||||
void initializeTargetLibraryInfoPass(PassRegistry&); | void initializeTargetLibraryInfoPass(PassRegistry&); | |||
void initializeTwoAddressInstructionPassPass(PassRegistry&); | void initializeTwoAddressInstructionPassPass(PassRegistry&); | |||
void initializeTypeBasedAliasAnalysisPass(PassRegistry&); | void initializeTypeBasedAliasAnalysisPass(PassRegistry&); | |||
void initializeUnifyFunctionExitNodesPass(PassRegistry&); | void initializeUnifyFunctionExitNodesPass(PassRegistry&); | |||
void initializeUnreachableBlockElimPass(PassRegistry&); | void initializeUnreachableBlockElimPass(PassRegistry&); | |||
void initializeUnreachableMachineBlockElimPass(PassRegistry&); | void initializeUnreachableMachineBlockElimPass(PassRegistry&); | |||
void initializeVerifierPass(PassRegistry&); | void initializeVerifierPass(PassRegistry&); | |||
void initializeVirtRegMapPass(PassRegistry&); | void initializeVirtRegMapPass(PassRegistry&); | |||
void initializeVirtRegRewriterPass(PassRegistry&); | void initializeVirtRegRewriterPass(PassRegistry&); | |||
void initializeInstSimplifierPass(PassRegistry&); | void initializeInstSimplifierPass(PassRegistry&); | |||
void initializeUnpackMachineBundlesPass(PassRegistry&); | void initializeUnpackMachineBundlesPass(PassRegistry&); | |||
void initializeFinalizeMachineBundlesPass(PassRegistry&); | void initializeFinalizeMachineBundlesPass(PassRegistry&); | |||
void initializeLoopVectorizePass(PassRegistry&); | void initializeLoopVectorizePass(PassRegistry&); | |||
void initializeSLPVectorizerPass(PassRegistry&); | ||||
void initializeBBVectorizePass(PassRegistry&); | void initializeBBVectorizePass(PassRegistry&); | |||
void initializeMachineFunctionPrinterPassPass(PassRegistry&); | void initializeMachineFunctionPrinterPassPass(PassRegistry&); | |||
} | } | |||
#endif | #endif | |||
End of changes. 12 change blocks. | ||||
5 lines changed or deleted | 15 lines changed or added | |||
InlineAsm.h | InlineAsm.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This class represents the inline asm strings, which are Value*'s that ar e | // This class represents the inline asm strings, which are Value*'s that ar e | |||
// used as the callee operand of call instructions. InlineAsm's are unique d | // used as the callee operand of call instructions. InlineAsm's are unique d | |||
// like constants, and created via InlineAsm::get(...). | // like constants, and created via InlineAsm::get(...). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_INLINEASM_H | #ifndef LLVM_IR_INLINEASM_H | |||
#define LLVM_INLINEASM_H | #define LLVM_IR_INLINEASM_H | |||
#include "llvm/Value.h" | ||||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/IR/Value.h" | ||||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class PointerType; | class PointerType; | |||
class FunctionType; | class FunctionType; | |||
class Module; | class Module; | |||
struct InlineAsmKeyType; | struct InlineAsmKeyType; | |||
template<class ValType, class ValRefType, class TypeClass, class ConstantCl ass, | template<class ValType, class ValRefType, class TypeClass, class ConstantCl ass, | |||
bool HasLargeKey> | bool HasLargeKey> | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
InlineCost.h | InlineCost.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements heuristics for inlining decisions. | // This file implements heuristics for inlining decisions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_INLINECOST_H | #ifndef LLVM_ANALYSIS_INLINECOST_H | |||
#define LLVM_ANALYSIS_INLINECOST_H | #define LLVM_ANALYSIS_INLINECOST_H | |||
#include "llvm/Function.h" | ||||
#include "llvm/ADT/DenseMap.h" | ||||
#include "llvm/ADT/SmallPtrSet.h" | ||||
#include "llvm/ADT/ValueMap.h" | ||||
#include "llvm/Analysis/CodeMetrics.h" | #include "llvm/Analysis/CodeMetrics.h" | |||
#include "llvm/Analysis/CallGraphSCCPass.h" | ||||
#include <cassert> | #include <cassert> | |||
#include <climits> | #include <climits> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
class CallSite; | ||||
class DataLayout; | ||||
class Function; | ||||
class TargetTransformInfo; | ||||
namespace InlineConstants { | ||||
// Various magic constants used to adjust heuristics. | ||||
const int InstrCost = 5; | ||||
const int IndirectCallThreshold = 100; | ||||
const int CallPenalty = 25; | ||||
const int LastCallToStaticBonus = -15000; | ||||
const int ColdccPenalty = 2000; | ||||
const int NoreturnPenalty = 10000; | ||||
/// Do not inline functions which allocate this many bytes on the stack | ||||
/// when the caller is recursive. | ||||
const unsigned TotalAllocaSizeRecursiveCaller = 1024; | ||||
} | ||||
/// \brief Represents the cost of inlining a function. | ||||
/// | ||||
/// This supports special values for functions which should "always" or | ||||
/// "never" be inlined. Otherwise, the cost represents a unitless amount; | ||||
/// smaller values increase the likelihood of the function being inlined. | ||||
/// | ||||
/// Objects of this type also provide the adjusted threshold for inlining | ||||
/// based on the information available for a particular callsite. They can | ||||
be | ||||
/// directly tested to determine if inlining should occur given the cost an | ||||
d | ||||
/// threshold for this cost metric. | ||||
class InlineCost { | ||||
enum SentinelValues { | ||||
AlwaysInlineCost = INT_MIN, | ||||
NeverInlineCost = INT_MAX | ||||
}; | ||||
/// \brief The estimated cost of inlining this callsite. | ||||
const int Cost; | ||||
/// \brief The adjusted threshold against which this cost was computed. | ||||
const int Threshold; | ||||
// Trivial constructor, interesting logic in the factory functions below. | ||||
InlineCost(int Cost, int Threshold) : Cost(Cost), Threshold(Threshold) {} | ||||
public: | ||||
static InlineCost get(int Cost, int Threshold) { | ||||
assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value"); | ||||
assert(Cost < NeverInlineCost && "Cost crosses sentinel value"); | ||||
return InlineCost(Cost, Threshold); | ||||
} | ||||
static InlineCost getAlways() { | ||||
return InlineCost(AlwaysInlineCost, 0); | ||||
} | ||||
static InlineCost getNever() { | ||||
return InlineCost(NeverInlineCost, 0); | ||||
} | ||||
class CallSite; | /// \brief Test whether the inline cost is low enough for inlining. | |||
class DataLayout; | operator bool() const { | |||
return Cost < Threshold; | ||||
} | ||||
namespace InlineConstants { | bool isAlways() const { return Cost == AlwaysInlineCost; } | |||
// Various magic constants used to adjust heuristics. | bool isNever() const { return Cost == NeverInlineCost; } | |||
const int InstrCost = 5; | bool isVariable() const { return !isAlways() && !isNever(); } | |||
const int IndirectCallThreshold = 100; | ||||
const int CallPenalty = 25; | /// \brief Get the inline cost estimate. | |||
const int LastCallToStaticBonus = -15000; | /// It is an error to call this on an "always" or "never" InlineCost. | |||
const int ColdccPenalty = 2000; | int getCost() const { | |||
const int NoreturnPenalty = 10000; | assert(isVariable() && "Invalid access of InlineCost"); | |||
/// Do not inline functions which allocate this many bytes on the stack | return Cost; | |||
/// when the caller is recursive. | ||||
const unsigned TotalAllocaSizeRecursiveCaller = 1024; | ||||
} | } | |||
/// \brief Represents the cost of inlining a function. | /// \brief Get the cost delta from the threshold for inlining. | |||
/// Only valid if the cost is of the variable kind. Returns a negative | ||||
/// value if the cost is too high to inline. | ||||
int getCostDelta() const { return Threshold - getCost(); } | ||||
}; | ||||
/// \brief Cost analyzer used by inliner. | ||||
class InlineCostAnalysis : public CallGraphSCCPass { | ||||
const DataLayout *TD; | ||||
const TargetTransformInfo *TTI; | ||||
public: | ||||
static char ID; | ||||
InlineCostAnalysis(); | ||||
~InlineCostAnalysis(); | ||||
// Pass interface implementation. | ||||
void getAnalysisUsage(AnalysisUsage &AU) const; | ||||
bool runOnSCC(CallGraphSCC &SCC); | ||||
/// \brief Get an InlineCost object representing the cost of inlining thi | ||||
s | ||||
/// callsite. | ||||
/// | /// | |||
/// This supports special values for functions which should "always" or | /// Note that threshold is passed into this function. Only costs below th | |||
/// "never" be inlined. Otherwise, the cost represents a unitless amount; | e | |||
/// smaller values increase the likelihood of the function being inlined. | /// threshold are computed with any accuracy. The threshold can be used t | |||
o | ||||
/// bound the computation necessary to determine whether the cost is | ||||
/// sufficiently low to warrant inlining. | ||||
/// | /// | |||
/// Objects of this type also provide the adjusted threshold for inlining | /// Also note that calling this function *dynamically* computes the cost | |||
/// based on the information available for a particular callsite. They ca | of | |||
n be | /// inlining the callsite. It is an expensive, heavyweight call. | |||
/// directly tested to determine if inlining should occur given the cost | InlineCost getInlineCost(CallSite CS, int Threshold); | |||
and | ||||
/// threshold for this cost metric. | /// \brief Get an InlineCost with the callee explicitly specified. | |||
class InlineCost { | /// This allows you to calculate the cost of inlining a function via a | |||
enum SentinelValues { | /// pointer. This behaves exactly as the version with no explicit callee | |||
AlwaysInlineCost = INT_MIN, | /// parameter in all other respects. | |||
NeverInlineCost = INT_MAX | // | |||
}; | // Note: This is used by out-of-tree passes, please do not remove withou | |||
t | ||||
/// \brief The estimated cost of inlining this callsite. | // adding a replacement API. | |||
const int Cost; | InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold); | |||
/// \brief The adjusted threshold against which this cost was computed. | /// \brief Minimal filter to detect invalid constructs for inlining. | |||
const int Threshold; | bool isInlineViable(Function &Callee); | |||
}; | ||||
// Trivial constructor, interesting logic in the factory functions belo | ||||
w. | ||||
InlineCost(int Cost, int Threshold) | ||||
: Cost(Cost), Threshold(Threshold) {} | ||||
public: | ||||
static InlineCost get(int Cost, int Threshold) { | ||||
assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value"); | ||||
assert(Cost < NeverInlineCost && "Cost crosses sentinel value"); | ||||
return InlineCost(Cost, Threshold); | ||||
} | ||||
static InlineCost getAlways() { | ||||
return InlineCost(AlwaysInlineCost, 0); | ||||
} | ||||
static InlineCost getNever() { | ||||
return InlineCost(NeverInlineCost, 0); | ||||
} | ||||
/// \brief Test whether the inline cost is low enough for inlining. | ||||
operator bool() const { | ||||
return Cost < Threshold; | ||||
} | ||||
bool isAlways() const { return Cost == AlwaysInlineCost; } | ||||
bool isNever() const { return Cost == NeverInlineCost; } | ||||
bool isVariable() const { return !isAlways() && !isNever(); } | ||||
/// \brief Get the inline cost estimate. | ||||
/// It is an error to call this on an "always" or "never" InlineCost. | ||||
int getCost() const { | ||||
assert(isVariable() && "Invalid access of InlineCost"); | ||||
return Cost; | ||||
} | ||||
/// \brief Get the cost delta from the threshold for inlining. | ||||
/// Only valid if the cost is of the variable kind. Returns a negative | ||||
/// value if the cost is too high to inline. | ||||
int getCostDelta() const { return Threshold - getCost(); } | ||||
}; | ||||
/// InlineCostAnalyzer - Cost analyzer used by inliner. | ||||
class InlineCostAnalyzer { | ||||
// DataLayout if available, or null. | ||||
const DataLayout *TD; | ||||
public: | ||||
InlineCostAnalyzer(): TD(0) {} | ||||
void setDataLayout(const DataLayout *TData) { TD = TData; } | ||||
/// \brief Get an InlineCost object representing the cost of inlining t | ||||
his | ||||
/// callsite. | ||||
/// | ||||
/// Note that threshold is passed into this function. Only costs below | ||||
the | ||||
/// threshold are computed with any accuracy. The threshold can be used | ||||
to | ||||
/// bound the computation necessary to determine whether the cost is | ||||
/// sufficiently low to warrant inlining. | ||||
InlineCost getInlineCost(CallSite CS, int Threshold); | ||||
/// getCalledFunction - The heuristic used to determine if we should in | ||||
line | ||||
/// the function call or not. The callee is explicitly specified, to a | ||||
llow | ||||
/// you to calculate the cost of inlining a function via a pointer. Th | ||||
is | ||||
/// behaves exactly as the version with no explicit callee parameter in | ||||
all | ||||
/// other respects. | ||||
// | ||||
// Note: This is used by out-of-tree passes, please do not remove with | ||||
out | ||||
// adding a replacement API. | ||||
InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold); | ||||
}; | ||||
} | } | |||
#endif | #endif | |||
End of changes. 10 change blocks. | ||||
115 lines changed or deleted | 119 lines changed or added | |||
InlinerPass.h | InlinerPass.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file defines a simple policy-based bottom-up inliner. This file | // This file defines a simple policy-based bottom-up inliner. This file | |||
// implements all of the boring mechanics of the bottom-up inlining, while the | // implements all of the boring mechanics of the bottom-up inlining, while the | |||
// subclass determines WHAT to inline, which is the much more interesting | // subclass determines WHAT to inline, which is the much more interesting | |||
// component. | // component. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_IPO_INLINERPASS_H | #ifndef LLVM_TRANSFORMS_IPO_INLINERPASS_H | |||
#define LLVM_TRANSFORMS_IPO_INLINERPASS_H | #define LLVM_TRANSFORMS_IPO_INLINERPASS_H | |||
#include "llvm/CallGraphSCCPass.h" | #include "llvm/Analysis/CallGraphSCCPass.h" | |||
namespace llvm { | namespace llvm { | |||
class CallSite; | class CallSite; | |||
class DataLayout; | class DataLayout; | |||
class InlineCost; | class InlineCost; | |||
template<class PtrType, unsigned SmallSize> | template<class PtrType, unsigned SmallSize> | |||
class SmallPtrSet; | class SmallPtrSet; | |||
/// Inliner - This class contains all of the helper code which is used to | /// Inliner - This class contains all of the helper code which is used to | |||
/// perform the inlining operations that do not depend on the policy. | /// perform the inlining operations that do not depend on the policy. | |||
skipping to change at line 45 | skipping to change at line 45 | |||
/// getAnalysisUsage - For this class, we declare that we require and pre serve | /// getAnalysisUsage - For this class, we declare that we require and pre serve | |||
/// the call graph. If the derived class implements this method, it shou ld | /// the call graph. If the derived class implements this method, it shou ld | |||
/// always explicitly call the implementation here. | /// always explicitly call the implementation here. | |||
virtual void getAnalysisUsage(AnalysisUsage &Info) const; | virtual void getAnalysisUsage(AnalysisUsage &Info) const; | |||
// Main run interface method, this implements the interface required by t he | // Main run interface method, this implements the interface required by t he | |||
// Pass class. | // Pass class. | |||
virtual bool runOnSCC(CallGraphSCC &SCC); | virtual bool runOnSCC(CallGraphSCC &SCC); | |||
using llvm::Pass::doFinalization; | ||||
// doFinalization - Remove now-dead linkonce functions at the end of | // doFinalization - Remove now-dead linkonce functions at the end of | |||
// processing to avoid breaking the SCC traversal. | // processing to avoid breaking the SCC traversal. | |||
virtual bool doFinalization(CallGraph &CG); | virtual bool doFinalization(CallGraph &CG); | |||
/// This method returns the value specified by the -inline-threshold valu e, | /// This method returns the value specified by the -inline-threshold valu e, | |||
/// specified on the command line. This is typically not directly needed . | /// specified on the command line. This is typically not directly needed . | |||
/// | /// | |||
unsigned getInlineThreshold() const { return InlineThreshold; } | unsigned getInlineThreshold() const { return InlineThreshold; } | |||
/// Calculate the inline threshold for given Caller. This threshold is lo wer | /// Calculate the inline threshold for given Caller. This threshold is lo wer | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 2 lines changed or added | |||
InstIterator.h | InstIterator.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// iterator that can probably be genericized later. | // iterator that can probably be genericized later. | |||
// | // | |||
// Note that this iterator gets invalidated any time that basic blocks or | // Note that this iterator gets invalidated any time that basic blocks or | |||
// instructions are moved around. | // instructions are moved around. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_INSTITERATOR_H | #ifndef LLVM_SUPPORT_INSTITERATOR_H | |||
#define LLVM_SUPPORT_INSTITERATOR_H | #define LLVM_SUPPORT_INSTITERATOR_H | |||
#include "llvm/BasicBlock.h" | #include "llvm/IR/BasicBlock.h" | |||
#include "llvm/Function.h" | #include "llvm/IR/Function.h" | |||
namespace llvm { | namespace llvm { | |||
// This class implements inst_begin() & inst_end() for | // This class implements inst_begin() & inst_end() for | |||
// inst_iterator and const_inst_iterator's. | // inst_iterator and const_inst_iterator's. | |||
// | // | |||
template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> | template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> | |||
class InstIterator { | class InstIterator { | |||
typedef _BB_t BBty; | typedef _BB_t BBty; | |||
typedef _BB_i_t BBIty; | typedef _BB_i_t BBIty; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
InstVisitor.h | InstVisitor.h | |||
---|---|---|---|---|
//===- llvm/Support/InstVisitor.h - Define instruction visitors -*- C++ -*- ===// | //===- llvm/InstVisitor.h - Instruction visitor templates -------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_INSTVISITOR_H | #ifndef LLVM_INSTVISITOR_H | |||
#define LLVM_SUPPORT_INSTVISITOR_H | #define LLVM_INSTVISITOR_H | |||
#include "llvm/Function.h" | #include "llvm/IR/Function.h" | |||
#include "llvm/Instructions.h" | #include "llvm/IR/Instructions.h" | |||
#include "llvm/Intrinsics.h" | #include "llvm/IR/IntrinsicInst.h" | |||
#include "llvm/IntrinsicInst.h" | #include "llvm/IR/Intrinsics.h" | |||
#include "llvm/Module.h" | #include "llvm/IR/Module.h" | |||
#include "llvm/Support/CallSite.h" | #include "llvm/Support/CallSite.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
namespace llvm { | namespace llvm { | |||
// We operate on opaque instruction classes, so forward declare all instruc tion | // We operate on opaque instruction classes, so forward declare all instruc tion | |||
// types now... | // types now... | |||
// | // | |||
#define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS; | #define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS; | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
#define DELEGATE(CLASS_TO_VISIT) \ | #define DELEGATE(CLASS_TO_VISIT) \ | |||
return static_cast<SubClass*>(this)-> \ | return static_cast<SubClass*>(this)-> \ | |||
visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I)) | visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I)) | |||
/// @brief Base class for instruction visitors | /// @brief Base class for instruction visitors | |||
/// | /// | |||
/// Instruction visitors are used when you want to perform different action s | /// Instruction visitors are used when you want to perform different action s | |||
/// for different kinds of instructions without having to use lots of casts | /// for different kinds of instructions without having to use lots of casts | |||
/// and a big switch statement (in your code, that is). | /// and a big switch statement (in your code, that is). | |||
skipping to change at line 124 | skipping to change at line 124 | |||
// visit - Finally, code to visit an instruction... | // visit - Finally, code to visit an instruction... | |||
// | // | |||
RetTy visit(Instruction &I) { | RetTy visit(Instruction &I) { | |||
switch (I.getOpcode()) { | switch (I.getOpcode()) { | |||
default: llvm_unreachable("Unknown instruction type encountered!"); | default: llvm_unreachable("Unknown instruction type encountered!"); | |||
// Build the switch statement using the Instruction.def file... | // Build the switch statement using the Instruction.def file... | |||
#define HANDLE_INST(NUM, OPCODE, CLASS) \ | #define HANDLE_INST(NUM, OPCODE, CLASS) \ | |||
case Instruction::OPCODE: return \ | case Instruction::OPCODE: return \ | |||
static_cast<SubClass*>(this)-> \ | static_cast<SubClass*>(this)-> \ | |||
visit##OPCODE(static_cast<CLASS&>(I)); | visit##OPCODE(static_cast<CLASS&>(I)); | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
} | } | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Visitation functions... these functions provide default fallbacks in c ase | // Visitation functions... these functions provide default fallbacks in c ase | |||
// the user does not specify what to do for a particular instruction type . | // the user does not specify what to do for a particular instruction type . | |||
// The default behavior is to generalize the instruction type to its subt ype | // The default behavior is to generalize the instruction type to its subt ype | |||
// and try visiting the subtype. All of this should be inlined perfectly , | // and try visiting the subtype. All of this should be inlined perfectly , | |||
// because there are no virtual functions to get in the way. | // because there are no virtual functions to get in the way. | |||
// | // | |||
skipping to change at line 159 | skipping to change at line 159 | |||
// instruction have multiple more specific Instruction subclasses. The Ca ll | // instruction have multiple more specific Instruction subclasses. The Ca ll | |||
// instruction currently supports this. We implement that by redirecting that | // instruction currently supports this. We implement that by redirecting that | |||
// instruction to a special delegation helper. | // instruction to a special delegation helper. | |||
#define HANDLE_INST(NUM, OPCODE, CLASS) \ | #define HANDLE_INST(NUM, OPCODE, CLASS) \ | |||
RetTy visit##OPCODE(CLASS &I) { \ | RetTy visit##OPCODE(CLASS &I) { \ | |||
if (NUM == Instruction::Call) \ | if (NUM == Instruction::Call) \ | |||
return delegateCallInst(I); \ | return delegateCallInst(I); \ | |||
else \ | else \ | |||
DELEGATE(CLASS); \ | DELEGATE(CLASS); \ | |||
} | } | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
// Specific Instruction type classes... note that all of the casts are | // Specific Instruction type classes... note that all of the casts are | |||
// necessary because we use the instruction classes as opaque types... | // necessary because we use the instruction classes as opaque types... | |||
// | // | |||
RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst );} | RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst );} | |||
RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst );} | RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst );} | |||
RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst );} | RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst );} | |||
RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst );} | RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst );} | |||
RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst );} | RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst );} | |||
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst );} | RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst );} | |||
End of changes. 6 change blocks. | ||||
11 lines changed or deleted | 11 lines changed or added | |||
InstrTypes.h | InstrTypes.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines various meta classes of instructions that exist in the VM | // This file defines various meta classes of instructions that exist in the VM | |||
// representation. Specific concrete subclasses of these may be found in t he | // representation. Specific concrete subclasses of these may be found in t he | |||
// i*.h files... | // i*.h files... | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_INSTRUCTION_TYPES_H | #ifndef LLVM_IR_INSTRTYPES_H | |||
#define LLVM_INSTRUCTION_TYPES_H | #define LLVM_IR_INSTRTYPES_H | |||
#include "llvm/Instruction.h" | ||||
#include "llvm/OperandTraits.h" | ||||
#include "llvm/DerivedTypes.h" | ||||
#include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | |||
#include "llvm/IR/DerivedTypes.h" | ||||
#include "llvm/IR/Instruction.h" | ||||
#include "llvm/IR/OperandTraits.h" | ||||
namespace llvm { | namespace llvm { | |||
class LLVMContext; | class LLVMContext; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// TerminatorInst Class | // TerminatorInst Class | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// TerminatorInst - Subclasses of this class are all able to terminate a b asic | /// TerminatorInst - Subclasses of this class are all able to terminate a b asic | |||
skipping to change at line 179 | skipping to change at line 179 | |||
const Twine &Name, BasicBlock *InsertAtEnd) ; | const Twine &Name, BasicBlock *InsertAtEnd) ; | |||
/// Create* - These methods just forward to Create, and are useful when y ou | /// Create* - These methods just forward to Create, and are useful when y ou | |||
/// statically know what type of instruction you're going to create. The se | /// statically know what type of instruction you're going to create. The se | |||
/// helpers just save some typing. | /// helpers just save some typing. | |||
#define HANDLE_BINARY_INST(N, OPC, CLASS) \ | #define HANDLE_BINARY_INST(N, OPC, CLASS) \ | |||
static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ | static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ | |||
const Twine &Name = "") {\ | const Twine &Name = "") {\ | |||
return Create(Instruction::OPC, V1, V2, Name);\ | return Create(Instruction::OPC, V1, V2, Name);\ | |||
} | } | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
#define HANDLE_BINARY_INST(N, OPC, CLASS) \ | #define HANDLE_BINARY_INST(N, OPC, CLASS) \ | |||
static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ | static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ | |||
const Twine &Name, BasicBlock *BB) {\ | const Twine &Name, BasicBlock *BB) {\ | |||
return Create(Instruction::OPC, V1, V2, Name, BB);\ | return Create(Instruction::OPC, V1, V2, Name, BB);\ | |||
} | } | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
#define HANDLE_BINARY_INST(N, OPC, CLASS) \ | #define HANDLE_BINARY_INST(N, OPC, CLASS) \ | |||
static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ | static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ | |||
const Twine &Name, Instruction *I) {\ | const Twine &Name, Instruction *I) {\ | |||
return Create(Instruction::OPC, V1, V2, Name, I);\ | return Create(Instruction::OPC, V1, V2, Name, I);\ | |||
} | } | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2, | static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2, | |||
const Twine &Name = "") { | const Twine &Name = "") { | |||
BinaryOperator *BO = Create(Opc, V1, V2, Name); | BinaryOperator *BO = Create(Opc, V1, V2, Name); | |||
BO->setHasNoSignedWrap(true); | BO->setHasNoSignedWrap(true); | |||
return BO; | return BO; | |||
} | } | |||
static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2, | static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2, | |||
const Twine &Name, BasicBlock *BB) { | const Twine &Name, BasicBlock *BB) { | |||
BinaryOperator *BO = Create(Opc, V1, V2, Name, BB); | BinaryOperator *BO = Create(Opc, V1, V2, Name, BB); | |||
skipping to change at line 311 | skipping to change at line 311 | |||
BasicBlock *InsertAtEnd); | BasicBlock *InsertAtEnd); | |||
static BinaryOperator *CreateNot(Value *Op, const Twine &Name = "", | static BinaryOperator *CreateNot(Value *Op, const Twine &Name = "", | |||
Instruction *InsertBefore = 0); | Instruction *InsertBefore = 0); | |||
static BinaryOperator *CreateNot(Value *Op, const Twine &Name, | static BinaryOperator *CreateNot(Value *Op, const Twine &Name, | |||
BasicBlock *InsertAtEnd); | BasicBlock *InsertAtEnd); | |||
/// isNeg, isFNeg, isNot - Check if the given Value is a | /// isNeg, isFNeg, isNot - Check if the given Value is a | |||
/// NEG, FNeg, or NOT instruction. | /// NEG, FNeg, or NOT instruction. | |||
/// | /// | |||
static bool isNeg(const Value *V); | static bool isNeg(const Value *V); | |||
static bool isFNeg(const Value *V); | static bool isFNeg(const Value *V, bool IgnoreZeroSign=false); | |||
static bool isNot(const Value *V); | static bool isNot(const Value *V); | |||
/// getNegArgument, getNotArgument - Helper functions to extract the | /// getNegArgument, getNotArgument - Helper functions to extract the | |||
/// unary argument of a NEG, FNEG or NOT operation implemented via | /// unary argument of a NEG, FNEG or NOT operation implemented via | |||
/// Sub, FSub, or Xor. | /// Sub, FSub, or Xor. | |||
/// | /// | |||
static const Value *getNegArgument(const Value *BinOp); | static const Value *getNegArgument(const Value *BinOp); | |||
static Value *getNegArgument( Value *BinOp); | static Value *getNegArgument( Value *BinOp); | |||
static const Value *getFNegArgument(const Value *BinOp); | static const Value *getFNegArgument(const Value *BinOp); | |||
static Value *getFNegArgument( Value *BinOp); | static Value *getFNegArgument( Value *BinOp); | |||
End of changes. 7 change blocks. | ||||
9 lines changed or deleted | 9 lines changed or added | |||
Instruction.h | Instruction.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the declaration of the Instruction class, which is th e | // This file contains the declaration of the Instruction class, which is th e | |||
// base class for all of the LLVM instructions. | // base class for all of the LLVM instructions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_INSTRUCTION_H | #ifndef LLVM_IR_INSTRUCTION_H | |||
#define LLVM_INSTRUCTION_H | #define LLVM_IR_INSTRUCTION_H | |||
#include "llvm/User.h" | ||||
#include "llvm/ADT/ilist_node.h" | #include "llvm/ADT/ilist_node.h" | |||
#include "llvm/IR/User.h" | ||||
#include "llvm/Support/DebugLoc.h" | #include "llvm/Support/DebugLoc.h" | |||
namespace llvm { | namespace llvm { | |||
class FastMathFlags; | ||||
class LLVMContext; | class LLVMContext; | |||
class MDNode; | class MDNode; | |||
template<typename ValueSubClass, typename ItemParentClass> | template<typename ValueSubClass, typename ItemParentClass> | |||
class SymbolTableListTraits; | class SymbolTableListTraits; | |||
class Instruction : public User, public ilist_node<Instruction> { | class Instruction : public User, public ilist_node<Instruction> { | |||
void operator=(const Instruction &) LLVM_DELETED_FUNCTION; | void operator=(const Instruction &) LLVM_DELETED_FUNCTION; | |||
Instruction(const Instruction &) LLVM_DELETED_FUNCTION; | Instruction(const Instruction &) LLVM_DELETED_FUNCTION; | |||
skipping to change at line 179 | skipping to change at line 180 | |||
/// Node is null. | /// Node is null. | |||
void setMetadata(unsigned KindID, MDNode *Node); | void setMetadata(unsigned KindID, MDNode *Node); | |||
void setMetadata(StringRef Kind, MDNode *Node); | void setMetadata(StringRef Kind, MDNode *Node); | |||
/// setDebugLoc - Set the debug location information for this instruction . | /// setDebugLoc - Set the debug location information for this instruction . | |||
void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; } | void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; } | |||
/// getDebugLoc - Return the debug location for this node as a DebugLoc. | /// getDebugLoc - Return the debug location for this node as a DebugLoc. | |||
const DebugLoc &getDebugLoc() const { return DbgLoc; } | const DebugLoc &getDebugLoc() const { return DbgLoc; } | |||
/// Set or clear the unsafe-algebra flag on this instruction, which must | ||||
be an | ||||
/// operator which supports this flag. See LangRef.html for the meaning o | ||||
f | ||||
/// this flag. | ||||
void setHasUnsafeAlgebra(bool B); | ||||
/// Set or clear the no-nans flag on this instruction, which must be an | ||||
/// operator which supports this flag. See LangRef.html for the meaning o | ||||
f | ||||
/// this flag. | ||||
void setHasNoNaNs(bool B); | ||||
/// Set or clear the no-infs flag on this instruction, which must be an | ||||
/// operator which supports this flag. See LangRef.html for the meaning o | ||||
f | ||||
/// this flag. | ||||
void setHasNoInfs(bool B); | ||||
/// Set or clear the no-signed-zeros flag on this instruction, which must | ||||
be | ||||
/// an operator which supports this flag. See LangRef.html for the meanin | ||||
g of | ||||
/// this flag. | ||||
void setHasNoSignedZeros(bool B); | ||||
/// Set or clear the allow-reciprocal flag on this instruction, which mus | ||||
t be | ||||
/// an operator which supports this flag. See LangRef.html for the meanin | ||||
g of | ||||
/// this flag. | ||||
void setHasAllowReciprocal(bool B); | ||||
/// Convenience function for setting all the fast-math flags on this | ||||
/// instruction, which must be an operator which supports these flags. Se | ||||
e | ||||
/// LangRef.html for the meaning of these flats. | ||||
void setFastMathFlags(FastMathFlags FMF); | ||||
/// Determine whether the unsafe-algebra flag is set. | ||||
bool hasUnsafeAlgebra() const; | ||||
/// Determine whether the no-NaNs flag is set. | ||||
bool hasNoNaNs() const; | ||||
/// Determine whether the no-infs flag is set. | ||||
bool hasNoInfs() const; | ||||
/// Determine whether the no-signed-zeros flag is set. | ||||
bool hasNoSignedZeros() const; | ||||
/// Determine whether the allow-reciprocal flag is set. | ||||
bool hasAllowReciprocal() const; | ||||
/// Convenience function for getting all the fast-math flags, which must | ||||
be an | ||||
/// operator which supports these flags. See LangRef.html for the meaning | ||||
of | ||||
/// these flats. | ||||
FastMathFlags getFastMathFlags() const; | ||||
/// Copy I's fast-math flags | ||||
void copyFastMathFlags(const Instruction *I); | ||||
private: | private: | |||
/// hasMetadataHashEntry - Return true if we have an entry in the on-the- side | /// hasMetadataHashEntry - Return true if we have an entry in the on-the- side | |||
/// metadata hash. | /// metadata hash. | |||
bool hasMetadataHashEntry() const { | bool hasMetadataHashEntry() const { | |||
return (getSubclassDataFromValue() & HasMetadataBit) != 0; | return (getSubclassDataFromValue() & HasMetadataBit) != 0; | |||
} | } | |||
// These are all implemented in Metadata.cpp. | // These are all implemented in Metadata.cpp. | |||
MDNode *getMetadataImpl(unsigned KindID) const; | MDNode *getMetadataImpl(unsigned KindID) const; | |||
MDNode *getMetadataImpl(StringRef Kind) const; | MDNode *getMetadataImpl(StringRef Kind) const; | |||
skipping to change at line 204 | skipping to change at line 258 | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Predicates and helper methods. | // Predicates and helper methods. | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// isAssociative - Return true if the instruction is associative: | /// isAssociative - Return true if the instruction is associative: | |||
/// | /// | |||
/// Associative operators satisfy: x op (y op z) === (x op y) op z | /// Associative operators satisfy: x op (y op z) === (x op y) op z | |||
/// | /// | |||
/// In LLVM, the Add, Mul, And, Or, and Xor operators are associative. | /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative. | |||
/// | /// | |||
bool isAssociative() const { return isAssociative(getOpcode()); } | bool isAssociative() const; | |||
static bool isAssociative(unsigned op); | static bool isAssociative(unsigned op); | |||
/// isCommutative - Return true if the instruction is commutative: | /// isCommutative - Return true if the instruction is commutative: | |||
/// | /// | |||
/// Commutative operators satisfy: (x op y) === (y op x) | /// Commutative operators satisfy: (x op y) === (y op x) | |||
/// | /// | |||
/// In LLVM, these are the associative operators, plus SetEQ and SetNE, w hen | /// In LLVM, these are the associative operators, plus SetEQ and SetNE, w hen | |||
/// applied to any type. | /// applied to any type. | |||
/// | /// | |||
bool isCommutative() const { return isCommutative(getOpcode()); } | bool isCommutative() const { return isCommutative(getOpcode()); } | |||
skipping to change at line 257 | skipping to change at line 311 | |||
/// write memory. | /// write memory. | |||
/// | /// | |||
bool mayReadOrWriteMemory() const { | bool mayReadOrWriteMemory() const { | |||
return mayReadFromMemory() || mayWriteToMemory(); | return mayReadFromMemory() || mayWriteToMemory(); | |||
} | } | |||
/// mayThrow - Return true if this instruction may throw an exception. | /// mayThrow - Return true if this instruction may throw an exception. | |||
/// | /// | |||
bool mayThrow() const; | bool mayThrow() const; | |||
/// mayReturn - Return true if this is a function that may return. | ||||
/// this is true for all normal instructions. The only exception | ||||
/// is functions that are marked with the 'noreturn' attribute. | ||||
/// | ||||
bool mayReturn() const; | ||||
/// mayHaveSideEffects - Return true if the instruction may have side eff ects. | /// mayHaveSideEffects - Return true if the instruction may have side eff ects. | |||
/// | /// | |||
/// Note that this does not consider malloc and alloca to have side | /// Note that this does not consider malloc and alloca to have side | |||
/// effects because the newly allocated memory is completely invisible to | /// effects because the newly allocated memory is completely invisible to | |||
/// instructions which don't used the returned value. For cases where th is | /// instructions which don't used the returned value. For cases where th is | |||
/// matters, isSafeToSpeculativelyExecute may be more appropriate. | /// matters, isSafeToSpeculativelyExecute may be more appropriate. | |||
bool mayHaveSideEffects() const { | bool mayHaveSideEffects() const { | |||
return mayWriteToMemory() || mayThrow(); | return mayWriteToMemory() || mayThrow() || !mayReturn(); | |||
} | } | |||
/// clone() - Create a copy of 'this' instruction that is identical in al l | /// clone() - Create a copy of 'this' instruction that is identical in al l | |||
/// ways except the following: | /// ways except the following: | |||
/// * The instruction has no parent | /// * The instruction has no parent | |||
/// * The instruction has no name | /// * The instruction has no name | |||
/// | /// | |||
Instruction *clone() const; | Instruction *clone() const; | |||
/// isIdenticalTo - Return true if the specified instruction is exactly | /// isIdenticalTo - Return true if the specified instruction is exactly | |||
skipping to change at line 322 | skipping to change at line 382 | |||
return V->getValueID() >= Value::InstructionVal; | return V->getValueID() >= Value::InstructionVal; | |||
} | } | |||
//---------------------------------------------------------------------- | //---------------------------------------------------------------------- | |||
// Exported enumerations. | // Exported enumerations. | |||
// | // | |||
enum TermOps { // These terminate basic blocks | enum TermOps { // These terminate basic blocks | |||
#define FIRST_TERM_INST(N) TermOpsBegin = N, | #define FIRST_TERM_INST(N) TermOpsBegin = N, | |||
#define HANDLE_TERM_INST(N, OPC, CLASS) OPC = N, | #define HANDLE_TERM_INST(N, OPC, CLASS) OPC = N, | |||
#define LAST_TERM_INST(N) TermOpsEnd = N+1 | #define LAST_TERM_INST(N) TermOpsEnd = N+1 | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
}; | }; | |||
enum BinaryOps { | enum BinaryOps { | |||
#define FIRST_BINARY_INST(N) BinaryOpsBegin = N, | #define FIRST_BINARY_INST(N) BinaryOpsBegin = N, | |||
#define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N, | #define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N, | |||
#define LAST_BINARY_INST(N) BinaryOpsEnd = N+1 | #define LAST_BINARY_INST(N) BinaryOpsEnd = N+1 | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
}; | }; | |||
enum MemoryOps { | enum MemoryOps { | |||
#define FIRST_MEMORY_INST(N) MemoryOpsBegin = N, | #define FIRST_MEMORY_INST(N) MemoryOpsBegin = N, | |||
#define HANDLE_MEMORY_INST(N, OPC, CLASS) OPC = N, | #define HANDLE_MEMORY_INST(N, OPC, CLASS) OPC = N, | |||
#define LAST_MEMORY_INST(N) MemoryOpsEnd = N+1 | #define LAST_MEMORY_INST(N) MemoryOpsEnd = N+1 | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
}; | }; | |||
enum CastOps { | enum CastOps { | |||
#define FIRST_CAST_INST(N) CastOpsBegin = N, | #define FIRST_CAST_INST(N) CastOpsBegin = N, | |||
#define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N, | #define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N, | |||
#define LAST_CAST_INST(N) CastOpsEnd = N+1 | #define LAST_CAST_INST(N) CastOpsEnd = N+1 | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
}; | }; | |||
enum OtherOps { | enum OtherOps { | |||
#define FIRST_OTHER_INST(N) OtherOpsBegin = N, | #define FIRST_OTHER_INST(N) OtherOpsBegin = N, | |||
#define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N, | #define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N, | |||
#define LAST_OTHER_INST(N) OtherOpsEnd = N+1 | #define LAST_OTHER_INST(N) OtherOpsEnd = N+1 | |||
#include "llvm/Instruction.def" | #include "llvm/IR/Instruction.def" | |||
}; | }; | |||
private: | private: | |||
// Shadow Value::setValueSubclassData with a private forwarding method so that | // Shadow Value::setValueSubclassData with a private forwarding method so that | |||
// subclasses cannot accidentally use it. | // subclasses cannot accidentally use it. | |||
void setValueSubclassData(unsigned short D) { | void setValueSubclassData(unsigned short D) { | |||
Value::setValueSubclassData(D); | Value::setValueSubclassData(D); | |||
} | } | |||
unsigned short getSubclassDataFromValue() const { | unsigned short getSubclassDataFromValue() const { | |||
return Value::getSubclassDataFromValue(); | return Value::getSubclassDataFromValue(); | |||
} | } | |||
End of changes. 13 change blocks. | ||||
10 lines changed or deleted | 81 lines changed or added | |||
InstructionSimplify.h | InstructionSimplify.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares routines for folding instructions into simpler forms | // This file declares routines for folding instructions into simpler forms | |||
// that do not require creating new instructions. This does constant foldi ng | // that do not require creating new instructions. This does constant foldi ng | |||
// ("add i32 1, 1" -> "2") but can also handle non-constant operands, eithe r | // ("add i32 1, 1" -> "2") but can also handle non-constant operands, eithe r | |||
// returning a constant ("and i32 %x, 0" -> "0") or an already existing val ue | // returning a constant ("and i32 %x, 0" -> "0") or an already existing val ue | |||
// ("and i32 %x, %x" -> "%x"). If the simplification is also an instructio n | // ("and i32 %x, %x" -> "%x"). If the simplification is also an instructio n | |||
// then it dominates the original instruction. | // then it dominates the original instruction. | |||
// | // | |||
// These routines implicitly resolve undef uses. The easiest way to be safe | ||||
when | ||||
// using these routines to obtain simplified values for existing instructio | ||||
ns is | ||||
// to always replace all uses of the instructions with the resulting simpli | ||||
fied | ||||
// values. This will prevent other code from seeing the same undef uses and | ||||
// resolving them to different values. | ||||
// | ||||
// These routines are designed to tolerate moderately incomplete IR, such a | ||||
s | ||||
// instructions that are not connected to basic blocks yet. However, they d | ||||
o | ||||
// require that all the IR that they encounter be valid. In particular, the | ||||
y | ||||
// require that all non-constant values be defined in the same function, an | ||||
d the | ||||
// same call context of that function (and not split between caller and cal | ||||
lee | ||||
// contexts of a directly recursive call, for example). | ||||
// | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H | #ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H | |||
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H | #define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H | |||
#include "llvm/IR/User.h" | ||||
namespace llvm { | namespace llvm { | |||
template<typename T> | template<typename T> | |||
class ArrayRef; | class ArrayRef; | |||
class DominatorTree; | class DominatorTree; | |||
class Instruction; | class Instruction; | |||
class DataLayout; | class DataLayout; | |||
class FastMathFlags; | ||||
class TargetLibraryInfo; | class TargetLibraryInfo; | |||
class Type; | class Type; | |||
class Value; | class Value; | |||
/// SimplifyAddInst - Given operands for an Add, see if we can | /// SimplifyAddInst - Given operands for an Add, see if we can | |||
/// fold the result. If not, this returns null. | /// fold the result. If not, this returns null. | |||
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, | Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, | |||
const DataLayout *TD = 0, | const DataLayout *TD = 0, | |||
const TargetLibraryInfo *TLI = 0, | const TargetLibraryInfo *TLI = 0, | |||
const DominatorTree *DT = 0); | const DominatorTree *DT = 0); | |||
/// SimplifySubInst - Given operands for a Sub, see if we can | /// SimplifySubInst - Given operands for a Sub, see if we can | |||
/// fold the result. If not, this returns null. | /// fold the result. If not, this returns null. | |||
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, | Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, | |||
const DataLayout *TD = 0, | const DataLayout *TD = 0, | |||
const TargetLibraryInfo *TLI = 0, | const TargetLibraryInfo *TLI = 0, | |||
const DominatorTree *DT = 0); | const DominatorTree *DT = 0); | |||
/// Given operands for an FAdd, see if we can fold the result. If not, t | ||||
his | ||||
/// returns null. | ||||
Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, | ||||
const DataLayout *TD = 0, | ||||
const TargetLibraryInfo *TLI = 0, | ||||
const DominatorTree *DT = 0); | ||||
/// Given operands for an FSub, see if we can fold the result. If not, t | ||||
his | ||||
/// returns null. | ||||
Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, | ||||
const DataLayout *TD = 0, | ||||
const TargetLibraryInfo *TLI = 0, | ||||
const DominatorTree *DT = 0); | ||||
/// Given operands for an FMul, see if we can fold the result. If not, t | ||||
his | ||||
/// returns null. | ||||
Value *SimplifyFMulInst(Value *LHS, Value *RHS, | ||||
FastMathFlags FMF, | ||||
const DataLayout *TD = 0, | ||||
const TargetLibraryInfo *TLI = 0, | ||||
const DominatorTree *DT = 0); | ||||
/// SimplifyMulInst - Given operands for a Mul, see if we can | /// SimplifyMulInst - Given operands for a Mul, see if we can | |||
/// fold the result. If not, this returns null. | /// fold the result. If not, this returns null. | |||
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0, | Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0, | |||
const TargetLibraryInfo *TLI = 0, | const TargetLibraryInfo *TLI = 0, | |||
const DominatorTree *DT = 0); | const DominatorTree *DT = 0); | |||
/// SimplifySDivInst - Given operands for an SDiv, see if we can | /// SimplifySDivInst - Given operands for an SDiv, see if we can | |||
/// fold the result. If not, this returns null. | /// fold the result. If not, this returns null. | |||
Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0, | Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0, | |||
const TargetLibraryInfo *TLI = 0, | const TargetLibraryInfo *TLI = 0, | |||
skipping to change at line 184 | skipping to change at line 222 | |||
const TargetLibraryInfo *TLI = 0, | const TargetLibraryInfo *TLI = 0, | |||
const DominatorTree *DT = 0); | const DominatorTree *DT = 0); | |||
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can | /// SimplifyBinOp - Given operands for a BinaryOperator, see if we can | |||
/// fold the result. If not, this returns null. | /// fold the result. If not, this returns null. | |||
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, | Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, | |||
const DataLayout *TD = 0, | const DataLayout *TD = 0, | |||
const TargetLibraryInfo *TLI = 0, | const TargetLibraryInfo *TLI = 0, | |||
const DominatorTree *DT = 0); | const DominatorTree *DT = 0); | |||
/// \brief Given a function and iterators over arguments, see if we can f | ||||
old | ||||
/// the result. | ||||
/// | ||||
/// If this call could not be simplified returns null. | ||||
Value *SimplifyCall(Value *V, User::op_iterator ArgBegin, | ||||
User::op_iterator ArgEnd, const DataLayout *TD = 0, | ||||
const TargetLibraryInfo *TLI = 0, | ||||
const DominatorTree *DT = 0); | ||||
/// \brief Given a function and set of arguments, see if we can fold the | ||||
/// result. | ||||
/// | ||||
/// If this call could not be simplified returns null. | ||||
Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, | ||||
const DataLayout *TD = 0, | ||||
const TargetLibraryInfo *TLI = 0, | ||||
const DominatorTree *DT = 0); | ||||
/// SimplifyInstruction - See if we can compute a simplified version of t his | /// SimplifyInstruction - See if we can compute a simplified version of t his | |||
/// instruction. If not, this returns null. | /// instruction. If not, this returns null. | |||
Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0, | Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0, | |||
const TargetLibraryInfo *TLI = 0, | const TargetLibraryInfo *TLI = 0, | |||
const DominatorTree *DT = 0); | const DominatorTree *DT = 0); | |||
/// \brief Replace all uses of 'I' with 'SimpleV' and simplify the uses | /// \brief Replace all uses of 'I' with 'SimpleV' and simplify the uses | |||
/// recursively. | /// recursively. | |||
/// | /// | |||
/// This first performs a normal RAUW of I with SimpleV. It then recursiv ely | /// This first performs a normal RAUW of I with SimpleV. It then recursiv ely | |||
End of changes. 5 change blocks. | ||||
0 lines changed or deleted | 68 lines changed or added | |||
Instructions.h | Instructions.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file exposes the class definitions of all of the subclasses of the | // This file exposes the class definitions of all of the subclasses of the | |||
// Instruction class. This is meant to be an easy way to get access to all | // Instruction class. This is meant to be an easy way to get access to all | |||
// instruction subclasses. | // instruction subclasses. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_INSTRUCTIONS_H | #ifndef LLVM_IR_INSTRUCTIONS_H | |||
#define LLVM_INSTRUCTIONS_H | #define LLVM_IR_INSTRUCTIONS_H | |||
#include "llvm/InstrTypes.h" | ||||
#include "llvm/DerivedTypes.h" | ||||
#include "llvm/Attributes.h" | ||||
#include "llvm/CallingConv.h" | ||||
#include "llvm/Support/IntegersSubset.h" | ||||
#include "llvm/Support/IntegersSubsetMapping.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/IR/Attributes.h" | ||||
#include "llvm/IR/CallingConv.h" | ||||
#include "llvm/IR/DerivedTypes.h" | ||||
#include "llvm/IR/InstrTypes.h" | ||||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include "llvm/Support/IntegersSubset.h" | ||||
#include "llvm/Support/IntegersSubsetMapping.h" | ||||
#include <iterator> | #include <iterator> | |||
namespace llvm { | namespace llvm { | |||
class APInt; | ||||
class ConstantInt; | class ConstantInt; | |||
class ConstantRange; | class ConstantRange; | |||
class APInt; | class DataLayout; | |||
class LLVMContext; | class LLVMContext; | |||
enum AtomicOrdering { | enum AtomicOrdering { | |||
NotAtomic = 0, | NotAtomic = 0, | |||
Unordered = 1, | Unordered = 1, | |||
Monotonic = 2, | Monotonic = 2, | |||
// Consume = 3, // Not specified yet. | // Consume = 3, // Not specified yet. | |||
Acquire = 4, | Acquire = 4, | |||
Release = 5, | Release = 5, | |||
AcquireRelease = 6, | AcquireRelease = 6, | |||
skipping to change at line 93 | skipping to change at line 94 | |||
/// getArraySize - Get the number of elements allocated. For a simple | /// getArraySize - Get the number of elements allocated. For a simple | |||
/// allocation of a single element, this will return a constant 1 value. | /// allocation of a single element, this will return a constant 1 value. | |||
/// | /// | |||
const Value *getArraySize() const { return getOperand(0); } | const Value *getArraySize() const { return getOperand(0); } | |||
Value *getArraySize() { return getOperand(0); } | Value *getArraySize() { return getOperand(0); } | |||
/// getType - Overload to return most specific pointer type | /// getType - Overload to return most specific pointer type | |||
/// | /// | |||
PointerType *getType() const { | PointerType *getType() const { | |||
return reinterpret_cast<PointerType*>(Instruction::getType()); | return cast<PointerType>(Instruction::getType()); | |||
} | } | |||
/// getAllocatedType - Return the type that is being allocated by the | /// getAllocatedType - Return the type that is being allocated by the | |||
/// instruction. | /// instruction. | |||
/// | /// | |||
Type *getAllocatedType() const; | Type *getAllocatedType() const; | |||
/// getAlignment - Return the alignment of the memory that is being alloc ated | /// getAlignment - Return the alignment of the memory that is being alloc ated | |||
/// by the instruction. | /// by the instruction. | |||
/// | /// | |||
skipping to change at line 760 | skipping to change at line 761 | |||
const Twine &NameStr, | const Twine &NameStr, | |||
BasicBlock *InsertAtEnd) { | BasicBlock *InsertAtEnd) { | |||
GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertAtEnd); | GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertAtEnd); | |||
GEP->setIsInBounds(true); | GEP->setIsInBounds(true); | |||
return GEP; | return GEP; | |||
} | } | |||
/// Transparently provide more efficient getOperand methods. | /// Transparently provide more efficient getOperand methods. | |||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | |||
// getType - Overload to return most specific pointer type... | // getType - Overload to return most specific sequential type. | |||
PointerType *getType() const { | SequentialType *getType() const { | |||
return reinterpret_cast<PointerType*>(Instruction::getType()); | return cast<SequentialType>(Instruction::getType()); | |||
} | } | |||
/// \brief Returns the address space of this instruction's pointer type. | /// \brief Returns the address space of this instruction's pointer type. | |||
unsigned getAddressSpace() const { | unsigned getAddressSpace() const { | |||
// Note that this is always the same as the pointer operand's address s pace | // Note that this is always the same as the pointer operand's address s pace | |||
// and that is cheaper to compute, so cheat here. | // and that is cheaper to compute, so cheat here. | |||
return getPointerAddressSpace(); | return getPointerAddressSpace(); | |||
} | } | |||
/// getIndexedType - Returns the type of the element that would be loaded with | /// getIndexedType - Returns the type of the element that would be loaded with | |||
skipping to change at line 849 | skipping to change at line 850 | |||
/// a constant offset between them. | /// a constant offset between them. | |||
bool hasAllConstantIndices() const; | bool hasAllConstantIndices() const; | |||
/// setIsInBounds - Set or clear the inbounds flag on this GEP instructio n. | /// setIsInBounds - Set or clear the inbounds flag on this GEP instructio n. | |||
/// See LangRef.html for the meaning of inbounds on a getelementptr. | /// See LangRef.html for the meaning of inbounds on a getelementptr. | |||
void setIsInBounds(bool b = true); | void setIsInBounds(bool b = true); | |||
/// isInBounds - Determine whether the GEP has the inbounds flag. | /// isInBounds - Determine whether the GEP has the inbounds flag. | |||
bool isInBounds() const; | bool isInBounds() const; | |||
/// \brief Accumulate the constant address offset of this GEP if possible | ||||
. | ||||
/// | ||||
/// This routine accepts an APInt into which it will accumulate the const | ||||
ant | ||||
/// offset of this GEP if the GEP is in fact constant. If the GEP is not | ||||
/// all-constant, it returns false and the value of the offset APInt is | ||||
/// undefined (it is *not* preserved!). The APInt passed into this routin | ||||
e | ||||
/// must be at least as wide as the IntPtr type for the address space of | ||||
/// the base GEP pointer. | ||||
bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const; | ||||
// Methods for support type inquiry through isa, cast, and dyn_cast: | // Methods for support type inquiry through isa, cast, and dyn_cast: | |||
static inline bool classof(const Instruction *I) { | static inline bool classof(const Instruction *I) { | |||
return (I->getOpcode() == Instruction::GetElementPtr); | return (I->getOpcode() == Instruction::GetElementPtr); | |||
} | } | |||
static inline bool classof(const Value *V) { | static inline bool classof(const Value *V) { | |||
return isa<Instruction>(V) && classof(cast<Instruction>(V)); | return isa<Instruction>(V) && classof(cast<Instruction>(V)); | |||
} | } | |||
}; | }; | |||
template <> | template <> | |||
skipping to change at line 939 | skipping to change at line 950 | |||
) : CmpInst(makeCmpResultType(LHS->getType()), | ) : CmpInst(makeCmpResultType(LHS->getType()), | |||
Instruction::ICmp, pred, LHS, RHS, NameStr, | Instruction::ICmp, pred, LHS, RHS, NameStr, | |||
&InsertAtEnd) { | &InsertAtEnd) { | |||
assert(pred >= CmpInst::FIRST_ICMP_PREDICATE && | assert(pred >= CmpInst::FIRST_ICMP_PREDICATE && | |||
pred <= CmpInst::LAST_ICMP_PREDICATE && | pred <= CmpInst::LAST_ICMP_PREDICATE && | |||
"Invalid ICmp predicate value"); | "Invalid ICmp predicate value"); | |||
assert(getOperand(0)->getType() == getOperand(1)->getType() && | assert(getOperand(0)->getType() == getOperand(1)->getType() && | |||
"Both operands to ICmp instruction are not of the same type!"); | "Both operands to ICmp instruction are not of the same type!"); | |||
// Check that the operands are the right type | // Check that the operands are the right type | |||
assert((getOperand(0)->getType()->isIntOrIntVectorTy() || | assert((getOperand(0)->getType()->isIntOrIntVectorTy() || | |||
getOperand(0)->getType()->isPointerTy()) && | getOperand(0)->getType()->getScalarType()->isPointerTy()) && | |||
"Invalid operand types for ICmp instruction"); | "Invalid operand types for ICmp instruction"); | |||
} | } | |||
/// \brief Constructor with no-insertion semantics | /// \brief Constructor with no-insertion semantics | |||
ICmpInst( | ICmpInst( | |||
Predicate pred, ///< The predicate to use for the comparison | Predicate pred, ///< The predicate to use for the comparison | |||
Value *LHS, ///< The left-hand-side of the expression | Value *LHS, ///< The left-hand-side of the expression | |||
Value *RHS, ///< The right-hand-side of the expression | Value *RHS, ///< The right-hand-side of the expression | |||
const Twine &NameStr = "" ///< Name of the instruction | const Twine &NameStr = "" ///< Name of the instruction | |||
) : CmpInst(makeCmpResultType(LHS->getType()), | ) : CmpInst(makeCmpResultType(LHS->getType()), | |||
skipping to change at line 1153 | skipping to change at line 1164 | |||
} | } | |||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// CallInst - This class represents a function call, abstracting a target | /// CallInst - This class represents a function call, abstracting a target | |||
/// machine's calling convention. This class uses low bit of the SubClassD ata | /// machine's calling convention. This class uses low bit of the SubClassD ata | |||
/// field to indicate whether or not this is a tail call. The rest of the bits | /// field to indicate whether or not this is a tail call. The rest of the bits | |||
/// hold the calling convention of the call. | /// hold the calling convention of the call. | |||
/// | /// | |||
class CallInst : public Instruction { | class CallInst : public Instruction { | |||
AttrListPtr AttributeList; ///< parameter attributes for call | AttributeSet AttributeList; ///< parameter attributes for call | |||
CallInst(const CallInst &CI); | CallInst(const CallInst &CI); | |||
void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr); | void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr); | |||
void init(Value *Func, const Twine &NameStr); | void init(Value *Func, const Twine &NameStr); | |||
/// Construct a CallInst given a range of arguments. | /// Construct a CallInst given a range of arguments. | |||
/// \brief Construct a CallInst from a range of arguments | /// \brief Construct a CallInst from a range of arguments | |||
inline CallInst(Value *Func, ArrayRef<Value *> Args, | inline CallInst(Value *Func, ArrayRef<Value *> Args, | |||
const Twine &NameStr, Instruction *InsertBefore); | const Twine &NameStr, Instruction *InsertBefore); | |||
/// Construct a CallInst given a range of arguments. | /// Construct a CallInst given a range of arguments. | |||
skipping to change at line 1251 | skipping to change at line 1262 | |||
CallingConv::ID getCallingConv() const { | CallingConv::ID getCallingConv() const { | |||
return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 1); | return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 1); | |||
} | } | |||
void setCallingConv(CallingConv::ID CC) { | void setCallingConv(CallingConv::ID CC) { | |||
setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | | setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | | |||
(static_cast<unsigned>(CC) << 1)); | (static_cast<unsigned>(CC) << 1)); | |||
} | } | |||
/// getAttributes - Return the parameter attributes for this call. | /// getAttributes - Return the parameter attributes for this call. | |||
/// | /// | |||
const AttrListPtr &getAttributes() const { return AttributeList; } | const AttributeSet &getAttributes() const { return AttributeList; } | |||
/// setAttributes - Set the parameter attributes for this call. | /// setAttributes - Set the parameter attributes for this call. | |||
/// | /// | |||
void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; } | void setAttributes(const AttributeSet &Attrs) { AttributeList = Attrs; } | |||
/// addAttribute - adds the attribute to the list of attributes. | /// addAttribute - adds the attribute to the list of attributes. | |||
void addAttribute(unsigned i, Attributes attr); | void addAttribute(unsigned i, Attribute::AttrKind attr); | |||
/// removeAttribute - removes the attribute from the list of attributes. | /// removeAttribute - removes the attribute from the list of attributes. | |||
void removeAttribute(unsigned i, Attributes attr); | void removeAttribute(unsigned i, Attribute attr); | |||
/// \brief Determine whether this call has the given attribute. | /// \brief Determine whether this call has the given attribute. | |||
bool hasFnAttr(Attributes::AttrVal A) const; | bool hasFnAttr(Attribute::AttrKind A) const; | |||
/// \brief Determine whether the call or the callee has the given attribu tes. | /// \brief Determine whether the call or the callee has the given attribu tes. | |||
bool paramHasAttr(unsigned i, Attributes::AttrVal A) const; | bool paramHasAttr(unsigned i, Attribute::AttrKind A) const; | |||
/// \brief Extract the alignment for a call or parameter (0=unknown). | /// \brief Extract the alignment for a call or parameter (0=unknown). | |||
unsigned getParamAlignment(unsigned i) const { | unsigned getParamAlignment(unsigned i) const { | |||
return AttributeList.getParamAlignment(i); | return AttributeList.getParamAlignment(i); | |||
} | } | |||
/// \brief Return true if the call should not be inlined. | /// \brief Return true if the call should not be inlined. | |||
bool isNoInline() const { return hasFnAttr(Attributes::NoInline); } | bool isNoInline() const { return hasFnAttr(Attribute::NoInline); } | |||
void setIsNoInline() { | void setIsNoInline() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::NoInline); | |||
Attributes::get(getContext(), Attributes::NoInline)); | ||||
} | } | |||
/// \brief Return true if the call can return twice | /// \brief Return true if the call can return twice | |||
bool canReturnTwice() const { | bool canReturnTwice() const { | |||
return hasFnAttr(Attributes::ReturnsTwice); | return hasFnAttr(Attribute::ReturnsTwice); | |||
} | } | |||
void setCanReturnTwice() { | void setCanReturnTwice() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::ReturnsTwice); | |||
Attributes::get(getContext(), Attributes::ReturnsTwice)); | ||||
} | } | |||
/// \brief Determine if the call does not access memory. | /// \brief Determine if the call does not access memory. | |||
bool doesNotAccessMemory() const { | bool doesNotAccessMemory() const { | |||
return hasFnAttr(Attributes::ReadNone); | return hasFnAttr(Attribute::ReadNone); | |||
} | } | |||
void setDoesNotAccessMemory() { | void setDoesNotAccessMemory() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone); | |||
Attributes::get(getContext(), Attributes::ReadNone)); | ||||
} | } | |||
/// \brief Determine if the call does not access or only reads memory. | /// \brief Determine if the call does not access or only reads memory. | |||
bool onlyReadsMemory() const { | bool onlyReadsMemory() const { | |||
return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly); | return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly); | |||
} | } | |||
void setOnlyReadsMemory() { | void setOnlyReadsMemory() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly); | |||
Attributes::get(getContext(), Attributes::ReadOnly)); | ||||
} | } | |||
/// \brief Determine if the call cannot return. | /// \brief Determine if the call cannot return. | |||
bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); } | bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } | |||
void setDoesNotReturn() { | void setDoesNotReturn() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::NoReturn); | |||
Attributes::get(getContext(), Attributes::NoReturn)); | ||||
} | } | |||
/// \brief Determine if the call cannot unwind. | /// \brief Determine if the call cannot unwind. | |||
bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); } | bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); } | |||
void setDoesNotThrow() { | void setDoesNotThrow() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); | |||
Attributes::get(getContext(), Attributes::NoUnwind)); | } | |||
/// \brief Determine if the call cannot be duplicated. | ||||
bool cannotDuplicate() const {return hasFnAttr(Attribute::NoDuplicate); } | ||||
void setCannotDuplicate() { | ||||
addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate); | ||||
} | } | |||
/// \brief Determine if the call returns a structure through first | /// \brief Determine if the call returns a structure through first | |||
/// pointer argument. | /// pointer argument. | |||
bool hasStructRetAttr() const { | bool hasStructRetAttr() const { | |||
// Be friendly and also check the callee. | // Be friendly and also check the callee. | |||
return paramHasAttr(1, Attributes::StructRet); | return paramHasAttr(1, Attribute::StructRet); | |||
} | } | |||
/// \brief Determine if any call argument is an aggregate passed by value . | /// \brief Determine if any call argument is an aggregate passed by value . | |||
bool hasByValArgument() const { | bool hasByValArgument() const { | |||
for (unsigned I = 0, E = AttributeList.getNumAttrs(); I != E; ++I) | return AttributeList.hasAttrSomewhere(Attribute::ByVal); | |||
if (AttributeList.getAttributesAtIndex(I).hasAttribute(Attributes::By | ||||
Val)) | ||||
return true; | ||||
return false; | ||||
} | } | |||
/// getCalledFunction - Return the function called, or null if this is an | /// getCalledFunction - Return the function called, or null if this is an | |||
/// indirect function invocation. | /// indirect function invocation. | |||
/// | /// | |||
Function *getCalledFunction() const { | Function *getCalledFunction() const { | |||
return dyn_cast<Function>(Op<-1>()); | return dyn_cast<Function>(Op<-1>()); | |||
} | } | |||
/// getCalledValue - Get a pointer to the function that is invoked by thi s | /// getCalledValue - Get a pointer to the function that is invoked by thi s | |||
skipping to change at line 1551 | skipping to change at line 1559 | |||
/// isValidOperands - Return true if an extractelement instruction can be | /// isValidOperands - Return true if an extractelement instruction can be | |||
/// formed with the specified operands. | /// formed with the specified operands. | |||
static bool isValidOperands(const Value *Vec, const Value *Idx); | static bool isValidOperands(const Value *Vec, const Value *Idx); | |||
Value *getVectorOperand() { return Op<0>(); } | Value *getVectorOperand() { return Op<0>(); } | |||
Value *getIndexOperand() { return Op<1>(); } | Value *getIndexOperand() { return Op<1>(); } | |||
const Value *getVectorOperand() const { return Op<0>(); } | const Value *getVectorOperand() const { return Op<0>(); } | |||
const Value *getIndexOperand() const { return Op<1>(); } | const Value *getIndexOperand() const { return Op<1>(); } | |||
VectorType *getVectorOperandType() const { | VectorType *getVectorOperandType() const { | |||
return reinterpret_cast<VectorType*>(getVectorOperand()->getType()); | return cast<VectorType>(getVectorOperand()->getType()); | |||
} | } | |||
/// Transparently provide more efficient getOperand methods. | /// Transparently provide more efficient getOperand methods. | |||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | |||
// Methods for support type inquiry through isa, cast, and dyn_cast: | // Methods for support type inquiry through isa, cast, and dyn_cast: | |||
static inline bool classof(const Instruction *I) { | static inline bool classof(const Instruction *I) { | |||
return I->getOpcode() == Instruction::ExtractElement; | return I->getOpcode() == Instruction::ExtractElement; | |||
} | } | |||
static inline bool classof(const Value *V) { | static inline bool classof(const Value *V) { | |||
skipping to change at line 1609 | skipping to change at line 1617 | |||
} | } | |||
/// isValidOperands - Return true if an insertelement instruction can be | /// isValidOperands - Return true if an insertelement instruction can be | |||
/// formed with the specified operands. | /// formed with the specified operands. | |||
static bool isValidOperands(const Value *Vec, const Value *NewElt, | static bool isValidOperands(const Value *Vec, const Value *NewElt, | |||
const Value *Idx); | const Value *Idx); | |||
/// getType - Overload to return most specific vector type. | /// getType - Overload to return most specific vector type. | |||
/// | /// | |||
VectorType *getType() const { | VectorType *getType() const { | |||
return reinterpret_cast<VectorType*>(Instruction::getType()); | return cast<VectorType>(Instruction::getType()); | |||
} | } | |||
/// Transparently provide more efficient getOperand methods. | /// Transparently provide more efficient getOperand methods. | |||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | |||
// Methods for support type inquiry through isa, cast, and dyn_cast: | // Methods for support type inquiry through isa, cast, and dyn_cast: | |||
static inline bool classof(const Instruction *I) { | static inline bool classof(const Instruction *I) { | |||
return I->getOpcode() == Instruction::InsertElement; | return I->getOpcode() == Instruction::InsertElement; | |||
} | } | |||
static inline bool classof(const Value *V) { | static inline bool classof(const Value *V) { | |||
skipping to change at line 1661 | skipping to change at line 1669 | |||
const Twine &NameStr, BasicBlock *InsertAtEnd); | const Twine &NameStr, BasicBlock *InsertAtEnd); | |||
/// isValidOperands - Return true if a shufflevector instruction can be | /// isValidOperands - Return true if a shufflevector instruction can be | |||
/// formed with the specified operands. | /// formed with the specified operands. | |||
static bool isValidOperands(const Value *V1, const Value *V2, | static bool isValidOperands(const Value *V1, const Value *V2, | |||
const Value *Mask); | const Value *Mask); | |||
/// getType - Overload to return most specific vector type. | /// getType - Overload to return most specific vector type. | |||
/// | /// | |||
VectorType *getType() const { | VectorType *getType() const { | |||
return reinterpret_cast<VectorType*>(Instruction::getType()); | return cast<VectorType>(Instruction::getType()); | |||
} | } | |||
/// Transparently provide more efficient getOperand methods. | /// Transparently provide more efficient getOperand methods. | |||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); | |||
Constant *getMask() const { | Constant *getMask() const { | |||
return reinterpret_cast<Constant*>(getOperand(2)); | return cast<Constant>(getOperand(2)); | |||
} | } | |||
/// getMaskValue - Return the index from the shuffle mask for the specifi ed | /// getMaskValue - Return the index from the shuffle mask for the specifi ed | |||
/// output result. This is either -1 if the element is undef or a number less | /// output result. This is either -1 if the element is undef or a number less | |||
/// than 2*numelements. | /// than 2*numelements. | |||
static int getMaskValue(Constant *Mask, unsigned i); | static int getMaskValue(Constant *Mask, unsigned i); | |||
int getMaskValue(unsigned i) const { | int getMaskValue(unsigned i) const { | |||
return getMaskValue(getMask(), i); | return getMaskValue(getMask(), i); | |||
} | } | |||
skipping to change at line 2643 | skipping to change at line 2651 | |||
} | } | |||
// Case iterators definition. | // Case iterators definition. | |||
template <class SwitchInstTy, class ConstantIntTy, | template <class SwitchInstTy, class ConstantIntTy, | |||
class SubsetsItTy, class BasicBlockTy> | class SubsetsItTy, class BasicBlockTy> | |||
class CaseIteratorT { | class CaseIteratorT { | |||
protected: | protected: | |||
SwitchInstTy *SI; | SwitchInstTy *SI; | |||
unsigned long Index; | unsigned Index; | |||
SubsetsItTy SubsetIt; | SubsetsItTy SubsetIt; | |||
/// Initializes case iterator for given SwitchInst and for given | /// Initializes case iterator for given SwitchInst and for given | |||
/// case number. | /// case number. | |||
friend class SwitchInst; | friend class SwitchInst; | |||
CaseIteratorT(SwitchInstTy *SI, unsigned SuccessorIndex, | CaseIteratorT(SwitchInstTy *SI, unsigned SuccessorIndex, | |||
SubsetsItTy CaseValueIt) { | SubsetsItTy CaseValueIt) { | |||
this->SI = SI; | this->SI = SI; | |||
Index = SuccessorIndex; | Index = SuccessorIndex; | |||
this->SubsetIt = CaseValueIt; | this->SubsetIt = CaseValueIt; | |||
skipping to change at line 2742 | skipping to change at line 2750 | |||
// Also allow "-1" iterator here. That will became valid after ++. | // Also allow "-1" iterator here. That will became valid after ++. | |||
unsigned NumCases = SI->getNumCases(); | unsigned NumCases = SI->getNumCases(); | |||
assert((Index == 0 || Index-1 <= NumCases) && | assert((Index == 0 || Index-1 <= NumCases) && | |||
"Index out the number of cases."); | "Index out the number of cases."); | |||
--Index; | --Index; | |||
if (Index == NumCases) { | if (Index == NumCases) { | |||
SubsetIt = SI->TheSubsets.end(); | SubsetIt = SI->TheSubsets.end(); | |||
return *this; | return *this; | |||
} | } | |||
if (Index != -1UL) | if (Index != -1U) | |||
--SubsetIt; | --SubsetIt; | |||
return *this; | return *this; | |||
} | } | |||
Self operator--(int) { | Self operator--(int) { | |||
Self tmp = *this; | Self tmp = *this; | |||
--(*this); | --(*this); | |||
return tmp; | return tmp; | |||
} | } | |||
bool operator==(const Self& RHS) const { | bool operator==(const Self& RHS) const { | |||
skipping to change at line 2931 | skipping to change at line 2939 | |||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) | DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// InvokeInst Class | // InvokeInst Class | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// InvokeInst - Invoke instruction. The SubclassData field is used to hol d the | /// InvokeInst - Invoke instruction. The SubclassData field is used to hol d the | |||
/// calling convention of the call. | /// calling convention of the call. | |||
/// | /// | |||
class InvokeInst : public TerminatorInst { | class InvokeInst : public TerminatorInst { | |||
AttrListPtr AttributeList; | AttributeSet AttributeList; | |||
InvokeInst(const InvokeInst &BI); | InvokeInst(const InvokeInst &BI); | |||
void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, | void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, | |||
ArrayRef<Value *> Args, const Twine &NameStr); | ArrayRef<Value *> Args, const Twine &NameStr); | |||
/// Construct an InvokeInst given a range of arguments. | /// Construct an InvokeInst given a range of arguments. | |||
/// | /// | |||
/// \brief Construct an InvokeInst from a range of arguments | /// \brief Construct an InvokeInst from a range of arguments | |||
inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfExcept ion, | inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfExcept ion, | |||
ArrayRef<Value *> Args, unsigned Values, | ArrayRef<Value *> Args, unsigned Values, | |||
const Twine &NameStr, Instruction *InsertBefore); | const Twine &NameStr, Instruction *InsertBefore); | |||
skipping to change at line 2992 | skipping to change at line 3000 | |||
/// function call. | /// function call. | |||
CallingConv::ID getCallingConv() const { | CallingConv::ID getCallingConv() const { | |||
return static_cast<CallingConv::ID>(getSubclassDataFromInstruction()); | return static_cast<CallingConv::ID>(getSubclassDataFromInstruction()); | |||
} | } | |||
void setCallingConv(CallingConv::ID CC) { | void setCallingConv(CallingConv::ID CC) { | |||
setInstructionSubclassData(static_cast<unsigned>(CC)); | setInstructionSubclassData(static_cast<unsigned>(CC)); | |||
} | } | |||
/// getAttributes - Return the parameter attributes for this invoke. | /// getAttributes - Return the parameter attributes for this invoke. | |||
/// | /// | |||
const AttrListPtr &getAttributes() const { return AttributeList; } | const AttributeSet &getAttributes() const { return AttributeList; } | |||
/// setAttributes - Set the parameter attributes for this invoke. | /// setAttributes - Set the parameter attributes for this invoke. | |||
/// | /// | |||
void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; } | void setAttributes(const AttributeSet &Attrs) { AttributeList = Attrs; } | |||
/// addAttribute - adds the attribute to the list of attributes. | /// addAttribute - adds the attribute to the list of attributes. | |||
void addAttribute(unsigned i, Attributes attr); | void addAttribute(unsigned i, Attribute::AttrKind attr); | |||
/// removeAttribute - removes the attribute from the list of attributes. | /// removeAttribute - removes the attribute from the list of attributes. | |||
void removeAttribute(unsigned i, Attributes attr); | void removeAttribute(unsigned i, Attribute attr); | |||
/// \brief Determine whether this call has the NoAlias attribute. | /// \brief Determine whether this call has the NoAlias attribute. | |||
bool hasFnAttr(Attributes::AttrVal A) const; | bool hasFnAttr(Attribute::AttrKind A) const; | |||
/// \brief Determine whether the call or the callee has the given attribu tes. | /// \brief Determine whether the call or the callee has the given attribu tes. | |||
bool paramHasAttr(unsigned i, Attributes::AttrVal A) const; | bool paramHasAttr(unsigned i, Attribute::AttrKind A) const; | |||
/// \brief Extract the alignment for a call or parameter (0=unknown). | /// \brief Extract the alignment for a call or parameter (0=unknown). | |||
unsigned getParamAlignment(unsigned i) const { | unsigned getParamAlignment(unsigned i) const { | |||
return AttributeList.getParamAlignment(i); | return AttributeList.getParamAlignment(i); | |||
} | } | |||
/// \brief Return true if the call should not be inlined. | /// \brief Return true if the call should not be inlined. | |||
bool isNoInline() const { return hasFnAttr(Attributes::NoInline); } | bool isNoInline() const { return hasFnAttr(Attribute::NoInline); } | |||
void setIsNoInline() { | void setIsNoInline() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::NoInline); | |||
Attributes::get(getContext(), Attributes::NoInline)); | ||||
} | } | |||
/// \brief Determine if the call does not access memory. | /// \brief Determine if the call does not access memory. | |||
bool doesNotAccessMemory() const { | bool doesNotAccessMemory() const { | |||
return hasFnAttr(Attributes::ReadNone); | return hasFnAttr(Attribute::ReadNone); | |||
} | } | |||
void setDoesNotAccessMemory() { | void setDoesNotAccessMemory() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone); | |||
Attributes::get(getContext(), Attributes::ReadNone)); | ||||
} | } | |||
/// \brief Determine if the call does not access or only reads memory. | /// \brief Determine if the call does not access or only reads memory. | |||
bool onlyReadsMemory() const { | bool onlyReadsMemory() const { | |||
return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly); | return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly); | |||
} | } | |||
void setOnlyReadsMemory() { | void setOnlyReadsMemory() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly); | |||
Attributes::get(getContext(), Attributes::ReadOnly)); | ||||
} | } | |||
/// \brief Determine if the call cannot return. | /// \brief Determine if the call cannot return. | |||
bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); } | bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } | |||
void setDoesNotReturn() { | void setDoesNotReturn() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::NoReturn); | |||
Attributes::get(getContext(), Attributes::NoReturn)); | ||||
} | } | |||
/// \brief Determine if the call cannot unwind. | /// \brief Determine if the call cannot unwind. | |||
bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); } | bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); } | |||
void setDoesNotThrow() { | void setDoesNotThrow() { | |||
addAttribute(AttrListPtr::FunctionIndex, | addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); | |||
Attributes::get(getContext(), Attributes::NoUnwind)); | ||||
} | } | |||
/// \brief Determine if the call returns a structure through first | /// \brief Determine if the call returns a structure through first | |||
/// pointer argument. | /// pointer argument. | |||
bool hasStructRetAttr() const { | bool hasStructRetAttr() const { | |||
// Be friendly and also check the callee. | // Be friendly and also check the callee. | |||
return paramHasAttr(1, Attributes::StructRet); | return paramHasAttr(1, Attribute::StructRet); | |||
} | } | |||
/// \brief Determine if any call argument is an aggregate passed by value . | /// \brief Determine if any call argument is an aggregate passed by value . | |||
bool hasByValArgument() const { | bool hasByValArgument() const { | |||
for (unsigned I = 0, E = AttributeList.getNumAttrs(); I != E; ++I) | return AttributeList.hasAttrSomewhere(Attribute::ByVal); | |||
if (AttributeList.getAttributesAtIndex(I).hasAttribute(Attributes::By | ||||
Val)) | ||||
return true; | ||||
return false; | ||||
} | } | |||
/// getCalledFunction - Return the function called, or null if this is an | /// getCalledFunction - Return the function called, or null if this is an | |||
/// indirect function invocation. | /// indirect function invocation. | |||
/// | /// | |||
Function *getCalledFunction() const { | Function *getCalledFunction() const { | |||
return dyn_cast<Function>(Op<-3>()); | return dyn_cast<Function>(Op<-3>()); | |||
} | } | |||
/// getCalledValue - Get a pointer to the function that is invoked by thi s | /// getCalledValue - Get a pointer to the function that is invoked by thi s | |||
End of changes. 56 change blocks. | ||||
79 lines changed or deleted | 80 lines changed or added | |||
Instrumentation.h | Instrumentation.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines constructor functions for instrumentation passes. | // This file defines constructor functions for instrumentation passes. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H | #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H | |||
#define LLVM_TRANSFORMS_INSTRUMENTATION_H | #define LLVM_TRANSFORMS_INSTRUMENTATION_H | |||
#include "llvm/ADT/StringRef.h" | ||||
namespace llvm { | namespace llvm { | |||
class ModulePass; | class ModulePass; | |||
class FunctionPass; | class FunctionPass; | |||
// Insert edge profiling instrumentation | // Insert edge profiling instrumentation | |||
ModulePass *createEdgeProfilerPass(); | ModulePass *createEdgeProfilerPass(); | |||
// Insert optimal edge profiling instrumentation | // Insert optimal edge profiling instrumentation | |||
ModulePass *createOptimalEdgeProfilerPass(); | ModulePass *createOptimalEdgeProfilerPass(); | |||
// Insert path profiling instrumentation | // Insert path profiling instrumentation | |||
ModulePass *createPathProfilerPass(); | ModulePass *createPathProfilerPass(); | |||
// Insert GCOV profiling instrumentation | // Insert GCOV profiling instrumentation | |||
ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = t | struct GCOVOptions { | |||
rue, | static GCOVOptions getDefault(); | |||
bool Use402Format = false, | ||||
bool UseExtraChecksum = false); | // Specify whether to emit .gcno files. | |||
bool EmitNotes; | ||||
// Specify whether to modify the program to emit .gcda files when run. | ||||
bool EmitData; | ||||
// A four-byte version string. The meaning of a version string is describ | ||||
ed in | ||||
// gcc's gcov-io.h | ||||
char Version[4]; | ||||
// Emit a "cfg checksum" that follows the "line number checksum" of a | ||||
// function. This affects both .gcno and .gcda files. | ||||
bool UseCfgChecksum; | ||||
// Add the 'noredzone' attribute to added runtime library calls. | ||||
bool NoRedZone; | ||||
// Emit the name of the function in the .gcda files. This is redundant, a | ||||
s | ||||
// the function identifier can be used to find the name from the .gcno fi | ||||
le. | ||||
bool FunctionNamesInData; | ||||
}; | ||||
ModulePass *createGCOVProfilerPass(const GCOVOptions &Options = | ||||
GCOVOptions::getDefault()); | ||||
// Insert AddressSanitizer (address sanity checking) instrumentation | // Insert AddressSanitizer (address sanity checking) instrumentation | |||
FunctionPass *createAddressSanitizerPass(); | FunctionPass *createAddressSanitizerFunctionPass( | |||
bool CheckInitOrder = true, bool CheckUseAfterReturn = false, | ||||
bool CheckLifetime = false, StringRef BlacklistFile = StringRef(), | ||||
bool ZeroBaseShadow = false); | ||||
ModulePass *createAddressSanitizerModulePass( | ||||
bool CheckInitOrder = true, StringRef BlacklistFile = StringRef(), | ||||
bool ZeroBaseShadow = false); | ||||
// Insert MemorySanitizer instrumentation (detection of uninitialized reads | ||||
) | ||||
FunctionPass *createMemorySanitizerPass(bool TrackOrigins = false, | ||||
StringRef BlacklistFile = StringRef | ||||
()); | ||||
// Insert ThreadSanitizer (race detection) instrumentation | // Insert ThreadSanitizer (race detection) instrumentation | |||
FunctionPass *createThreadSanitizerPass(); | FunctionPass *createThreadSanitizerPass(StringRef BlacklistFile = StringRef ()); | |||
// BoundsChecking - This pass instruments the code to perform run-time boun ds | // BoundsChecking - This pass instruments the code to perform run-time boun ds | |||
// checking on loads, stores, and other memory intrinsics. | // checking on loads, stores, and other memory intrinsics. | |||
// Penalty is the maximum run-time that is acceptable for the user. | FunctionPass *createBoundsCheckingPass(); | |||
// | ||||
FunctionPass *createBoundsCheckingPass(unsigned Penalty = 5); | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 5 change blocks. | ||||
9 lines changed or deleted | 47 lines changed or added | |||
IntegerDivision.h | IntegerDivision.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains an implementation of 32bit integer division for targe ts | // This file contains an implementation of 32bit integer division for targe ts | |||
// that don't have native support. It's largely derived from compiler-rt's | // that don't have native support. It's largely derived from compiler-rt's | |||
// implementation of __udivsi3, but hand-tuned for targets that prefer less | // implementation of __udivsi3, but hand-tuned for targets that prefer less | |||
// control flow. | // control flow. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef TRANSFORMS_UTILS_INTEGERDIVISION_H | #ifndef LLVM_TRANSFORMS_UTILS_INTEGERDIVISION_H | |||
#define TRANSFORMS_UTILS_INTEGERDIVISION_H | #define LLVM_TRANSFORMS_UTILS_INTEGERDIVISION_H | |||
namespace llvm { | namespace llvm { | |||
class BinaryOperator; | class BinaryOperator; | |||
} | } | |||
namespace llvm { | namespace llvm { | |||
/// Generate code to calculate the remainder of two integers, replacing R em | /// Generate code to calculate the remainder of two integers, replacing R em | |||
/// with the generated code. This currently generates code using the udiv | /// with the generated code. This currently generates code using the udiv | |||
/// expansion, but future work includes generating more specialized code, | /// expansion, but future work includes generating more specialized code, | |||
skipping to change at line 46 | skipping to change at line 46 | |||
/// Generate code to divide two integers, replacing Div with the generate d | /// Generate code to divide two integers, replacing Div with the generate d | |||
/// code. This currently generates code similarly to compiler-rt's | /// code. This currently generates code similarly to compiler-rt's | |||
/// implementations, but future work includes generating more specialized code | /// implementations, but future work includes generating more specialized code | |||
/// when more information about the operands are known. Currently only | /// when more information about the operands are known. Currently only | |||
/// implements 32bit scalar division, but future work is removing this | /// implements 32bit scalar division, but future work is removing this | |||
/// limitation. | /// limitation. | |||
/// | /// | |||
/// @brief Replace Div with generated code. | /// @brief Replace Div with generated code. | |||
bool expandDivision(BinaryOperator* Div); | bool expandDivision(BinaryOperator* Div); | |||
/// Generate code to calculate the remainder of two integers, replacing R | ||||
em | ||||
/// with the generated code. Uses the above 32bit routine, therefore adeq | ||||
uate | ||||
/// for targets with little or no support for less than 32 bit arithmetic | ||||
. | ||||
/// | ||||
/// @brief Replace Rem with generated code. | ||||
bool expandRemainderUpTo32Bits(BinaryOperator *Rem); | ||||
/// Generate code to divide two integers, replacing Div with the generate | ||||
d | ||||
/// code. Uses the above 32bit routine, therefore adequate for targets wi | ||||
th | ||||
/// little or no support for less than 32 bit arithmetic. | ||||
/// | ||||
/// @brief Replace Rem with generated code. | ||||
bool expandDivisionUpTo32Bits(BinaryOperator *Div); | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 21 lines changed or added | |||
IntegersSubset.h | IntegersSubset.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
/// @file | /// @file | |||
/// This file contains class that implements constant set of ranges: | /// This file contains class that implements constant set of ranges: | |||
/// [<Low0,High0>,...,<LowN,HighN>]. Initially, this class was created for | /// [<Low0,High0>,...,<LowN,HighN>]. Initially, this class was created for | |||
/// SwitchInst and was used for case value representation that may contain | /// SwitchInst and was used for case value representation that may contain | |||
/// multiple ranges for a single successor. | /// multiple ranges for a single successor. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef CONSTANTRANGESSET_H_ | #ifndef LLVM_SUPPORT_INTEGERSSUBSET_H | |||
#define CONSTANTRANGESSET_H_ | #define LLVM_SUPPORT_INTEGERSSUBSET_H | |||
#include "llvm/IR/Constants.h" | ||||
#include "llvm/IR/DerivedTypes.h" | ||||
#include "llvm/IR/LLVMContext.h" | ||||
#include <list> | #include <list> | |||
#include "llvm/Constants.h" | ||||
#include "llvm/DerivedTypes.h" | ||||
#include "llvm/LLVMContext.h" | ||||
namespace llvm { | namespace llvm { | |||
// The IntItem is a wrapper for APInt. | // The IntItem is a wrapper for APInt. | |||
// 1. It determines sign of integer, it allows to use | // 1. It determines sign of integer, it allows to use | |||
// comparison operators >,<,>=,<=, and as result we got shorter and cl eaner | // comparison operators >,<,>=,<=, and as result we got shorter and cl eaner | |||
// constructions. | // constructions. | |||
// 2. It helps to implement PR1255 (case ranges) as a series of small pat ches. | // 2. It helps to implement PR1255 (case ranges) as a series of small pat ches. | |||
// 3. Currently we can interpret IntItem both as ConstantInt and as APInt . | // 3. Currently we can interpret IntItem both as ConstantInt and as APInt . | |||
// It allows to provide SwitchInst methods that works with ConstantInt for | // It allows to provide SwitchInst methods that works with ConstantInt for | |||
// non-updated passes. And it allows to use APInt interface for new me thods. | // non-updated passes. And it allows to use APInt interface for new me thods. | |||
skipping to change at line 541 | skipping to change at line 540 | |||
} | } | |||
operator Constant*() { return Holder; } | operator Constant*() { return Holder; } | |||
operator const Constant*() const { return Holder; } | operator const Constant*() const { return Holder; } | |||
Constant *operator->() { return Holder; } | Constant *operator->() { return Holder; } | |||
const Constant *operator->() const { return Holder; } | const Constant *operator->() const { return Holder; } | |||
}; | }; | |||
} | } | |||
#endif /* CONSTANTRANGESSET_H_ */ | #endif /* CLLVM_SUPPORT_INTEGERSSUBSET_H */ | |||
End of changes. 4 change blocks. | ||||
6 lines changed or deleted | 5 lines changed or added | |||
IntegersSubsetMapping.h | IntegersSubsetMapping.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
/// @file | /// @file | |||
/// IntegersSubsetMapping is mapping from A to B, where | /// IntegersSubsetMapping is mapping from A to B, where | |||
/// Items in A is subsets of integers, | /// Items in A is subsets of integers, | |||
/// Items in B some pointers (Successors). | /// Items in B some pointers (Successors). | |||
/// If user which to add another subset for successor that is already | /// If user which to add another subset for successor that is already | |||
/// exists in mapping, IntegersSubsetMapping merges existing subset with | /// exists in mapping, IntegersSubsetMapping merges existing subset with | |||
/// added one. | /// added one. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef CRSBUILDER_H_ | #ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H | |||
#define CRSBUILDER_H_ | #define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H | |||
#include "llvm/Support/IntegersSubset.h" | #include "llvm/Support/IntegersSubset.h" | |||
#include <list> | #include <list> | |||
#include <map> | #include <map> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
template <class SuccessorClass, | template <class SuccessorClass, | |||
class IntegersSubsetTy = IntegersSubset, | class IntegersSubsetTy = IntegersSubset, | |||
skipping to change at line 587 | skipping to change at line 587 | |||
RangeIterator begin() { return Items.begin(); } | RangeIterator begin() { return Items.begin(); } | |||
RangeIterator end() { return Items.end(); } | RangeIterator end() { return Items.end(); } | |||
}; | }; | |||
class BasicBlock; | class BasicBlock; | |||
typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB; | typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB; | |||
} | } | |||
#endif /* CRSBUILDER_H_ */ | #endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */ | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Interpreter.h | Interpreter.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file forces the interpreter to link in on certain operating systems . | // This file forces the interpreter to link in on certain operating systems . | |||
// (Windows). | // (Windows). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef EXECUTION_ENGINE_INTERPRETER_H | #ifndef LLVM_EXECUTIONENGINE_INTERPRETER_H | |||
#define EXECUTION_ENGINE_INTERPRETER_H | #define LLVM_EXECUTIONENGINE_INTERPRETER_H | |||
#include "llvm/ExecutionEngine/ExecutionEngine.h" | #include "llvm/ExecutionEngine/ExecutionEngine.h" | |||
#include <cstdlib> | #include <cstdlib> | |||
extern "C" void LLVMLinkInInterpreter(); | extern "C" void LLVMLinkInInterpreter(); | |||
namespace { | namespace { | |||
struct ForceInterpreterLinking { | struct ForceInterpreterLinking { | |||
ForceInterpreterLinking() { | ForceInterpreterLinking() { | |||
// We must reference the interpreter in such a way that compilers wil l not | // We must reference the interpreter in such a way that compilers wil l not | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Interval.h | Interval.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file contains the declaration of the Interval class, which | // This file contains the declaration of the Interval class, which | |||
// represents a set of CFG nodes and is a portion of an interval partition. | // represents a set of CFG nodes and is a portion of an interval partition. | |||
// | // | |||
// Intervals have some interesting and useful properties, including the | // Intervals have some interesting and useful properties, including the | |||
// following: | // following: | |||
// 1. The header node of an interval dominates all of the elements of th e | // 1. The header node of an interval dominates all of the elements of th e | |||
// interval | // interval | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_INTERVAL_H | #ifndef LLVM_ANALYSIS_INTERVAL_H | |||
#define LLVM_INTERVAL_H | #define LLVM_ANALYSIS_INTERVAL_H | |||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class BasicBlock; | class BasicBlock; | |||
class raw_ostream; | class raw_ostream; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
IntervalIterator.h | IntervalIterator.h | |||
---|---|---|---|---|
skipping to change at line 33 | skipping to change at line 33 | |||
// passing a false value into the intervals_begin() function. This causes t he | // passing a false value into the intervals_begin() function. This causes t he | |||
// IOwnMem member to be set, and the intervals to not be deleted. | // IOwnMem member to be set, and the intervals to not be deleted. | |||
// | // | |||
// It is only safe to use this if all of the intervals are deleted by the c aller | // It is only safe to use this if all of the intervals are deleted by the c aller | |||
// and all of the intervals are processed. However, the user of the iterat or is | // and all of the intervals are processed. However, the user of the iterat or is | |||
// not allowed to modify or delete the intervals until after the iterator h as | // not allowed to modify or delete the intervals until after the iterator h as | |||
// been used completely. The IntervalPartition class uses this functionali ty. | // been used completely. The IntervalPartition class uses this functionali ty. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_INTERVAL_ITERATOR_H | #ifndef LLVM_ANALYSIS_INTERVALITERATOR_H | |||
#define LLVM_INTERVAL_ITERATOR_H | #define LLVM_ANALYSIS_INTERVALITERATOR_H | |||
#include "llvm/Analysis/IntervalPartition.h" | #include "llvm/Analysis/IntervalPartition.h" | |||
#include "llvm/Function.h" | #include "llvm/IR/Function.h" | |||
#include "llvm/Support/CFG.h" | #include "llvm/Support/CFG.h" | |||
#include <algorithm> | #include <algorithm> | |||
#include <set> | #include <set> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
// getNodeHeader - Given a source graph node and the source graph, return t he | // getNodeHeader - Given a source graph node and the source graph, return t he | |||
// BasicBlock that is the header node. This is the opposite of | // BasicBlock that is the header node. This is the opposite of | |||
// getSourceGraphNode. | // getSourceGraphNode. | |||
skipping to change at line 156 | skipping to change at line 156 | |||
return *this; | return *this; | |||
} | } | |||
inline _Self operator++(int) { // Postincrement | inline _Self operator++(int) { // Postincrement | |||
_Self tmp = *this; ++*this; return tmp; | _Self tmp = *this; ++*this; return tmp; | |||
} | } | |||
private: | private: | |||
// ProcessInterval - This method is used during the construction of the | // ProcessInterval - This method is used during the construction of the | |||
// interval graph. It walks through the source graph, recursively creati ng | // interval graph. It walks through the source graph, recursively creati ng | |||
// an interval per invokation until the entire graph is covered. This us es | // an interval per invocation until the entire graph is covered. This us es | |||
// the ProcessNode method to add all of the nodes to the interval. | // the ProcessNode method to add all of the nodes to the interval. | |||
// | // | |||
// This method is templated because it may operate on two different sourc e | // This method is templated because it may operate on two different sourc e | |||
// graphs: a basic block graph, or a preexisting interval graph. | // graphs: a basic block graph, or a preexisting interval graph. | |||
// | // | |||
bool ProcessInterval(NodeTy *Node) { | bool ProcessInterval(NodeTy *Node) { | |||
BasicBlock *Header = getNodeHeader(Node); | BasicBlock *Header = getNodeHeader(Node); | |||
if (Visited.count(Header)) return false; | if (Visited.count(Header)) return false; | |||
Interval *Int = new Interval(Header); | Interval *Int = new Interval(Header); | |||
End of changes. 3 change blocks. | ||||
4 lines changed or deleted | 4 lines changed or added | |||
IntervalMap.h | IntervalMap.h | |||
---|---|---|---|---|
skipping to change at line 102 | skipping to change at line 102 | |||
// public: | // public: | |||
// void insert(KeyT a, KeyT b, Value y); | // void insert(KeyT a, KeyT b, Value y); | |||
// void erase(); | // void erase(); | |||
// }; | // }; | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_INTERVALMAP_H | #ifndef LLVM_ADT_INTERVALMAP_H | |||
#define LLVM_ADT_INTERVALMAP_H | #define LLVM_ADT_INTERVALMAP_H | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/Support/Allocator.h" | #include "llvm/Support/Allocator.h" | |||
#include "llvm/Support/RecyclingAllocator.h" | #include "llvm/Support/RecyclingAllocator.h" | |||
#include <iterator> | #include <iterator> | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
//--- Key traits ---// | //--- Key traits ---// | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
skipping to change at line 153 | skipping to change at line 153 | |||
} | } | |||
/// adjacent - Return true when the intervals [x;a] and [b;y] can coalesc e. | /// adjacent - Return true when the intervals [x;a] and [b;y] can coalesc e. | |||
/// This is a+1 == b for closed intervals, a == b for half-open intervals . | /// This is a+1 == b for closed intervals, a == b for half-open intervals . | |||
static inline bool adjacent(const T &a, const T &b) { | static inline bool adjacent(const T &a, const T &b) { | |||
return a+1 == b; | return a+1 == b; | |||
} | } | |||
}; | }; | |||
template <typename T> | ||||
struct IntervalMapHalfOpenInfo { | ||||
/// startLess - Return true if x is not in [a;b). | ||||
static inline bool startLess(const T &x, const T &a) { | ||||
return x < a; | ||||
} | ||||
/// stopLess - Return true if x is not in [a;b). | ||||
static inline bool stopLess(const T &b, const T &x) { | ||||
return b <= x; | ||||
} | ||||
/// adjacent - Return true when the intervals [x;a) and [b;y) can coalesc | ||||
e. | ||||
static inline bool adjacent(const T &a, const T &b) { | ||||
return a == b; | ||||
} | ||||
}; | ||||
/// IntervalMapImpl - Namespace used for IntervalMap implementation details . | /// IntervalMapImpl - Namespace used for IntervalMap implementation details . | |||
/// It should be considered private to the implementation. | /// It should be considered private to the implementation. | |||
namespace IntervalMapImpl { | namespace IntervalMapImpl { | |||
// Forward declarations. | // Forward declarations. | |||
template <typename, typename, unsigned, typename> class LeafNode; | template <typename, typename, unsigned, typename> class LeafNode; | |||
template <typename, typename, unsigned, typename> class BranchNode; | template <typename, typename, unsigned, typename> class BranchNode; | |||
typedef std::pair<unsigned,unsigned> IdxPair; | typedef std::pair<unsigned,unsigned> IdxPair; | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 22 lines changed or added | |||
IntervalPartition.h | IntervalPartition.h | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// | // | |||
// In this way, the interval partition may be used to reduce a flow graph d own | // In this way, the interval partition may be used to reduce a flow graph d own | |||
// to its degenerate single node interval partition (unless it is irreducib le). | // to its degenerate single node interval partition (unless it is irreducib le). | |||
// | // | |||
// TODO: The IntervalPartition class should take a bool parameter that tell s | // TODO: The IntervalPartition class should take a bool parameter that tell s | |||
// whether it should add the "tails" of an interval to an interval itself o r if | // whether it should add the "tails" of an interval to an interval itself o r if | |||
// they should be represented as distinct intervals. | // they should be represented as distinct intervals. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_INTERVAL_PARTITION_H | #ifndef LLVM_ANALYSIS_INTERVALPARTITION_H | |||
#define LLVM_INTERVAL_PARTITION_H | #define LLVM_ANALYSIS_INTERVALPARTITION_H | |||
#include "llvm/Analysis/Interval.h" | #include "llvm/Analysis/Interval.h" | |||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
#include <map> | #include <map> | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// IntervalPartition - This class builds and holds an "interval partition" for | // IntervalPartition - This class builds and holds an "interval partition" for | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
IntrinsicInst.h | IntrinsicInst.h | |||
---|---|---|---|---|
skipping to change at line 24 | skipping to change at line 24 | |||
// if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst)) | // if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst)) | |||
// ... MCI->getDest() ... MCI->getSource() ... | // ... MCI->getDest() ... MCI->getSource() ... | |||
// | // | |||
// All intrinsic function calls are instances of the call instruction, so t hese | // All intrinsic function calls are instances of the call instruction, so t hese | |||
// are all subclasses of the CallInst class. Note that none of these class es | // are all subclasses of the CallInst class. Note that none of these class es | |||
// has state or virtual methods, which is an important part of this gross/n eat | // has state or virtual methods, which is an important part of this gross/n eat | |||
// hack working. | // hack working. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_INTRINSICINST_H | #ifndef LLVM_IR_INTRINSICINST_H | |||
#define LLVM_INTRINSICINST_H | #define LLVM_IR_INTRINSICINST_H | |||
#include "llvm/Constants.h" | #include "llvm/IR/Constants.h" | |||
#include "llvm/Function.h" | #include "llvm/IR/Function.h" | |||
#include "llvm/Instructions.h" | #include "llvm/IR/Instructions.h" | |||
#include "llvm/Intrinsics.h" | #include "llvm/IR/Intrinsics.h" | |||
namespace llvm { | namespace llvm { | |||
/// IntrinsicInst - A useful wrapper class for inspecting calls to intrin sic | /// IntrinsicInst - A useful wrapper class for inspecting calls to intrin sic | |||
/// functions. This allows the standard isa/dyncast/cast functionality t o | /// functions. This allows the standard isa/dyncast/cast functionality t o | |||
/// work with calls to intrinsic functions. | /// work with calls to intrinsic functions. | |||
class IntrinsicInst : public CallInst { | class IntrinsicInst : public CallInst { | |||
IntrinsicInst() LLVM_DELETED_FUNCTION; | IntrinsicInst() LLVM_DELETED_FUNCTION; | |||
IntrinsicInst(const IntrinsicInst&) LLVM_DELETED_FUNCTION; | IntrinsicInst(const IntrinsicInst&) LLVM_DELETED_FUNCTION; | |||
void operator=(const IntrinsicInst&) LLVM_DELETED_FUNCTION; | void operator=(const IntrinsicInst&) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
/// getIntrinsicID - Return the intrinsic ID of this intrinsic. | /// getIntrinsicID - Return the intrinsic ID of this intrinsic. | |||
/// | /// | |||
Intrinsic::ID getIntrinsicID() const { | Intrinsic::ID getIntrinsicID() const { | |||
return (Intrinsic::ID)getCalledFunction()->getIntrinsicID(); | return (Intrinsic::ID)getCalledFunction()->getIntrinsicID(); | |||
} | } | |||
// Methods for support type inquiry through isa, cast, and dyn_cast: | // Methods for support type inquiry through isa, cast, and dyn_cast: | |||
static inline bool classof(const CallInst *I) { | static inline bool classof(const CallInst *I) { | |||
if (const Function *CF = I->getCalledFunction()) | if (const Function *CF = I->getCalledFunction()) | |||
return CF->getIntrinsicID() != 0; | return CF->isIntrinsic(); | |||
return false; | return false; | |||
} | } | |||
static inline bool classof(const Value *V) { | static inline bool classof(const Value *V) { | |||
return isa<CallInst>(V) && classof(cast<CallInst>(V)); | return isa<CallInst>(V) && classof(cast<CallInst>(V)); | |||
} | } | |||
}; | }; | |||
/// DbgInfoIntrinsic - This is the common base class for debug info intri nsics | /// DbgInfoIntrinsic - This is the common base class for debug info intri nsics | |||
/// | /// | |||
class DbgInfoIntrinsic : public IntrinsicInst { | class DbgInfoIntrinsic : public IntrinsicInst { | |||
End of changes. 3 change blocks. | ||||
7 lines changed or deleted | 7 lines changed or added | |||
IntrinsicLowering.h | IntrinsicLowering.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file defines the IntrinsicLowering interface. This interface allow s | // This file defines the IntrinsicLowering interface. This interface allow s | |||
// addition of domain-specific or front-end specific intrinsics to LLVM wit hout | // addition of domain-specific or front-end specific intrinsics to LLVM wit hout | |||
// having to modify all of the C backend or interpreter. | // having to modify all of the C backend or interpreter. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_INTRINSICLOWERING_H | #ifndef LLVM_CODEGEN_INTRINSICLOWERING_H | |||
#define LLVM_CODEGEN_INTRINSICLOWERING_H | #define LLVM_CODEGEN_INTRINSICLOWERING_H | |||
#include "llvm/Intrinsics.h" | #include "llvm/IR/Intrinsics.h" | |||
namespace llvm { | namespace llvm { | |||
class CallInst; | class CallInst; | |||
class Module; | class Module; | |||
class DataLayout; | class DataLayout; | |||
class IntrinsicLowering { | class IntrinsicLowering { | |||
const DataLayout& TD; | const DataLayout& TD; | |||
bool Warned; | bool Warned; | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Intrinsics.gen | Intrinsics.gen | |||
---|---|---|---|---|
/*===- TableGen'erated file -------------------------------------*- C++ -*- ===*\ | /*===- TableGen'erated file -------------------------------------*- C++ -*- ===*\ | |||
|* *| | |* *| | |||
|* Intrinsic Function Source Fragment *| | |*Intrinsic Function Source Fragment *| | |||
|* *| | |* *| | |||
|* Automatically generated file, do not edit! *| | |* Automatically generated file, do not edit! *| | |||
|* *| | |* *| | |||
\*===---------------------------------------------------------------------- ===*/ | \*===---------------------------------------------------------------------- ===*/ | |||
// VisualStudio defines setjmp as _setjmp | // VisualStudio defines setjmp as _setjmp | |||
#if defined(_MSC_VER) && defined(setjmp) && \ | #if defined(_MSC_VER) && defined(setjmp) && \ | |||
!defined(setjmp_undefined_for_msvc) | !defined(setjmp_undefined_for_msvc) | |||
# pragma push_macro("setjmp") | # pragma push_macro("setjmp") | |||
# undef setjmp | # undef setjmp | |||
skipping to change at line 145 | skipping to change at line 145 | |||
arm_qadd, // llvm.arm.qadd | arm_qadd, // llvm.arm.qadd | |||
arm_qsub, // llvm.arm.qsub | arm_qsub, // llvm.arm.qsub | |||
arm_set_fpscr, // llvm.arm.set.fpscr | arm_set_fpscr, // llvm.arm.set.fpscr | |||
arm_ssat, // llvm.arm.ssat | arm_ssat, // llvm.arm.ssat | |||
arm_strexd, // llvm.arm.strexd | arm_strexd, // llvm.arm.strexd | |||
arm_thread_pointer, // llvm.arm.thread.pointer | arm_thread_pointer, // llvm.arm.thread.pointer | |||
arm_usat, // llvm.arm.usat | arm_usat, // llvm.arm.usat | |||
arm_vcvtr, // llvm.arm.vcvtr | arm_vcvtr, // llvm.arm.vcvtr | |||
arm_vcvtru, // llvm.arm.vcvtru | arm_vcvtru, // llvm.arm.vcvtru | |||
bswap, // llvm.bswap | bswap, // llvm.bswap | |||
ceil, // llvm.ceil | ||||
convert_from_fp16, // llvm.convert.from.fp16 | convert_from_fp16, // llvm.convert.from.fp16 | |||
convert_to_fp16, // llvm.convert.to.fp16 | convert_to_fp16, // llvm.convert.to.fp16 | |||
convertff, // llvm.convertff | convertff, // llvm.convertff | |||
convertfsi, // llvm.convertfsi | convertfsi, // llvm.convertfsi | |||
convertfui, // llvm.convertfui | convertfui, // llvm.convertfui | |||
convertsif, // llvm.convertsif | convertsif, // llvm.convertsif | |||
convertss, // llvm.convertss | convertss, // llvm.convertss | |||
convertsu, // llvm.convertsu | convertsu, // llvm.convertsu | |||
convertuif, // llvm.convertuif | convertuif, // llvm.convertuif | |||
convertus, // llvm.convertus | convertus, // llvm.convertus | |||
skipping to change at line 1187 | skipping to change at line 1188 | |||
mips_subqh_r_ph, // llvm.mips.subqh.r.ph | mips_subqh_r_ph, // llvm.mips.subqh.r.ph | |||
mips_subqh_r_w, // llvm.mips.subqh.r.w | mips_subqh_r_w, // llvm.mips.subqh.r.w | |||
mips_subqh_w, // llvm.mips.subqh.w | mips_subqh_w, // llvm.mips.subqh.w | |||
mips_subu_ph, // llvm.mips.subu.ph | mips_subu_ph, // llvm.mips.subu.ph | |||
mips_subu_qb, // llvm.mips.subu.qb | mips_subu_qb, // llvm.mips.subu.qb | |||
mips_subu_s_ph, // llvm.mips.subu.s.ph | mips_subu_s_ph, // llvm.mips.subu.s.ph | |||
mips_subu_s_qb, // llvm.mips.subu.s.qb | mips_subu_s_qb, // llvm.mips.subu.s.qb | |||
mips_subuh_qb, // llvm.mips.subuh.qb | mips_subuh_qb, // llvm.mips.subuh.qb | |||
mips_subuh_r_qb, // llvm.mips.subuh.r.qb | mips_subuh_r_qb, // llvm.mips.subuh.r.qb | |||
mips_wrdsp, // llvm.mips.wrdsp | mips_wrdsp, // llvm.mips.wrdsp | |||
nearbyint, // llvm.nearbyint | ||||
nvvm_abs_i, // llvm.nvvm.abs.i | nvvm_abs_i, // llvm.nvvm.abs.i | |||
nvvm_abs_ll, // llvm.nvvm.abs.ll | nvvm_abs_ll, // llvm.nvvm.abs.ll | |||
nvvm_add_rm_d, // llvm.nvvm.add.rm.d | nvvm_add_rm_d, // llvm.nvvm.add.rm.d | |||
nvvm_add_rm_f, // llvm.nvvm.add.rm.f | nvvm_add_rm_f, // llvm.nvvm.add.rm.f | |||
nvvm_add_rm_ftz_f, // llvm.nvvm.add.rm.ftz.f | nvvm_add_rm_ftz_f, // llvm.nvvm.add.rm.ftz.f | |||
nvvm_add_rn_d, // llvm.nvvm.add.rn.d | nvvm_add_rn_d, // llvm.nvvm.add.rn.d | |||
nvvm_add_rn_f, // llvm.nvvm.add.rn.f | nvvm_add_rn_f, // llvm.nvvm.add.rn.f | |||
nvvm_add_rn_ftz_f, // llvm.nvvm.add.rn.ftz.f | nvvm_add_rn_ftz_f, // llvm.nvvm.add.rn.ftz.f | |||
nvvm_add_rp_d, // llvm.nvvm.add.rp.d | nvvm_add_rp_d, // llvm.nvvm.add.rp.d | |||
nvvm_add_rp_f, // llvm.nvvm.add.rp.f | nvvm_add_rp_f, // llvm.nvvm.add.rp.f | |||
skipping to change at line 1333 | skipping to change at line 1335 | |||
nvvm_fmin_ftz_f, // llvm.nvvm.fmin.ftz.f | nvvm_fmin_ftz_f, // llvm.nvvm.fmin.ftz.f | |||
nvvm_h2f, // llvm.nvvm.h2f | nvvm_h2f, // llvm.nvvm.h2f | |||
nvvm_i2d_rm, // llvm.nvvm.i2d.rm | nvvm_i2d_rm, // llvm.nvvm.i2d.rm | |||
nvvm_i2d_rn, // llvm.nvvm.i2d.rn | nvvm_i2d_rn, // llvm.nvvm.i2d.rn | |||
nvvm_i2d_rp, // llvm.nvvm.i2d.rp | nvvm_i2d_rp, // llvm.nvvm.i2d.rp | |||
nvvm_i2d_rz, // llvm.nvvm.i2d.rz | nvvm_i2d_rz, // llvm.nvvm.i2d.rz | |||
nvvm_i2f_rm, // llvm.nvvm.i2f.rm | nvvm_i2f_rm, // llvm.nvvm.i2f.rm | |||
nvvm_i2f_rn, // llvm.nvvm.i2f.rn | nvvm_i2f_rn, // llvm.nvvm.i2f.rn | |||
nvvm_i2f_rp, // llvm.nvvm.i2f.rp | nvvm_i2f_rp, // llvm.nvvm.i2f.rp | |||
nvvm_i2f_rz, // llvm.nvvm.i2f.rz | nvvm_i2f_rz, // llvm.nvvm.i2f.rz | |||
nvvm_ldg_global_f, // llvm.nvvm.ldg.global.f | ||||
nvvm_ldg_global_i, // llvm.nvvm.ldg.global.i | ||||
nvvm_ldg_global_p, // llvm.nvvm.ldg.global.p | ||||
nvvm_ldu_global_f, // llvm.nvvm.ldu.global.f | nvvm_ldu_global_f, // llvm.nvvm.ldu.global.f | |||
nvvm_ldu_global_i, // llvm.nvvm.ldu.global.i | nvvm_ldu_global_i, // llvm.nvvm.ldu.global.i | |||
nvvm_ldu_global_p, // llvm.nvvm.ldu.global.p | nvvm_ldu_global_p, // llvm.nvvm.ldu.global.p | |||
nvvm_lg2_approx_d, // llvm.nvvm.lg2.approx.d | nvvm_lg2_approx_d, // llvm.nvvm.lg2.approx.d | |||
nvvm_lg2_approx_f, // llvm.nvvm.lg2.approx.f | nvvm_lg2_approx_f, // llvm.nvvm.lg2.approx.f | |||
nvvm_lg2_approx_ftz_f, // llvm.nvvm.lg2.approx.ftz.f | nvvm_lg2_approx_ftz_f, // llvm.nvvm.lg2.approx.ftz.f | |||
nvvm_ll2d_rm, // llvm.nvvm.ll2d.rm | nvvm_ll2d_rm, // llvm.nvvm.ll2d.rm | |||
nvvm_ll2d_rn, // llvm.nvvm.ll2d.rn | nvvm_ll2d_rn, // llvm.nvvm.ll2d.rn | |||
nvvm_ll2d_rp, // llvm.nvvm.ll2d.rp | nvvm_ll2d_rp, // llvm.nvvm.ll2d.rp | |||
nvvm_ll2d_rz, // llvm.nvvm.ll2d.rz | nvvm_ll2d_rz, // llvm.nvvm.ll2d.rz | |||
skipping to change at line 1437 | skipping to change at line 1442 | |||
nvvm_rsqrt_approx_ftz_f, // llvm.nvvm.rsqrt.approx.ftz .f | nvvm_rsqrt_approx_ftz_f, // llvm.nvvm.rsqrt.approx.ftz .f | |||
nvvm_sad_i, // llvm.nvvm.sad.i | nvvm_sad_i, // llvm.nvvm.sad.i | |||
nvvm_sad_ui, // llvm.nvvm.sad.ui | nvvm_sad_ui, // llvm.nvvm.sad.ui | |||
nvvm_saturate_d, // llvm.nvvm.saturate.d | nvvm_saturate_d, // llvm.nvvm.saturate.d | |||
nvvm_saturate_f, // llvm.nvvm.saturate.f | nvvm_saturate_f, // llvm.nvvm.saturate.f | |||
nvvm_saturate_ftz_f, // llvm.nvvm.saturate.ftz.f | nvvm_saturate_ftz_f, // llvm.nvvm.saturate.ftz.f | |||
nvvm_sin_approx_f, // llvm.nvvm.sin.approx.f | nvvm_sin_approx_f, // llvm.nvvm.sin.approx.f | |||
nvvm_sin_approx_ftz_f, // llvm.nvvm.sin.approx.ftz.f | nvvm_sin_approx_ftz_f, // llvm.nvvm.sin.approx.ftz.f | |||
nvvm_sqrt_approx_f, // llvm.nvvm.sqrt.approx.f | nvvm_sqrt_approx_f, // llvm.nvvm.sqrt.approx.f | |||
nvvm_sqrt_approx_ftz_f, // llvm.nvvm.sqrt.approx.ftz. f | nvvm_sqrt_approx_ftz_f, // llvm.nvvm.sqrt.approx.ftz. f | |||
nvvm_sqrt_f, // llvm.nvvm.sqrt.f | ||||
nvvm_sqrt_rm_d, // llvm.nvvm.sqrt.rm.d | nvvm_sqrt_rm_d, // llvm.nvvm.sqrt.rm.d | |||
nvvm_sqrt_rm_f, // llvm.nvvm.sqrt.rm.f | nvvm_sqrt_rm_f, // llvm.nvvm.sqrt.rm.f | |||
nvvm_sqrt_rm_ftz_f, // llvm.nvvm.sqrt.rm.ftz.f | nvvm_sqrt_rm_ftz_f, // llvm.nvvm.sqrt.rm.ftz.f | |||
nvvm_sqrt_rn_d, // llvm.nvvm.sqrt.rn.d | nvvm_sqrt_rn_d, // llvm.nvvm.sqrt.rn.d | |||
nvvm_sqrt_rn_f, // llvm.nvvm.sqrt.rn.f | nvvm_sqrt_rn_f, // llvm.nvvm.sqrt.rn.f | |||
nvvm_sqrt_rn_ftz_f, // llvm.nvvm.sqrt.rn.ftz.f | nvvm_sqrt_rn_ftz_f, // llvm.nvvm.sqrt.rn.ftz.f | |||
nvvm_sqrt_rp_d, // llvm.nvvm.sqrt.rp.d | nvvm_sqrt_rp_d, // llvm.nvvm.sqrt.rp.d | |||
nvvm_sqrt_rp_f, // llvm.nvvm.sqrt.rp.f | nvvm_sqrt_rp_f, // llvm.nvvm.sqrt.rp.f | |||
nvvm_sqrt_rp_ftz_f, // llvm.nvvm.sqrt.rp.ftz.f | nvvm_sqrt_rp_ftz_f, // llvm.nvvm.sqrt.rp.ftz.f | |||
nvvm_sqrt_rz_d, // llvm.nvvm.sqrt.rz.d | nvvm_sqrt_rz_d, // llvm.nvvm.sqrt.rz.d | |||
skipping to change at line 1664 | skipping to change at line 1670 | |||
ptx_read_pm0, // llvm.ptx.read.pm0 | ptx_read_pm0, // llvm.ptx.read.pm0 | |||
ptx_read_pm1, // llvm.ptx.read.pm1 | ptx_read_pm1, // llvm.ptx.read.pm1 | |||
ptx_read_pm2, // llvm.ptx.read.pm2 | ptx_read_pm2, // llvm.ptx.read.pm2 | |||
ptx_read_pm3, // llvm.ptx.read.pm3 | ptx_read_pm3, // llvm.ptx.read.pm3 | |||
ptx_read_smid, // llvm.ptx.read.smid | ptx_read_smid, // llvm.ptx.read.smid | |||
ptx_read_tid_w, // llvm.ptx.read.tid.w | ptx_read_tid_w, // llvm.ptx.read.tid.w | |||
ptx_read_tid_x, // llvm.ptx.read.tid.x | ptx_read_tid_x, // llvm.ptx.read.tid.x | |||
ptx_read_tid_y, // llvm.ptx.read.tid.y | ptx_read_tid_y, // llvm.ptx.read.tid.y | |||
ptx_read_tid_z, // llvm.ptx.read.tid.z | ptx_read_tid_z, // llvm.ptx.read.tid.z | |||
ptx_read_warpid, // llvm.ptx.read.warpid | ptx_read_warpid, // llvm.ptx.read.warpid | |||
r600_read_global_size_x, // llvm.r600.read.global.size | ||||
.x | ||||
r600_read_global_size_y, // llvm.r600.read.global.size | ||||
.y | ||||
r600_read_global_size_z, // llvm.r600.read.global.size | ||||
.z | ||||
r600_read_local_size_x, // llvm.r600.read.local.size. | ||||
x | ||||
r600_read_local_size_y, // llvm.r600.read.local.size. | ||||
y | ||||
r600_read_local_size_z, // llvm.r600.read.local.size. | ||||
z | ||||
r600_read_ngroups_x, // llvm.r600.read.ngroups.x | ||||
r600_read_ngroups_y, // llvm.r600.read.ngroups.y | ||||
r600_read_ngroups_z, // llvm.r600.read.ngroups.z | ||||
r600_read_tgid_x, // llvm.r600.read.tgid.x | ||||
r600_read_tgid_y, // llvm.r600.read.tgid.y | ||||
r600_read_tgid_z, // llvm.r600.read.tgid.z | ||||
r600_read_tidig_x, // llvm.r600.read.tidig.x | ||||
r600_read_tidig_y, // llvm.r600.read.tidig.y | ||||
r600_read_tidig_z, // llvm.r600.read.tidig.z | ||||
readcyclecounter, // llvm.readcyclecounter | readcyclecounter, // llvm.readcyclecounter | |||
returnaddress, // llvm.returnaddress | returnaddress, // llvm.returnaddress | |||
rint, // llvm.rint | ||||
sadd_with_overflow, // llvm.sadd.with.overflow | sadd_with_overflow, // llvm.sadd.with.overflow | |||
setjmp, // llvm.setjmp | setjmp, // llvm.setjmp | |||
siglongjmp, // llvm.siglongjmp | siglongjmp, // llvm.siglongjmp | |||
sigsetjmp, // llvm.sigsetjmp | sigsetjmp, // llvm.sigsetjmp | |||
sin, // llvm.sin | sin, // llvm.sin | |||
smul_with_overflow, // llvm.smul.with.overflow | smul_with_overflow, // llvm.smul.with.overflow | |||
spu_si_a, // llvm.spu.si.a | ||||
spu_si_addx, // llvm.spu.si.addx | ||||
spu_si_ah, // llvm.spu.si.ah | ||||
spu_si_ahi, // llvm.spu.si.ahi | ||||
spu_si_ai, // llvm.spu.si.ai | ||||
spu_si_and, // llvm.spu.si.and | ||||
spu_si_andbi, // llvm.spu.si.andbi | ||||
spu_si_andc, // llvm.spu.si.andc | ||||
spu_si_andhi, // llvm.spu.si.andhi | ||||
spu_si_andi, // llvm.spu.si.andi | ||||
spu_si_bg, // llvm.spu.si.bg | ||||
spu_si_bgx, // llvm.spu.si.bgx | ||||
spu_si_ceq, // llvm.spu.si.ceq | ||||
spu_si_ceqb, // llvm.spu.si.ceqb | ||||
spu_si_ceqbi, // llvm.spu.si.ceqbi | ||||
spu_si_ceqh, // llvm.spu.si.ceqh | ||||
spu_si_ceqhi, // llvm.spu.si.ceqhi | ||||
spu_si_ceqi, // llvm.spu.si.ceqi | ||||
spu_si_cg, // llvm.spu.si.cg | ||||
spu_si_cgt, // llvm.spu.si.cgt | ||||
spu_si_cgtb, // llvm.spu.si.cgtb | ||||
spu_si_cgtbi, // llvm.spu.si.cgtbi | ||||
spu_si_cgth, // llvm.spu.si.cgth | ||||
spu_si_cgthi, // llvm.spu.si.cgthi | ||||
spu_si_cgti, // llvm.spu.si.cgti | ||||
spu_si_cgx, // llvm.spu.si.cgx | ||||
spu_si_clgt, // llvm.spu.si.clgt | ||||
spu_si_clgtb, // llvm.spu.si.clgtb | ||||
spu_si_clgtbi, // llvm.spu.si.clgtbi | ||||
spu_si_clgth, // llvm.spu.si.clgth | ||||
spu_si_clgthi, // llvm.spu.si.clgthi | ||||
spu_si_clgti, // llvm.spu.si.clgti | ||||
spu_si_dfa, // llvm.spu.si.dfa | ||||
spu_si_dfm, // llvm.spu.si.dfm | ||||
spu_si_dfma, // llvm.spu.si.dfma | ||||
spu_si_dfms, // llvm.spu.si.dfms | ||||
spu_si_dfnma, // llvm.spu.si.dfnma | ||||
spu_si_dfnms, // llvm.spu.si.dfnms | ||||
spu_si_dfs, // llvm.spu.si.dfs | ||||
spu_si_fa, // llvm.spu.si.fa | ||||
spu_si_fceq, // llvm.spu.si.fceq | ||||
spu_si_fcgt, // llvm.spu.si.fcgt | ||||
spu_si_fcmeq, // llvm.spu.si.fcmeq | ||||
spu_si_fcmgt, // llvm.spu.si.fcmgt | ||||
spu_si_fm, // llvm.spu.si.fm | ||||
spu_si_fma, // llvm.spu.si.fma | ||||
spu_si_fms, // llvm.spu.si.fms | ||||
spu_si_fnms, // llvm.spu.si.fnms | ||||
spu_si_fs, // llvm.spu.si.fs | ||||
spu_si_fsmbi, // llvm.spu.si.fsmbi | ||||
spu_si_mpy, // llvm.spu.si.mpy | ||||
spu_si_mpya, // llvm.spu.si.mpya | ||||
spu_si_mpyh, // llvm.spu.si.mpyh | ||||
spu_si_mpyhh, // llvm.spu.si.mpyhh | ||||
spu_si_mpyhha, // llvm.spu.si.mpyhha | ||||
spu_si_mpyhhau, // llvm.spu.si.mpyhhau | ||||
spu_si_mpyhhu, // llvm.spu.si.mpyhhu | ||||
spu_si_mpyi, // llvm.spu.si.mpyi | ||||
spu_si_mpys, // llvm.spu.si.mpys | ||||
spu_si_mpyu, // llvm.spu.si.mpyu | ||||
spu_si_mpyui, // llvm.spu.si.mpyui | ||||
spu_si_nand, // llvm.spu.si.nand | ||||
spu_si_nor, // llvm.spu.si.nor | ||||
spu_si_or, // llvm.spu.si.or | ||||
spu_si_orbi, // llvm.spu.si.orbi | ||||
spu_si_orc, // llvm.spu.si.orc | ||||
spu_si_orhi, // llvm.spu.si.orhi | ||||
spu_si_ori, // llvm.spu.si.ori | ||||
spu_si_sf, // llvm.spu.si.sf | ||||
spu_si_sfh, // llvm.spu.si.sfh | ||||
spu_si_sfhi, // llvm.spu.si.sfhi | ||||
spu_si_sfi, // llvm.spu.si.sfi | ||||
spu_si_sfx, // llvm.spu.si.sfx | ||||
spu_si_shli, // llvm.spu.si.shli | ||||
spu_si_shlqbi, // llvm.spu.si.shlqbi | ||||
spu_si_shlqbii, // llvm.spu.si.shlqbii | ||||
spu_si_shlqby, // llvm.spu.si.shlqby | ||||
spu_si_shlqbyi, // llvm.spu.si.shlqbyi | ||||
spu_si_xor, // llvm.spu.si.xor | ||||
spu_si_xorbi, // llvm.spu.si.xorbi | ||||
spu_si_xorhi, // llvm.spu.si.xorhi | ||||
spu_si_xori, // llvm.spu.si.xori | ||||
sqrt, // llvm.sqrt | sqrt, // llvm.sqrt | |||
ssub_with_overflow, // llvm.ssub.with.overflow | ssub_with_overflow, // llvm.ssub.with.overflow | |||
stackprotector, // llvm.stackprotector | stackprotector, // llvm.stackprotector | |||
stackrestore, // llvm.stackrestore | stackrestore, // llvm.stackrestore | |||
stacksave, // llvm.stacksave | stacksave, // llvm.stacksave | |||
trap, // llvm.trap | trap, // llvm.trap | |||
trunc, // llvm.trunc | ||||
uadd_with_overflow, // llvm.uadd.with.overflow | uadd_with_overflow, // llvm.uadd.with.overflow | |||
umul_with_overflow, // llvm.umul.with.overflow | umul_with_overflow, // llvm.umul.with.overflow | |||
usub_with_overflow, // llvm.usub.with.overflow | usub_with_overflow, // llvm.usub.with.overflow | |||
vacopy, // llvm.va_copy | vacopy, // llvm.va_copy | |||
vaend, // llvm.va_end | vaend, // llvm.va_end | |||
var_annotation, // llvm.var.annotation | var_annotation, // llvm.var.annotation | |||
vastart, // llvm.va_start | vastart, // llvm.va_start | |||
x86_3dnow_pavgusb, // llvm.x86.3dnow.pavgusb | x86_3dnow_pavgusb, // llvm.x86.3dnow.pavgusb | |||
x86_3dnow_pf2id, // llvm.x86.3dnow.pf2id | x86_3dnow_pf2id, // llvm.x86.3dnow.pf2id | |||
x86_3dnow_pfacc, // llvm.x86.3dnow.pfacc | x86_3dnow_pfacc, // llvm.x86.3dnow.pfacc | |||
skipping to change at line 2134 | skipping to change at line 2075 | |||
x86_mmx_punpcklwd, // llvm.x86.mmx.punpcklwd | x86_mmx_punpcklwd, // llvm.x86.mmx.punpcklwd | |||
x86_mmx_pxor, // llvm.x86.mmx.pxor | x86_mmx_pxor, // llvm.x86.mmx.pxor | |||
x86_pclmulqdq, // llvm.x86.pclmulqdq | x86_pclmulqdq, // llvm.x86.pclmulqdq | |||
x86_rdfsbase_32, // llvm.x86.rdfsbase.32 | x86_rdfsbase_32, // llvm.x86.rdfsbase.32 | |||
x86_rdfsbase_64, // llvm.x86.rdfsbase.64 | x86_rdfsbase_64, // llvm.x86.rdfsbase.64 | |||
x86_rdgsbase_32, // llvm.x86.rdgsbase.32 | x86_rdgsbase_32, // llvm.x86.rdgsbase.32 | |||
x86_rdgsbase_64, // llvm.x86.rdgsbase.64 | x86_rdgsbase_64, // llvm.x86.rdgsbase.64 | |||
x86_rdrand_16, // llvm.x86.rdrand.16 | x86_rdrand_16, // llvm.x86.rdrand.16 | |||
x86_rdrand_32, // llvm.x86.rdrand.32 | x86_rdrand_32, // llvm.x86.rdrand.32 | |||
x86_rdrand_64, // llvm.x86.rdrand.64 | x86_rdrand_64, // llvm.x86.rdrand.64 | |||
x86_rdseed_16, // llvm.x86.rdseed.16 | ||||
x86_rdseed_32, // llvm.x86.rdseed.32 | ||||
x86_rdseed_64, // llvm.x86.rdseed.64 | ||||
x86_sse2_add_sd, // llvm.x86.sse2.add.sd | x86_sse2_add_sd, // llvm.x86.sse2.add.sd | |||
x86_sse2_clflush, // llvm.x86.sse2.clflush | x86_sse2_clflush, // llvm.x86.sse2.clflush | |||
x86_sse2_cmp_pd, // llvm.x86.sse2.cmp.pd | x86_sse2_cmp_pd, // llvm.x86.sse2.cmp.pd | |||
x86_sse2_cmp_sd, // llvm.x86.sse2.cmp.sd | x86_sse2_cmp_sd, // llvm.x86.sse2.cmp.sd | |||
x86_sse2_comieq_sd, // llvm.x86.sse2.comieq.sd | x86_sse2_comieq_sd, // llvm.x86.sse2.comieq.sd | |||
x86_sse2_comige_sd, // llvm.x86.sse2.comige.sd | x86_sse2_comige_sd, // llvm.x86.sse2.comige.sd | |||
x86_sse2_comigt_sd, // llvm.x86.sse2.comigt.sd | x86_sse2_comigt_sd, // llvm.x86.sse2.comigt.sd | |||
x86_sse2_comile_sd, // llvm.x86.sse2.comile.sd | x86_sse2_comile_sd, // llvm.x86.sse2.comile.sd | |||
x86_sse2_comilt_sd, // llvm.x86.sse2.comilt.sd | x86_sse2_comilt_sd, // llvm.x86.sse2.comilt.sd | |||
x86_sse2_comineq_sd, // llvm.x86.sse2.comineq.sd | x86_sse2_comineq_sd, // llvm.x86.sse2.comineq.sd | |||
skipping to change at line 2455 | skipping to change at line 2399 | |||
x86_xop_vprotw, // llvm.x86.xop.vprotw | x86_xop_vprotw, // llvm.x86.xop.vprotw | |||
x86_xop_vprotwi, // llvm.x86.xop.vprotwi | x86_xop_vprotwi, // llvm.x86.xop.vprotwi | |||
x86_xop_vpshab, // llvm.x86.xop.vpshab | x86_xop_vpshab, // llvm.x86.xop.vpshab | |||
x86_xop_vpshad, // llvm.x86.xop.vpshad | x86_xop_vpshad, // llvm.x86.xop.vpshad | |||
x86_xop_vpshaq, // llvm.x86.xop.vpshaq | x86_xop_vpshaq, // llvm.x86.xop.vpshaq | |||
x86_xop_vpshaw, // llvm.x86.xop.vpshaw | x86_xop_vpshaw, // llvm.x86.xop.vpshaw | |||
x86_xop_vpshlb, // llvm.x86.xop.vpshlb | x86_xop_vpshlb, // llvm.x86.xop.vpshlb | |||
x86_xop_vpshld, // llvm.x86.xop.vpshld | x86_xop_vpshld, // llvm.x86.xop.vpshld | |||
x86_xop_vpshlq, // llvm.x86.xop.vpshlq | x86_xop_vpshlq, // llvm.x86.xop.vpshlq | |||
x86_xop_vpshlw, // llvm.x86.xop.vpshlw | x86_xop_vpshlw, // llvm.x86.xop.vpshlw | |||
x86_xtest, // llvm.x86.xtest | ||||
xcore_bitrev, // llvm.xcore.bitrev | xcore_bitrev, // llvm.xcore.bitrev | |||
xcore_checkevent, // llvm.xcore.checkevent | xcore_checkevent, // llvm.xcore.checkevent | |||
xcore_chkct, // llvm.xcore.chkct | xcore_chkct, // llvm.xcore.chkct | |||
xcore_clre, // llvm.xcore.clre | xcore_clre, // llvm.xcore.clre | |||
xcore_clrsr, // llvm.xcore.clrsr | xcore_clrsr, // llvm.xcore.clrsr | |||
xcore_crc32, // llvm.xcore.crc32 | xcore_crc32, // llvm.xcore.crc32 | |||
xcore_crc8, // llvm.xcore.crc8 | xcore_crc8, // llvm.xcore.crc8 | |||
xcore_eeu, // llvm.xcore.eeu | xcore_eeu, // llvm.xcore.eeu | |||
xcore_endin, // llvm.xcore.endin | xcore_endin, // llvm.xcore.endin | |||
xcore_freer, // llvm.xcore.freer | xcore_freer, // llvm.xcore.freer | |||
skipping to change at line 2637 | skipping to change at line 2582 | |||
"llvm.arm.qadd", | "llvm.arm.qadd", | |||
"llvm.arm.qsub", | "llvm.arm.qsub", | |||
"llvm.arm.set.fpscr", | "llvm.arm.set.fpscr", | |||
"llvm.arm.ssat", | "llvm.arm.ssat", | |||
"llvm.arm.strexd", | "llvm.arm.strexd", | |||
"llvm.arm.thread.pointer", | "llvm.arm.thread.pointer", | |||
"llvm.arm.usat", | "llvm.arm.usat", | |||
"llvm.arm.vcvtr", | "llvm.arm.vcvtr", | |||
"llvm.arm.vcvtru", | "llvm.arm.vcvtru", | |||
"llvm.bswap", | "llvm.bswap", | |||
"llvm.ceil", | ||||
"llvm.convert.from.fp16", | "llvm.convert.from.fp16", | |||
"llvm.convert.to.fp16", | "llvm.convert.to.fp16", | |||
"llvm.convertff", | "llvm.convertff", | |||
"llvm.convertfsi", | "llvm.convertfsi", | |||
"llvm.convertfui", | "llvm.convertfui", | |||
"llvm.convertsif", | "llvm.convertsif", | |||
"llvm.convertss", | "llvm.convertss", | |||
"llvm.convertsu", | "llvm.convertsu", | |||
"llvm.convertuif", | "llvm.convertuif", | |||
"llvm.convertus", | "llvm.convertus", | |||
skipping to change at line 3679 | skipping to change at line 3625 | |||
"llvm.mips.subqh.r.ph", | "llvm.mips.subqh.r.ph", | |||
"llvm.mips.subqh.r.w", | "llvm.mips.subqh.r.w", | |||
"llvm.mips.subqh.w", | "llvm.mips.subqh.w", | |||
"llvm.mips.subu.ph", | "llvm.mips.subu.ph", | |||
"llvm.mips.subu.qb", | "llvm.mips.subu.qb", | |||
"llvm.mips.subu.s.ph", | "llvm.mips.subu.s.ph", | |||
"llvm.mips.subu.s.qb", | "llvm.mips.subu.s.qb", | |||
"llvm.mips.subuh.qb", | "llvm.mips.subuh.qb", | |||
"llvm.mips.subuh.r.qb", | "llvm.mips.subuh.r.qb", | |||
"llvm.mips.wrdsp", | "llvm.mips.wrdsp", | |||
"llvm.nearbyint", | ||||
"llvm.nvvm.abs.i", | "llvm.nvvm.abs.i", | |||
"llvm.nvvm.abs.ll", | "llvm.nvvm.abs.ll", | |||
"llvm.nvvm.add.rm.d", | "llvm.nvvm.add.rm.d", | |||
"llvm.nvvm.add.rm.f", | "llvm.nvvm.add.rm.f", | |||
"llvm.nvvm.add.rm.ftz.f", | "llvm.nvvm.add.rm.ftz.f", | |||
"llvm.nvvm.add.rn.d", | "llvm.nvvm.add.rn.d", | |||
"llvm.nvvm.add.rn.f", | "llvm.nvvm.add.rn.f", | |||
"llvm.nvvm.add.rn.ftz.f", | "llvm.nvvm.add.rn.ftz.f", | |||
"llvm.nvvm.add.rp.d", | "llvm.nvvm.add.rp.d", | |||
"llvm.nvvm.add.rp.f", | "llvm.nvvm.add.rp.f", | |||
skipping to change at line 3825 | skipping to change at line 3772 | |||
"llvm.nvvm.fmin.ftz.f", | "llvm.nvvm.fmin.ftz.f", | |||
"llvm.nvvm.h2f", | "llvm.nvvm.h2f", | |||
"llvm.nvvm.i2d.rm", | "llvm.nvvm.i2d.rm", | |||
"llvm.nvvm.i2d.rn", | "llvm.nvvm.i2d.rn", | |||
"llvm.nvvm.i2d.rp", | "llvm.nvvm.i2d.rp", | |||
"llvm.nvvm.i2d.rz", | "llvm.nvvm.i2d.rz", | |||
"llvm.nvvm.i2f.rm", | "llvm.nvvm.i2f.rm", | |||
"llvm.nvvm.i2f.rn", | "llvm.nvvm.i2f.rn", | |||
"llvm.nvvm.i2f.rp", | "llvm.nvvm.i2f.rp", | |||
"llvm.nvvm.i2f.rz", | "llvm.nvvm.i2f.rz", | |||
"llvm.nvvm.ldg.global.f", | ||||
"llvm.nvvm.ldg.global.i", | ||||
"llvm.nvvm.ldg.global.p", | ||||
"llvm.nvvm.ldu.global.f", | "llvm.nvvm.ldu.global.f", | |||
"llvm.nvvm.ldu.global.i", | "llvm.nvvm.ldu.global.i", | |||
"llvm.nvvm.ldu.global.p", | "llvm.nvvm.ldu.global.p", | |||
"llvm.nvvm.lg2.approx.d", | "llvm.nvvm.lg2.approx.d", | |||
"llvm.nvvm.lg2.approx.f", | "llvm.nvvm.lg2.approx.f", | |||
"llvm.nvvm.lg2.approx.ftz.f", | "llvm.nvvm.lg2.approx.ftz.f", | |||
"llvm.nvvm.ll2d.rm", | "llvm.nvvm.ll2d.rm", | |||
"llvm.nvvm.ll2d.rn", | "llvm.nvvm.ll2d.rn", | |||
"llvm.nvvm.ll2d.rp", | "llvm.nvvm.ll2d.rp", | |||
"llvm.nvvm.ll2d.rz", | "llvm.nvvm.ll2d.rz", | |||
skipping to change at line 3929 | skipping to change at line 3879 | |||
"llvm.nvvm.rsqrt.approx.ftz.f", | "llvm.nvvm.rsqrt.approx.ftz.f", | |||
"llvm.nvvm.sad.i", | "llvm.nvvm.sad.i", | |||
"llvm.nvvm.sad.ui", | "llvm.nvvm.sad.ui", | |||
"llvm.nvvm.saturate.d", | "llvm.nvvm.saturate.d", | |||
"llvm.nvvm.saturate.f", | "llvm.nvvm.saturate.f", | |||
"llvm.nvvm.saturate.ftz.f", | "llvm.nvvm.saturate.ftz.f", | |||
"llvm.nvvm.sin.approx.f", | "llvm.nvvm.sin.approx.f", | |||
"llvm.nvvm.sin.approx.ftz.f", | "llvm.nvvm.sin.approx.ftz.f", | |||
"llvm.nvvm.sqrt.approx.f", | "llvm.nvvm.sqrt.approx.f", | |||
"llvm.nvvm.sqrt.approx.ftz.f", | "llvm.nvvm.sqrt.approx.ftz.f", | |||
"llvm.nvvm.sqrt.f", | ||||
"llvm.nvvm.sqrt.rm.d", | "llvm.nvvm.sqrt.rm.d", | |||
"llvm.nvvm.sqrt.rm.f", | "llvm.nvvm.sqrt.rm.f", | |||
"llvm.nvvm.sqrt.rm.ftz.f", | "llvm.nvvm.sqrt.rm.ftz.f", | |||
"llvm.nvvm.sqrt.rn.d", | "llvm.nvvm.sqrt.rn.d", | |||
"llvm.nvvm.sqrt.rn.f", | "llvm.nvvm.sqrt.rn.f", | |||
"llvm.nvvm.sqrt.rn.ftz.f", | "llvm.nvvm.sqrt.rn.ftz.f", | |||
"llvm.nvvm.sqrt.rp.d", | "llvm.nvvm.sqrt.rp.d", | |||
"llvm.nvvm.sqrt.rp.f", | "llvm.nvvm.sqrt.rp.f", | |||
"llvm.nvvm.sqrt.rp.ftz.f", | "llvm.nvvm.sqrt.rp.ftz.f", | |||
"llvm.nvvm.sqrt.rz.d", | "llvm.nvvm.sqrt.rz.d", | |||
skipping to change at line 4156 | skipping to change at line 4107 | |||
"llvm.ptx.read.pm0", | "llvm.ptx.read.pm0", | |||
"llvm.ptx.read.pm1", | "llvm.ptx.read.pm1", | |||
"llvm.ptx.read.pm2", | "llvm.ptx.read.pm2", | |||
"llvm.ptx.read.pm3", | "llvm.ptx.read.pm3", | |||
"llvm.ptx.read.smid", | "llvm.ptx.read.smid", | |||
"llvm.ptx.read.tid.w", | "llvm.ptx.read.tid.w", | |||
"llvm.ptx.read.tid.x", | "llvm.ptx.read.tid.x", | |||
"llvm.ptx.read.tid.y", | "llvm.ptx.read.tid.y", | |||
"llvm.ptx.read.tid.z", | "llvm.ptx.read.tid.z", | |||
"llvm.ptx.read.warpid", | "llvm.ptx.read.warpid", | |||
"llvm.r600.read.global.size.x", | ||||
"llvm.r600.read.global.size.y", | ||||
"llvm.r600.read.global.size.z", | ||||
"llvm.r600.read.local.size.x", | ||||
"llvm.r600.read.local.size.y", | ||||
"llvm.r600.read.local.size.z", | ||||
"llvm.r600.read.ngroups.x", | ||||
"llvm.r600.read.ngroups.y", | ||||
"llvm.r600.read.ngroups.z", | ||||
"llvm.r600.read.tgid.x", | ||||
"llvm.r600.read.tgid.y", | ||||
"llvm.r600.read.tgid.z", | ||||
"llvm.r600.read.tidig.x", | ||||
"llvm.r600.read.tidig.y", | ||||
"llvm.r600.read.tidig.z", | ||||
"llvm.readcyclecounter", | "llvm.readcyclecounter", | |||
"llvm.returnaddress", | "llvm.returnaddress", | |||
"llvm.rint", | ||||
"llvm.sadd.with.overflow", | "llvm.sadd.with.overflow", | |||
"llvm.setjmp", | "llvm.setjmp", | |||
"llvm.siglongjmp", | "llvm.siglongjmp", | |||
"llvm.sigsetjmp", | "llvm.sigsetjmp", | |||
"llvm.sin", | "llvm.sin", | |||
"llvm.smul.with.overflow", | "llvm.smul.with.overflow", | |||
"llvm.spu.si.a", | ||||
"llvm.spu.si.addx", | ||||
"llvm.spu.si.ah", | ||||
"llvm.spu.si.ahi", | ||||
"llvm.spu.si.ai", | ||||
"llvm.spu.si.and", | ||||
"llvm.spu.si.andbi", | ||||
"llvm.spu.si.andc", | ||||
"llvm.spu.si.andhi", | ||||
"llvm.spu.si.andi", | ||||
"llvm.spu.si.bg", | ||||
"llvm.spu.si.bgx", | ||||
"llvm.spu.si.ceq", | ||||
"llvm.spu.si.ceqb", | ||||
"llvm.spu.si.ceqbi", | ||||
"llvm.spu.si.ceqh", | ||||
"llvm.spu.si.ceqhi", | ||||
"llvm.spu.si.ceqi", | ||||
"llvm.spu.si.cg", | ||||
"llvm.spu.si.cgt", | ||||
"llvm.spu.si.cgtb", | ||||
"llvm.spu.si.cgtbi", | ||||
"llvm.spu.si.cgth", | ||||
"llvm.spu.si.cgthi", | ||||
"llvm.spu.si.cgti", | ||||
"llvm.spu.si.cgx", | ||||
"llvm.spu.si.clgt", | ||||
"llvm.spu.si.clgtb", | ||||
"llvm.spu.si.clgtbi", | ||||
"llvm.spu.si.clgth", | ||||
"llvm.spu.si.clgthi", | ||||
"llvm.spu.si.clgti", | ||||
"llvm.spu.si.dfa", | ||||
"llvm.spu.si.dfm", | ||||
"llvm.spu.si.dfma", | ||||
"llvm.spu.si.dfms", | ||||
"llvm.spu.si.dfnma", | ||||
"llvm.spu.si.dfnms", | ||||
"llvm.spu.si.dfs", | ||||
"llvm.spu.si.fa", | ||||
"llvm.spu.si.fceq", | ||||
"llvm.spu.si.fcgt", | ||||
"llvm.spu.si.fcmeq", | ||||
"llvm.spu.si.fcmgt", | ||||
"llvm.spu.si.fm", | ||||
"llvm.spu.si.fma", | ||||
"llvm.spu.si.fms", | ||||
"llvm.spu.si.fnms", | ||||
"llvm.spu.si.fs", | ||||
"llvm.spu.si.fsmbi", | ||||
"llvm.spu.si.mpy", | ||||
"llvm.spu.si.mpya", | ||||
"llvm.spu.si.mpyh", | ||||
"llvm.spu.si.mpyhh", | ||||
"llvm.spu.si.mpyhha", | ||||
"llvm.spu.si.mpyhhau", | ||||
"llvm.spu.si.mpyhhu", | ||||
"llvm.spu.si.mpyi", | ||||
"llvm.spu.si.mpys", | ||||
"llvm.spu.si.mpyu", | ||||
"llvm.spu.si.mpyui", | ||||
"llvm.spu.si.nand", | ||||
"llvm.spu.si.nor", | ||||
"llvm.spu.si.or", | ||||
"llvm.spu.si.orbi", | ||||
"llvm.spu.si.orc", | ||||
"llvm.spu.si.orhi", | ||||
"llvm.spu.si.ori", | ||||
"llvm.spu.si.sf", | ||||
"llvm.spu.si.sfh", | ||||
"llvm.spu.si.sfhi", | ||||
"llvm.spu.si.sfi", | ||||
"llvm.spu.si.sfx", | ||||
"llvm.spu.si.shli", | ||||
"llvm.spu.si.shlqbi", | ||||
"llvm.spu.si.shlqbii", | ||||
"llvm.spu.si.shlqby", | ||||
"llvm.spu.si.shlqbyi", | ||||
"llvm.spu.si.xor", | ||||
"llvm.spu.si.xorbi", | ||||
"llvm.spu.si.xorhi", | ||||
"llvm.spu.si.xori", | ||||
"llvm.sqrt", | "llvm.sqrt", | |||
"llvm.ssub.with.overflow", | "llvm.ssub.with.overflow", | |||
"llvm.stackprotector", | "llvm.stackprotector", | |||
"llvm.stackrestore", | "llvm.stackrestore", | |||
"llvm.stacksave", | "llvm.stacksave", | |||
"llvm.trap", | "llvm.trap", | |||
"llvm.trunc", | ||||
"llvm.uadd.with.overflow", | "llvm.uadd.with.overflow", | |||
"llvm.umul.with.overflow", | "llvm.umul.with.overflow", | |||
"llvm.usub.with.overflow", | "llvm.usub.with.overflow", | |||
"llvm.va_copy", | "llvm.va_copy", | |||
"llvm.va_end", | "llvm.va_end", | |||
"llvm.var.annotation", | "llvm.var.annotation", | |||
"llvm.va_start", | "llvm.va_start", | |||
"llvm.x86.3dnow.pavgusb", | "llvm.x86.3dnow.pavgusb", | |||
"llvm.x86.3dnow.pf2id", | "llvm.x86.3dnow.pf2id", | |||
"llvm.x86.3dnow.pfacc", | "llvm.x86.3dnow.pfacc", | |||
skipping to change at line 4626 | skipping to change at line 4512 | |||
"llvm.x86.mmx.punpcklwd", | "llvm.x86.mmx.punpcklwd", | |||
"llvm.x86.mmx.pxor", | "llvm.x86.mmx.pxor", | |||
"llvm.x86.pclmulqdq", | "llvm.x86.pclmulqdq", | |||
"llvm.x86.rdfsbase.32", | "llvm.x86.rdfsbase.32", | |||
"llvm.x86.rdfsbase.64", | "llvm.x86.rdfsbase.64", | |||
"llvm.x86.rdgsbase.32", | "llvm.x86.rdgsbase.32", | |||
"llvm.x86.rdgsbase.64", | "llvm.x86.rdgsbase.64", | |||
"llvm.x86.rdrand.16", | "llvm.x86.rdrand.16", | |||
"llvm.x86.rdrand.32", | "llvm.x86.rdrand.32", | |||
"llvm.x86.rdrand.64", | "llvm.x86.rdrand.64", | |||
"llvm.x86.rdseed.16", | ||||
"llvm.x86.rdseed.32", | ||||
"llvm.x86.rdseed.64", | ||||
"llvm.x86.sse2.add.sd", | "llvm.x86.sse2.add.sd", | |||
"llvm.x86.sse2.clflush", | "llvm.x86.sse2.clflush", | |||
"llvm.x86.sse2.cmp.pd", | "llvm.x86.sse2.cmp.pd", | |||
"llvm.x86.sse2.cmp.sd", | "llvm.x86.sse2.cmp.sd", | |||
"llvm.x86.sse2.comieq.sd", | "llvm.x86.sse2.comieq.sd", | |||
"llvm.x86.sse2.comige.sd", | "llvm.x86.sse2.comige.sd", | |||
"llvm.x86.sse2.comigt.sd", | "llvm.x86.sse2.comigt.sd", | |||
"llvm.x86.sse2.comile.sd", | "llvm.x86.sse2.comile.sd", | |||
"llvm.x86.sse2.comilt.sd", | "llvm.x86.sse2.comilt.sd", | |||
"llvm.x86.sse2.comineq.sd", | "llvm.x86.sse2.comineq.sd", | |||
skipping to change at line 4947 | skipping to change at line 4836 | |||
"llvm.x86.xop.vprotw", | "llvm.x86.xop.vprotw", | |||
"llvm.x86.xop.vprotwi", | "llvm.x86.xop.vprotwi", | |||
"llvm.x86.xop.vpshab", | "llvm.x86.xop.vpshab", | |||
"llvm.x86.xop.vpshad", | "llvm.x86.xop.vpshad", | |||
"llvm.x86.xop.vpshaq", | "llvm.x86.xop.vpshaq", | |||
"llvm.x86.xop.vpshaw", | "llvm.x86.xop.vpshaw", | |||
"llvm.x86.xop.vpshlb", | "llvm.x86.xop.vpshlb", | |||
"llvm.x86.xop.vpshld", | "llvm.x86.xop.vpshld", | |||
"llvm.x86.xop.vpshlq", | "llvm.x86.xop.vpshlq", | |||
"llvm.x86.xop.vpshlw", | "llvm.x86.xop.vpshlw", | |||
"llvm.x86.xtest", | ||||
"llvm.xcore.bitrev", | "llvm.xcore.bitrev", | |||
"llvm.xcore.checkevent", | "llvm.xcore.checkevent", | |||
"llvm.xcore.chkct", | "llvm.xcore.chkct", | |||
"llvm.xcore.clre", | "llvm.xcore.clre", | |||
"llvm.xcore.clrsr", | "llvm.xcore.clrsr", | |||
"llvm.xcore.crc32", | "llvm.xcore.crc32", | |||
"llvm.xcore.crc8", | "llvm.xcore.crc8", | |||
"llvm.xcore.eeu", | "llvm.xcore.eeu", | |||
"llvm.xcore.endin", | "llvm.xcore.endin", | |||
"llvm.xcore.freer", | "llvm.xcore.freer", | |||
skipping to change at line 5018 | skipping to change at line 4908 | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4), | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4), | |||
0, | 0, | |||
0 | (1<<4) | (1<<5) | (1<<6), | 0 | (1<<4) | (1<<5) | (1<<6) | (1<<7), | |||
0 | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7), | 0 | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7), | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5), | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6), | |||
0, | ||||
0 | (1<<5) | (1<<6) | (1<<7), | ||||
0 | (1<<0) | (1<<1) | (1<<3) | (1<<4), | ||||
0, | ||||
0, | ||||
0, | ||||
0, | ||||
0, | ||||
0, | ||||
0, | 0, | |||
0 | (1<<6) | (1<<7), | ||||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<4) | (1<<5), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
skipping to change at line 5131 | skipping to change at line 5014 | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<3) | (1<<4) | (1<<5) | (1<<7), | ||||
0 | (1<<0) | (1<<1), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<4) | (1<<5) | (1<<6), | ||||
0 | (1<<0) | (1<<1) | (1<<2), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<7), | ||||
0 | (1<<0) | (1<<1), | ||||
0, | 0, | |||
0 | (1<<1) | (1<<2), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<2), | ||||
0, | 0, | |||
0 | (1<<1) | (1<<2) | (1<<3), | ||||
0, | 0, | |||
0 | (1<<3) | (1<<4), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<3) | (1<<4) | (1<<5), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<3), | ||||
0, | 0, | |||
0, | 0, | |||
0 | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7), | ||||
0 | (1<<0) | (1<<1), | ||||
0, | 0, | |||
0, | 0, | |||
0 | (1<<5) | (1<<6) | (1<<7), | ||||
0 | (1<<0) | (1<<1) | (1<<2), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<0), | ||||
0, | 0, | |||
0 | (1<<6) | (1<<7), | ||||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6), | ||||
0, | 0, | |||
0, | 0, | |||
0 | (1<<2) | (1<<4) | (1<<5), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<0) | (1<<2) | (1<<3), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<3), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<0) | (1<<4) | (1<<5), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<1), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<5) | (1<<6), | ||||
0 | (1<<2) | (1<<3) | (1<<4) | (1<<5), | ||||
0 | (1<<2) | (1<<3) | (1<<4) | (1<<5), | ||||
0, | 0, | |||
0, | 0, | |||
0 | (1<<0) | (1<<1) | (1<<6) | (1<<7), | ||||
0 | (1<<0), | ||||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
skipping to change at line 5307 | skipping to change at line 5191 | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0, | 0, | |||
0 | (1<<7), | 0 | (1<<0) | (1<<5) | (1<<6) | (1<<7), | |||
0 | (1<<4) | (1<<5) | (1<<6), | 0 | (1<<4) | (1<<5) | (1<<6) | (1<<7), | |||
0 | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7), | ||||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | |||
0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7) , | |||
0 | (1<<0) | (1<<1) | (1<<3) | (1<<4) | (1<<5) | (1<<7), | 0 | (1<<0) | (1<<1) | (1<<2) | (1<<4) | (1<<5) | (1<<6), | |||
0 | (1<<0) | (1<<3) | (1<<4) | (1<<5) | 0 | (1<<0) | (1<<1) | (1<<4) | (1<<5) | (1<<6), | |||
0 | ||||
}; | }; | |||
return (OTable[id/8] & (1 << (id%8))) != 0; | return (OTable[id/8] & (1 << (id%8))) != 0; | |||
#endif | #endif | |||
// Function name -> enum value recognizer code. | // Function name -> enum value recognizer code. | |||
#ifdef GET_FUNCTION_RECOGNIZER | #ifdef GET_FUNCTION_RECOGNIZER | |||
StringRef NameR(Name+6, Len-6); // Skip over 'llvm.' | StringRef NameR(Name+6, Len-6); // Skip over 'llvm.' | |||
switch (Name[5]) { // Dispatch on first letter. | switch (Name[5]) { // Dispatch on first letter. | |||
default: break; | default: break; | |||
skipping to change at line 5624 | skipping to change at line 5508 | |||
break; | break; | |||
return Intrinsic::arm_thread_pointer; // "rm.thread.pointer" | return Intrinsic::arm_thread_pointer; // "rm.thread.pointer" | |||
} | } | |||
break; | break; | |||
} | } | |||
break; // end of 'a' case. | break; // end of 'a' case. | |||
case 'b': | case 'b': | |||
if (NameR.startswith("swap.")) return Intrinsic::bswap; | if (NameR.startswith("swap.")) return Intrinsic::bswap; | |||
break; // end of 'b' case. | break; // end of 'b' case. | |||
case 'c': | case 'c': | |||
if (NameR.startswith("eil.")) return Intrinsic::ceil; | ||||
if (NameR.startswith("onvertff.")) return Intrinsic::convertff; | if (NameR.startswith("onvertff.")) return Intrinsic::convertff; | |||
if (NameR.startswith("onvertfsi.")) return Intrinsic::convertfsi; | if (NameR.startswith("onvertfsi.")) return Intrinsic::convertfsi; | |||
if (NameR.startswith("onvertfui.")) return Intrinsic::convertfui; | if (NameR.startswith("onvertfui.")) return Intrinsic::convertfui; | |||
if (NameR.startswith("onvertsif.")) return Intrinsic::convertsif; | if (NameR.startswith("onvertsif.")) return Intrinsic::convertsif; | |||
if (NameR.startswith("onvertss.")) return Intrinsic::convertss; | if (NameR.startswith("onvertss.")) return Intrinsic::convertss; | |||
if (NameR.startswith("onvertsu.")) return Intrinsic::convertsu; | if (NameR.startswith("onvertsu.")) return Intrinsic::convertsu; | |||
if (NameR.startswith("onvertuif.")) return Intrinsic::convertuif; | if (NameR.startswith("onvertuif.")) return Intrinsic::convertuif; | |||
if (NameR.startswith("onvertus.")) return Intrinsic::convertus; | if (NameR.startswith("onvertus.")) return Intrinsic::convertus; | |||
if (NameR.startswith("onvertuu.")) return Intrinsic::convertuu; | if (NameR.startswith("onvertuu.")) return Intrinsic::convertuu; | |||
if (NameR.startswith("os.")) return Intrinsic::cos; | if (NameR.startswith("os.")) return Intrinsic::cos; | |||
skipping to change at line 13704 | skipping to change at line 13589 | |||
return Intrinsic::mips_precrqu_s_qb_ph; // "ips.precrqu.s.q b.ph" | return Intrinsic::mips_precrqu_s_qb_ph; // "ips.precrqu.s.q b.ph" | |||
} | } | |||
break; | break; | |||
case 20: // 1 string to match. | case 20: // 1 string to match. | |||
if (memcmp(NameR.data()+0, "ips.precr.sra.r.ph.w", 20)) | if (memcmp(NameR.data()+0, "ips.precr.sra.r.ph.w", 20)) | |||
break; | break; | |||
return Intrinsic::mips_precr_sra_r_ph_w; // "ips.precr.sra.r.ph.w" | return Intrinsic::mips_precr_sra_r_ph_w; // "ips.precr.sra.r.ph.w" | |||
} | } | |||
break; // end of 'm' case. | break; // end of 'm' case. | |||
case 'n': | case 'n': | |||
if (NameR.startswith("earbyint.")) return Intrinsic::nearbyint; | ||||
if (NameR.startswith("vvm.atomic.load.add.f32.")) return Intrinsic::nvv m_atomic_load_add_f32; | if (NameR.startswith("vvm.atomic.load.add.f32.")) return Intrinsic::nvv m_atomic_load_add_f32; | |||
if (NameR.startswith("vvm.atomic.load.dec.32.")) return Intrinsic::nvvm _atomic_load_dec_32; | if (NameR.startswith("vvm.atomic.load.dec.32.")) return Intrinsic::nvvm _atomic_load_dec_32; | |||
if (NameR.startswith("vvm.atomic.load.inc.32.")) return Intrinsic::nvvm _atomic_load_inc_32; | if (NameR.startswith("vvm.atomic.load.inc.32.")) return Intrinsic::nvvm _atomic_load_inc_32; | |||
if (NameR.startswith("vvm.compiler.error.")) return Intrinsic::nvvm_com piler_error; | if (NameR.startswith("vvm.compiler.error.")) return Intrinsic::nvvm_com piler_error; | |||
if (NameR.startswith("vvm.compiler.warn.")) return Intrinsic::nvvm_comp iler_warn; | if (NameR.startswith("vvm.compiler.warn.")) return Intrinsic::nvvm_comp iler_warn; | |||
if (NameR.startswith("vvm.ldg.global.f.")) return Intrinsic::nvvm_ldg_g | ||||
lobal_f; | ||||
if (NameR.startswith("vvm.ldg.global.i.")) return Intrinsic::nvvm_ldg_g | ||||
lobal_i; | ||||
if (NameR.startswith("vvm.ldg.global.p.")) return Intrinsic::nvvm_ldg_g | ||||
lobal_p; | ||||
if (NameR.startswith("vvm.ldu.global.f.")) return Intrinsic::nvvm_ldu_g lobal_f; | if (NameR.startswith("vvm.ldu.global.f.")) return Intrinsic::nvvm_ldu_g lobal_f; | |||
if (NameR.startswith("vvm.ldu.global.i.")) return Intrinsic::nvvm_ldu_g lobal_i; | if (NameR.startswith("vvm.ldu.global.i.")) return Intrinsic::nvvm_ldu_g lobal_i; | |||
if (NameR.startswith("vvm.ldu.global.p.")) return Intrinsic::nvvm_ldu_g lobal_p; | if (NameR.startswith("vvm.ldu.global.p.")) return Intrinsic::nvvm_ldu_g lobal_p; | |||
if (NameR.startswith("vvm.move.ptr.")) return Intrinsic::nvvm_move_ptr; | if (NameR.startswith("vvm.move.ptr.")) return Intrinsic::nvvm_move_ptr; | |||
if (NameR.startswith("vvm.ptr.constant.to.gen.")) return Intrinsic::nvv m_ptr_constant_to_gen; | if (NameR.startswith("vvm.ptr.constant.to.gen.")) return Intrinsic::nvv m_ptr_constant_to_gen; | |||
if (NameR.startswith("vvm.ptr.gen.to.constant.")) return Intrinsic::nvv m_ptr_gen_to_constant; | if (NameR.startswith("vvm.ptr.gen.to.constant.")) return Intrinsic::nvv m_ptr_gen_to_constant; | |||
if (NameR.startswith("vvm.ptr.gen.to.global.")) return Intrinsic::nvvm_ ptr_gen_to_global; | if (NameR.startswith("vvm.ptr.gen.to.global.")) return Intrinsic::nvvm_ ptr_gen_to_global; | |||
if (NameR.startswith("vvm.ptr.gen.to.local.")) return Intrinsic::nvvm_p tr_gen_to_local; | if (NameR.startswith("vvm.ptr.gen.to.local.")) return Intrinsic::nvvm_p tr_gen_to_local; | |||
if (NameR.startswith("vvm.ptr.gen.to.param.")) return Intrinsic::nvvm_p tr_gen_to_param; | if (NameR.startswith("vvm.ptr.gen.to.param.")) return Intrinsic::nvvm_p tr_gen_to_param; | |||
if (NameR.startswith("vvm.ptr.gen.to.shared.")) return Intrinsic::nvvm_ ptr_gen_to_shared; | if (NameR.startswith("vvm.ptr.gen.to.shared.")) return Intrinsic::nvvm_ ptr_gen_to_shared; | |||
skipping to change at line 13764 | skipping to change at line 13653 | |||
break; | break; | |||
return Intrinsic::nvvm_min_i; // "vvm.min.i" | return Intrinsic::nvvm_min_i; // "vvm.min.i" | |||
} | } | |||
break; | break; | |||
case 's': // 1 string to match. | case 's': // 1 string to match. | |||
if (memcmp(NameR.data()+5, "ad.i", 4)) | if (memcmp(NameR.data()+5, "ad.i", 4)) | |||
break; | break; | |||
return Intrinsic::nvvm_sad_i; // "vvm.sad.i" | return Intrinsic::nvvm_sad_i; // "vvm.sad.i" | |||
} | } | |||
break; | break; | |||
case 10: // 41 strings to match. | case 10: // 42 strings to match. | |||
if (memcmp(NameR.data()+0, "vvm.", 4)) | if (memcmp(NameR.data()+0, "vvm.", 4)) | |||
break; | break; | |||
switch (NameR[4]) { | switch (NameR[4]) { | |||
default: break; | default: break; | |||
case 'a': // 1 string to match. | case 'a': // 1 string to match. | |||
if (memcmp(NameR.data()+5, "bs.ll", 5)) | if (memcmp(NameR.data()+5, "bs.ll", 5)) | |||
break; | break; | |||
return Intrinsic::nvvm_abs_ll; // "vvm.abs.ll" | return Intrinsic::nvvm_abs_ll; // "vvm.abs.ll" | |||
case 'b': // 2 strings to match. | case 'b': // 2 strings to match. | |||
if (memcmp(NameR.data()+5, "rev", 3)) | if (memcmp(NameR.data()+5, "rev", 3)) | |||
skipping to change at line 14001 | skipping to change at line 13890 | |||
break; | break; | |||
return Intrinsic::nvvm_min_ui; // "vvm.min.ui" | return Intrinsic::nvvm_min_ui; // "vvm.min.ui" | |||
} | } | |||
break; | break; | |||
} | } | |||
break; | break; | |||
case 'p': // 1 string to match. | case 'p': // 1 string to match. | |||
if (memcmp(NameR.data()+5, "opc.i", 5)) | if (memcmp(NameR.data()+5, "opc.i", 5)) | |||
break; | break; | |||
return Intrinsic::nvvm_popc_i; // "vvm.popc.i" | return Intrinsic::nvvm_popc_i; // "vvm.popc.i" | |||
case 's': // 1 string to match. | case 's': // 2 strings to match. | |||
if (memcmp(NameR.data()+5, "ad.ui", 5)) | switch (NameR[5]) { | |||
break; | default: break; | |||
return Intrinsic::nvvm_sad_ui; // "vvm.sad.ui" | case 'a': // 1 string to match. | |||
if (memcmp(NameR.data()+6, "d.ui", 4)) | ||||
break; | ||||
return Intrinsic::nvvm_sad_ui; // "vvm.sad.ui" | ||||
case 'q': // 1 string to match. | ||||
if (memcmp(NameR.data()+6, "rt.f", 4)) | ||||
break; | ||||
return Intrinsic::nvvm_sqrt_f; // "vvm.sqrt.f" | ||||
} | ||||
break; | ||||
} | } | |||
break; | break; | |||
case 11: // 44 strings to match. | case 11: // 44 strings to match. | |||
if (memcmp(NameR.data()+0, "vvm.", 4)) | if (memcmp(NameR.data()+0, "vvm.", 4)) | |||
break; | break; | |||
switch (NameR[4]) { | switch (NameR[4]) { | |||
default: break; | default: break; | |||
case 'd': // 8 strings to match. | case 'd': // 8 strings to match. | |||
if (NameR[5] != '2') | if (NameR[5] != '2') | |||
break; | break; | |||
skipping to change at line 16527 | skipping to change at line 16425 | |||
break; | break; | |||
case 'm': // 1 string to match. | case 'm': // 1 string to match. | |||
if (memcmp(NameR.data()+13, "hraddshs", 8)) | if (memcmp(NameR.data()+13, "hraddshs", 8)) | |||
break; | break; | |||
return Intrinsic::ppc_altivec_vmhraddshs; // "pc.altivec.vmhr addshs" | return Intrinsic::ppc_altivec_vmhraddshs; // "pc.altivec.vmhr addshs" | |||
} | } | |||
break; | break; | |||
} | } | |||
break; // end of 'p' case. | break; // end of 'p' case. | |||
case 'r': | case 'r': | |||
if (NameR.startswith("int.")) return Intrinsic::rint; | ||||
switch (NameR.size()) { | switch (NameR.size()) { | |||
default: break; | default: break; | |||
case 12: // 1 string to match. | case 12: // 1 string to match. | |||
if (memcmp(NameR.data()+0, "eturnaddress", 12)) | if (memcmp(NameR.data()+0, "eturnaddress", 12)) | |||
break; | break; | |||
return Intrinsic::returnaddress; // "eturnaddress" | return Intrinsic::returnaddress; // "eturnaddress" | |||
case 15: // 1 string to match. | case 15: // 4 strings to match. | |||
if (memcmp(NameR.data()+0, "eadcyclecounter", 15)) | ||||
break; | ||||
return Intrinsic::readcyclecounter; // "eadcyclecounter" | ||||
} | ||||
break; // end of 'r' case. | ||||
case 's': | ||||
if (NameR.startswith("add.with.overflow.")) return Intrinsic::sadd_with | ||||
_overflow; | ||||
if (NameR.startswith("in.")) return Intrinsic::sin; | ||||
if (NameR.startswith("mul.with.overflow.")) return Intrinsic::smul_with | ||||
_overflow; | ||||
if (NameR.startswith("qrt.")) return Intrinsic::sqrt; | ||||
if (NameR.startswith("sub.with.overflow.")) return Intrinsic::ssub_with | ||||
_overflow; | ||||
switch (NameR.size()) { | ||||
default: break; | ||||
case 5: // 1 string to match. | ||||
if (memcmp(NameR.data()+0, "etjmp", 5)) | ||||
break; | ||||
return Intrinsic::setjmp; // "etjmp" | ||||
case 7: // 1 string to match. | ||||
if (memcmp(NameR.data()+0, "pu.si.a", 7)) | ||||
break; | ||||
return Intrinsic::spu_si_a; // "pu.si.a" | ||||
case 8: // 11 strings to match. | ||||
switch (NameR[0]) { | switch (NameR[0]) { | |||
default: break; | default: break; | |||
case 'i': // 1 string to match. | case '6': // 3 strings to match. | |||
if (memcmp(NameR.data()+1, "gsetjmp", 7)) | if (memcmp(NameR.data()+1, "00.read.tgid.", 13)) | |||
break; | ||||
return Intrinsic::sigsetjmp; // "igsetjmp" | ||||
case 'p': // 9 strings to match. | ||||
if (memcmp(NameR.data()+1, "u.si.", 5)) | ||||
break; | break; | |||
switch (NameR[6]) { | switch (NameR[14]) { | |||
default: break; | default: break; | |||
case 'a': // 2 strings to match. | case 'x': // 1 string to match. | |||
switch (NameR[7]) { | return Intrinsic::r600_read_tgid_x; // "600.read.tgid.x" | |||
default: break; | case 'y': // 1 string to match. | |||
case 'h': // 1 string to match. | return Intrinsic::r600_read_tgid_y; // "600.read.tgid.y" | |||
return Intrinsic::spu_si_ah; // "pu.si.ah" | case 'z': // 1 string to match. | |||
case 'i': // 1 string to match. | return Intrinsic::r600_read_tgid_z; // "600.read.tgid.z" | |||
return Intrinsic::spu_si_ai; // "pu.si.ai" | ||||
} | ||||
break; | ||||
case 'b': // 1 string to match. | ||||
if (NameR[7] != 'g') | ||||
break; | ||||
return Intrinsic::spu_si_bg; // "pu.si.bg" | ||||
case 'c': // 1 string to match. | ||||
if (NameR[7] != 'g') | ||||
break; | ||||
return Intrinsic::spu_si_cg; // "pu.si.cg" | ||||
case 'f': // 3 strings to match. | ||||
switch (NameR[7]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_fa; // "pu.si.fa" | ||||
case 'm': // 1 string to match. | ||||
return Intrinsic::spu_si_fm; // "pu.si.fm" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_fs; // "pu.si.fs" | ||||
} | ||||
break; | ||||
case 'o': // 1 string to match. | ||||
if (NameR[7] != 'r') | ||||
break; | ||||
return Intrinsic::spu_si_or; // "pu.si.or" | ||||
case 's': // 1 string to match. | ||||
if (NameR[7] != 'f') | ||||
break; | ||||
return Intrinsic::spu_si_sf; // "pu.si.sf" | ||||
} | } | |||
break; | break; | |||
case 't': // 1 string to match. | case 'e': // 1 string to match. | |||
if (memcmp(NameR.data()+1, "acksave", 7)) | if (memcmp(NameR.data()+1, "adcyclecounter", 14)) | |||
break; | break; | |||
return Intrinsic::stacksave; // "tacksave" | return Intrinsic::readcyclecounter; // "eadcyclecounter" | |||
} | } | |||
break; | break; | |||
case 9: // 20 strings to match. | case 16: // 3 strings to match. | |||
switch (NameR[0]) { | if (memcmp(NameR.data()+0, "600.read.tidig.", 15)) | |||
default: break; | ||||
case 'i': // 1 string to match. | ||||
if (memcmp(NameR.data()+1, "glongjmp", 8)) | ||||
break; | ||||
return Intrinsic::siglongjmp; // "iglongjmp" | ||||
case 'p': // 19 strings to match. | ||||
if (memcmp(NameR.data()+1, "u.si.", 5)) | ||||
break; | ||||
switch (NameR[6]) { | ||||
default: break; | ||||
case 'a': // 2 strings to match. | ||||
switch (NameR[7]) { | ||||
default: break; | ||||
case 'h': // 1 string to match. | ||||
if (NameR[8] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_ahi; // "pu.si.ahi" | ||||
case 'n': // 1 string to match. | ||||
if (NameR[8] != 'd') | ||||
break; | ||||
return Intrinsic::spu_si_and; // "pu.si.and" | ||||
} | ||||
break; | ||||
case 'b': // 1 string to match. | ||||
if (memcmp(NameR.data()+7, "gx", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_bgx; // "pu.si.bgx" | ||||
case 'c': // 3 strings to match. | ||||
switch (NameR[7]) { | ||||
default: break; | ||||
case 'e': // 1 string to match. | ||||
if (NameR[8] != 'q') | ||||
break; | ||||
return Intrinsic::spu_si_ceq; // "pu.si.ceq" | ||||
case 'g': // 2 strings to match. | ||||
switch (NameR[8]) { | ||||
default: break; | ||||
case 't': // 1 string to match. | ||||
return Intrinsic::spu_si_cgt; // "pu.si.cgt" | ||||
case 'x': // 1 string to match. | ||||
return Intrinsic::spu_si_cgx; // "pu.si.cgx" | ||||
} | ||||
break; | ||||
} | ||||
break; | ||||
case 'd': // 3 strings to match. | ||||
if (NameR[7] != 'f') | ||||
break; | ||||
switch (NameR[8]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_dfa; // "pu.si.dfa" | ||||
case 'm': // 1 string to match. | ||||
return Intrinsic::spu_si_dfm; // "pu.si.dfm" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_dfs; // "pu.si.dfs" | ||||
} | ||||
break; | ||||
case 'f': // 2 strings to match. | ||||
if (NameR[7] != 'm') | ||||
break; | ||||
switch (NameR[8]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_fma; // "pu.si.fma" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_fms; // "pu.si.fms" | ||||
} | ||||
break; | ||||
case 'm': // 1 string to match. | ||||
if (memcmp(NameR.data()+7, "py", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_mpy; // "pu.si.mpy" | ||||
case 'n': // 1 string to match. | ||||
if (memcmp(NameR.data()+7, "or", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_nor; // "pu.si.nor" | ||||
case 'o': // 2 strings to match. | ||||
if (NameR[7] != 'r') | ||||
break; | ||||
switch (NameR[8]) { | ||||
default: break; | ||||
case 'c': // 1 string to match. | ||||
return Intrinsic::spu_si_orc; // "pu.si.orc" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_ori; // "pu.si.ori" | ||||
} | ||||
break; | ||||
case 's': // 3 strings to match. | ||||
if (NameR[7] != 'f') | ||||
break; | ||||
switch (NameR[8]) { | ||||
default: break; | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_sfh; // "pu.si.sfh" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_sfi; // "pu.si.sfi" | ||||
case 'x': // 1 string to match. | ||||
return Intrinsic::spu_si_sfx; // "pu.si.sfx" | ||||
} | ||||
break; | ||||
case 'x': // 1 string to match. | ||||
if (memcmp(NameR.data()+7, "or", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_xor; // "pu.si.xor" | ||||
} | ||||
break; | break; | |||
switch (NameR[15]) { | ||||
default: break; | ||||
case 'x': // 1 string to match. | ||||
return Intrinsic::r600_read_tidig_x; // "600.read.tidig.x" | ||||
case 'y': // 1 string to match. | ||||
return Intrinsic::r600_read_tidig_y; // "600.read.tidig.y" | ||||
case 'z': // 1 string to match. | ||||
return Intrinsic::r600_read_tidig_z; // "600.read.tidig.z" | ||||
} | } | |||
break; | break; | |||
case 10: // 26 strings to match. | case 18: // 3 strings to match. | |||
if (memcmp(NameR.data()+0, "pu.si.", 6)) | if (memcmp(NameR.data()+0, "600.read.ngroups.", 17)) | |||
break; | break; | |||
switch (NameR[6]) { | switch (NameR[17]) { | |||
default: break; | default: break; | |||
case 'a': // 3 strings to match. | ||||
switch (NameR[7]) { | ||||
default: break; | ||||
case 'd': // 1 string to match. | ||||
if (memcmp(NameR.data()+8, "dx", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_addx; // "pu.si.addx" | ||||
case 'n': // 2 strings to match. | ||||
if (NameR[8] != 'd') | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'c': // 1 string to match. | ||||
return Intrinsic::spu_si_andc; // "pu.si.andc" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_andi; // "pu.si.andi" | ||||
} | ||||
break; | ||||
} | ||||
break; | ||||
case 'c': // 7 strings to match. | ||||
switch (NameR[7]) { | ||||
default: break; | ||||
case 'e': // 3 strings to match. | ||||
if (NameR[8] != 'q') | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
return Intrinsic::spu_si_ceqb; // "pu.si.ceqb" | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_ceqh; // "pu.si.ceqh" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_ceqi; // "pu.si.ceqi" | ||||
} | ||||
break; | ||||
case 'g': // 3 strings to match. | ||||
if (NameR[8] != 't') | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
return Intrinsic::spu_si_cgtb; // "pu.si.cgtb" | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_cgth; // "pu.si.cgth" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_cgti; // "pu.si.cgti" | ||||
} | ||||
break; | ||||
case 'l': // 1 string to match. | ||||
if (memcmp(NameR.data()+8, "gt", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_clgt; // "pu.si.clgt" | ||||
} | ||||
break; | ||||
case 'd': // 2 strings to match. | ||||
if (memcmp(NameR.data()+7, "fm", 2)) | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_dfma; // "pu.si.dfma" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_dfms; // "pu.si.dfms" | ||||
} | ||||
break; | ||||
case 'f': // 3 strings to match. | ||||
switch (NameR[7]) { | ||||
default: break; | ||||
case 'c': // 2 strings to match. | ||||
switch (NameR[8]) { | ||||
default: break; | ||||
case 'e': // 1 string to match. | ||||
if (NameR[9] != 'q') | ||||
break; | ||||
return Intrinsic::spu_si_fceq; // "pu.si.fceq" | ||||
case 'g': // 1 string to match. | ||||
if (NameR[9] != 't') | ||||
break; | ||||
return Intrinsic::spu_si_fcgt; // "pu.si.fcgt" | ||||
} | ||||
break; | ||||
case 'n': // 1 string to match. | ||||
if (memcmp(NameR.data()+8, "ms", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_fnms; // "pu.si.fnms" | ||||
} | ||||
break; | ||||
case 'm': // 5 strings to match. | ||||
if (memcmp(NameR.data()+7, "py", 2)) | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_mpya; // "pu.si.mpya" | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_mpyh; // "pu.si.mpyh" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_mpyi; // "pu.si.mpyi" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_mpys; // "pu.si.mpys" | ||||
case 'u': // 1 string to match. | ||||
return Intrinsic::spu_si_mpyu; // "pu.si.mpyu" | ||||
} | ||||
break; | ||||
case 'n': // 1 string to match. | ||||
if (memcmp(NameR.data()+7, "and", 3)) | ||||
break; | ||||
return Intrinsic::spu_si_nand; // "pu.si.nand" | ||||
case 'o': // 2 strings to match. | ||||
if (NameR[7] != 'r') | ||||
break; | ||||
switch (NameR[8]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
if (NameR[9] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_orbi; // "pu.si.orbi" | ||||
case 'h': // 1 string to match. | ||||
if (NameR[9] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_orhi; // "pu.si.orhi" | ||||
} | ||||
break; | ||||
case 's': // 2 strings to match. | ||||
switch (NameR[7]) { | ||||
default: break; | ||||
case 'f': // 1 string to match. | ||||
if (memcmp(NameR.data()+8, "hi", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_sfhi; // "pu.si.sfhi" | ||||
case 'h': // 1 string to match. | ||||
if (memcmp(NameR.data()+8, "li", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_shli; // "pu.si.shli" | ||||
} | ||||
break; | ||||
case 'x': // 1 string to match. | case 'x': // 1 string to match. | |||
if (memcmp(NameR.data()+7, "ori", 3)) | return Intrinsic::r600_read_ngroups_x; // "600.read.ngroups.x" | |||
break; | case 'y': // 1 string to match. | |||
return Intrinsic::spu_si_xori; // "pu.si.xori" | return Intrinsic::r600_read_ngroups_y; // "600.read.ngroups.y" | |||
case 'z': // 1 string to match. | ||||
return Intrinsic::r600_read_ngroups_z; // "600.read.ngroups.z" | ||||
} | } | |||
break; | break; | |||
case 11: // 19 strings to match. | case 21: // 3 strings to match. | |||
switch (NameR[0]) { | if (memcmp(NameR.data()+0, "600.read.local.size.", 20)) | |||
default: break; | ||||
case 'p': // 18 strings to match. | ||||
if (memcmp(NameR.data()+1, "u.si.", 5)) | ||||
break; | ||||
switch (NameR[6]) { | ||||
default: break; | ||||
case 'a': // 2 strings to match. | ||||
if (memcmp(NameR.data()+7, "nd", 2)) | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
if (NameR[10] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_andbi; // "pu.si.andbi" | ||||
case 'h': // 1 string to match. | ||||
if (NameR[10] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_andhi; // "pu.si.andhi" | ||||
} | ||||
break; | ||||
case 'c': // 7 strings to match. | ||||
switch (NameR[7]) { | ||||
default: break; | ||||
case 'e': // 2 strings to match. | ||||
if (NameR[8] != 'q') | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
if (NameR[10] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_ceqbi; // "pu.si.ceqbi" | ||||
case 'h': // 1 string to match. | ||||
if (NameR[10] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_ceqhi; // "pu.si.ceqhi" | ||||
} | ||||
break; | ||||
case 'g': // 2 strings to match. | ||||
if (NameR[8] != 't') | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
if (NameR[10] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_cgtbi; // "pu.si.cgtbi" | ||||
case 'h': // 1 string to match. | ||||
if (NameR[10] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_cgthi; // "pu.si.cgthi" | ||||
} | ||||
break; | ||||
case 'l': // 3 strings to match. | ||||
if (memcmp(NameR.data()+8, "gt", 2)) | ||||
break; | ||||
switch (NameR[10]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
return Intrinsic::spu_si_clgtb; // "pu.si.clgtb" | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_clgth; // "pu.si.clgth" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_clgti; // "pu.si.clgti" | ||||
} | ||||
break; | ||||
} | ||||
break; | ||||
case 'd': // 2 strings to match. | ||||
if (memcmp(NameR.data()+7, "fnm", 3)) | ||||
break; | ||||
switch (NameR[10]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_dfnma; // "pu.si.dfnma" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_dfnms; // "pu.si.dfnms" | ||||
} | ||||
break; | ||||
case 'f': // 3 strings to match. | ||||
switch (NameR[7]) { | ||||
default: break; | ||||
case 'c': // 2 strings to match. | ||||
if (NameR[8] != 'm') | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'e': // 1 string to match. | ||||
if (NameR[10] != 'q') | ||||
break; | ||||
return Intrinsic::spu_si_fcmeq; // "pu.si.fcmeq" | ||||
case 'g': // 1 string to match. | ||||
if (NameR[10] != 't') | ||||
break; | ||||
return Intrinsic::spu_si_fcmgt; // "pu.si.fcmgt" | ||||
} | ||||
break; | ||||
case 's': // 1 string to match. | ||||
if (memcmp(NameR.data()+8, "mbi", 3)) | ||||
break; | ||||
return Intrinsic::spu_si_fsmbi; // "pu.si.fsmbi" | ||||
} | ||||
break; | ||||
case 'm': // 2 strings to match. | ||||
if (memcmp(NameR.data()+7, "py", 2)) | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'h': // 1 string to match. | ||||
if (NameR[10] != 'h') | ||||
break; | ||||
return Intrinsic::spu_si_mpyhh; // "pu.si.mpyhh" | ||||
case 'u': // 1 string to match. | ||||
if (NameR[10] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_mpyui; // "pu.si.mpyui" | ||||
} | ||||
break; | ||||
case 'x': // 2 strings to match. | ||||
if (memcmp(NameR.data()+7, "or", 2)) | ||||
break; | ||||
switch (NameR[9]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
if (NameR[10] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_xorbi; // "pu.si.xorbi" | ||||
case 'h': // 1 string to match. | ||||
if (NameR[10] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_xorhi; // "pu.si.xorhi" | ||||
} | ||||
break; | ||||
} | ||||
break; | break; | |||
case 't': // 1 string to match. | switch (NameR[20]) { | |||
if (memcmp(NameR.data()+1, "ackrestore", 10)) | default: break; | |||
break; | case 'x': // 1 string to match. | |||
return Intrinsic::stackrestore; // "tackrestore" | return Intrinsic::r600_read_local_size_x; // "600.read.local. | |||
size.x" | ||||
case 'y': // 1 string to match. | ||||
return Intrinsic::r600_read_local_size_y; // "600.read.local. | ||||
size.y" | ||||
case 'z': // 1 string to match. | ||||
return Intrinsic::r600_read_local_size_z; // "600.read.local. | ||||
size.z" | ||||
} | } | |||
break; | break; | |||
case 12: // 6 strings to match. | case 22: // 3 strings to match. | |||
if (memcmp(NameR.data()+0, "pu.si.", 6)) | if (memcmp(NameR.data()+0, "600.read.global.size.", 21)) | |||
break; | break; | |||
switch (NameR[6]) { | switch (NameR[21]) { | |||
default: break; | default: break; | |||
case 'c': // 2 strings to match. | case 'x': // 1 string to match. | |||
if (memcmp(NameR.data()+7, "lgt", 3)) | return Intrinsic::r600_read_global_size_x; // "600.read.global | |||
break; | .size.x" | |||
switch (NameR[10]) { | case 'y': // 1 string to match. | |||
default: break; | return Intrinsic::r600_read_global_size_y; // "600.read.global | |||
case 'b': // 1 string to match. | .size.y" | |||
if (NameR[11] != 'i') | case 'z': // 1 string to match. | |||
break; | return Intrinsic::r600_read_global_size_z; // "600.read.global | |||
return Intrinsic::spu_si_clgtbi; // "pu.si.clgtbi" | .size.z" | |||
case 'h': // 1 string to match. | ||||
if (NameR[11] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_clgthi; // "pu.si.clgthi" | ||||
} | ||||
break; | ||||
case 'm': // 2 strings to match. | ||||
if (memcmp(NameR.data()+7, "pyhh", 4)) | ||||
break; | ||||
switch (NameR[11]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_mpyhha; // "pu.si.mpyhha" | ||||
case 'u': // 1 string to match. | ||||
return Intrinsic::spu_si_mpyhhu; // "pu.si.mpyhhu" | ||||
} | ||||
break; | ||||
case 's': // 2 strings to match. | ||||
if (memcmp(NameR.data()+7, "hlqb", 4)) | ||||
break; | ||||
switch (NameR[11]) { | ||||
default: break; | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_shlqbi; // "pu.si.shlqbi" | ||||
case 'y': // 1 string to match. | ||||
return Intrinsic::spu_si_shlqby; // "pu.si.shlqby" | ||||
} | ||||
break; | ||||
} | } | |||
break; | break; | |||
case 13: // 4 strings to match. | } | |||
break; // end of 'r' case. | ||||
case 's': | ||||
if (NameR.startswith("add.with.overflow.")) return Intrinsic::sadd_with | ||||
_overflow; | ||||
if (NameR.startswith("in.")) return Intrinsic::sin; | ||||
if (NameR.startswith("mul.with.overflow.")) return Intrinsic::smul_with | ||||
_overflow; | ||||
if (NameR.startswith("qrt.")) return Intrinsic::sqrt; | ||||
if (NameR.startswith("sub.with.overflow.")) return Intrinsic::ssub_with | ||||
_overflow; | ||||
switch (NameR.size()) { | ||||
default: break; | ||||
case 5: // 1 string to match. | ||||
if (memcmp(NameR.data()+0, "etjmp", 5)) | ||||
break; | ||||
return Intrinsic::setjmp; // "etjmp" | ||||
case 8: // 2 strings to match. | ||||
switch (NameR[0]) { | switch (NameR[0]) { | |||
default: break; | default: break; | |||
case 'p': // 3 strings to match. | case 'i': // 1 string to match. | |||
if (memcmp(NameR.data()+1, "u.si.", 5)) | if (memcmp(NameR.data()+1, "gsetjmp", 7)) | |||
break; | ||||
switch (NameR[6]) { | ||||
default: break; | ||||
case 'm': // 1 string to match. | ||||
if (memcmp(NameR.data()+7, "pyhhau", 6)) | ||||
break; | ||||
return Intrinsic::spu_si_mpyhhau; // "pu.si.mpyhhau" | ||||
case 's': // 2 strings to match. | ||||
if (memcmp(NameR.data()+7, "hlqb", 4)) | ||||
break; | ||||
switch (NameR[11]) { | ||||
default: break; | ||||
case 'i': // 1 string to match. | ||||
if (NameR[12] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_shlqbii; // "pu.si.shlqbii" | ||||
case 'y': // 1 string to match. | ||||
if (NameR[12] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_shlqbyi; // "pu.si.shlqbyi" | ||||
} | ||||
break; | break; | |||
} | return Intrinsic::sigsetjmp; // "igsetjmp" | |||
break; | ||||
case 't': // 1 string to match. | case 't': // 1 string to match. | |||
if (memcmp(NameR.data()+1, "ackprotector", 12)) | if (memcmp(NameR.data()+1, "acksave", 7)) | |||
break; | break; | |||
return Intrinsic::stackprotector; // "tackprotector" | return Intrinsic::stacksave; // "tacksave" | |||
} | } | |||
break; | break; | |||
case 9: // 1 string to match. | ||||
if (memcmp(NameR.data()+0, "iglongjmp", 9)) | ||||
break; | ||||
return Intrinsic::siglongjmp; // "iglongjmp" | ||||
case 11: // 1 string to match. | ||||
if (memcmp(NameR.data()+0, "tackrestore", 11)) | ||||
break; | ||||
return Intrinsic::stackrestore; // "tackrestore" | ||||
case 13: // 1 string to match. | ||||
if (memcmp(NameR.data()+0, "tackprotector", 13)) | ||||
break; | ||||
return Intrinsic::stackprotector; // "tackprotector" | ||||
} | } | |||
break; // end of 's' case. | break; // end of 's' case. | |||
case 't': | case 't': | |||
if (NameR.startswith("runc.")) return Intrinsic::trunc; | ||||
switch (NameR.size()) { | switch (NameR.size()) { | |||
default: break; | default: break; | |||
case 3: // 1 string to match. | case 3: // 1 string to match. | |||
if (memcmp(NameR.data()+0, "rap", 3)) | if (memcmp(NameR.data()+0, "rap", 3)) | |||
break; | break; | |||
return Intrinsic::trap; // "rap" | return Intrinsic::trap; // "rap" | |||
} | } | |||
break; // end of 't' case. | break; // end of 't' case. | |||
case 'u': | case 'u': | |||
if (NameR.startswith("add.with.overflow.")) return Intrinsic::uadd_with _overflow; | if (NameR.startswith("add.with.overflow.")) return Intrinsic::uadd_with _overflow; | |||
skipping to change at line 17176 | skipping to change at line 16629 | |||
switch (NameR.size()) { | switch (NameR.size()) { | |||
default: break; | default: break; | |||
case 6: // 1 string to match. | case 6: // 1 string to match. | |||
if (memcmp(NameR.data()+0, "86.int", 6)) | if (memcmp(NameR.data()+0, "86.int", 6)) | |||
break; | break; | |||
return Intrinsic::x86_int; // "86.int" | return Intrinsic::x86_int; // "86.int" | |||
case 7: // 1 string to match. | case 7: // 1 string to match. | |||
if (memcmp(NameR.data()+0, "86.xend", 7)) | if (memcmp(NameR.data()+0, "86.xend", 7)) | |||
break; | break; | |||
return Intrinsic::x86_xend; // "86.xend" | return Intrinsic::x86_xend; // "86.xend" | |||
case 8: // 1 string to match. | ||||
if (memcmp(NameR.data()+0, "86.xtest", 8)) | ||||
break; | ||||
return Intrinsic::x86_xtest; // "86.xtest" | ||||
case 9: // 6 strings to match. | case 9: // 6 strings to match. | |||
switch (NameR[0]) { | switch (NameR[0]) { | |||
default: break; | default: break; | |||
case '8': // 2 strings to match. | case '8': // 2 strings to match. | |||
if (memcmp(NameR.data()+1, "6.x", 3)) | if (memcmp(NameR.data()+1, "6.x", 3)) | |||
break; | break; | |||
switch (NameR[4]) { | switch (NameR[4]) { | |||
default: break; | default: break; | |||
case 'a': // 1 string to match. | case 'a': // 1 string to match. | |||
if (memcmp(NameR.data()+5, "bort", 4)) | if (memcmp(NameR.data()+5, "bort", 4)) | |||
skipping to change at line 17334 | skipping to change at line 16791 | |||
} | } | |||
break; | break; | |||
} | } | |||
break; | break; | |||
case 'c': // 1 string to match. | case 'c': // 1 string to match. | |||
if (memcmp(NameR.data()+1, "ore.bitrev", 10)) | if (memcmp(NameR.data()+1, "ore.bitrev", 10)) | |||
break; | break; | |||
return Intrinsic::xcore_bitrev; // "core.bitrev" | return Intrinsic::xcore_bitrev; // "core.bitrev" | |||
} | } | |||
break; | break; | |||
case 12: // 6 strings to match. | case 12: // 9 strings to match. | |||
if (memcmp(NameR.data()+0, "86.", 3)) | if (memcmp(NameR.data()+0, "86.", 3)) | |||
break; | break; | |||
switch (NameR[3]) { | switch (NameR[3]) { | |||
default: break; | default: break; | |||
case 'm': // 2 strings to match. | case 'm': // 2 strings to match. | |||
if (memcmp(NameR.data()+4, "mx.", 3)) | if (memcmp(NameR.data()+4, "mx.", 3)) | |||
break; | break; | |||
switch (NameR[7]) { | switch (NameR[7]) { | |||
default: break; | default: break; | |||
case 'f': // 1 string to match. | case 'f': // 1 string to match. | |||
skipping to change at line 17358 | skipping to change at line 16815 | |||
case 'p': // 1 string to match. | case 'p': // 1 string to match. | |||
if (memcmp(NameR.data()+8, "andn", 4)) | if (memcmp(NameR.data()+8, "andn", 4)) | |||
break; | break; | |||
return Intrinsic::x86_mmx_pandn; // "86.mmx.pandn" | return Intrinsic::x86_mmx_pandn; // "86.mmx.pandn" | |||
} | } | |||
break; | break; | |||
case 'p': // 1 string to match. | case 'p': // 1 string to match. | |||
if (memcmp(NameR.data()+4, "clmulqdq", 8)) | if (memcmp(NameR.data()+4, "clmulqdq", 8)) | |||
break; | break; | |||
return Intrinsic::x86_pclmulqdq; // "86.pclmulqdq" | return Intrinsic::x86_pclmulqdq; // "86.pclmulqdq" | |||
case 'r': // 3 strings to match. | case 'r': // 6 strings to match. | |||
if (memcmp(NameR.data()+4, "drand.", 6)) | if (NameR[4] != 'd') | |||
break; | break; | |||
switch (NameR[10]) { | switch (NameR[5]) { | |||
default: break; | default: break; | |||
case '1': // 1 string to match. | case 'r': // 3 strings to match. | |||
if (NameR[11] != '6') | if (memcmp(NameR.data()+6, "and.", 4)) | |||
break; | ||||
return Intrinsic::x86_rdrand_16; // "86.rdrand.16" | ||||
case '3': // 1 string to match. | ||||
if (NameR[11] != '2') | ||||
break; | break; | |||
return Intrinsic::x86_rdrand_32; // "86.rdrand.32" | switch (NameR[10]) { | |||
case '6': // 1 string to match. | default: break; | |||
if (NameR[11] != '4') | case '1': // 1 string to match. | |||
if (NameR[11] != '6') | ||||
break; | ||||
return Intrinsic::x86_rdrand_16; // "86.rdrand.16" | ||||
case '3': // 1 string to match. | ||||
if (NameR[11] != '2') | ||||
break; | ||||
return Intrinsic::x86_rdrand_32; // "86.rdrand.32" | ||||
case '6': // 1 string to match. | ||||
if (NameR[11] != '4') | ||||
break; | ||||
return Intrinsic::x86_rdrand_64; // "86.rdrand.64" | ||||
} | ||||
break; | ||||
case 's': // 3 strings to match. | ||||
if (memcmp(NameR.data()+6, "eed.", 4)) | ||||
break; | break; | |||
return Intrinsic::x86_rdrand_64; // "86.rdrand.64" | switch (NameR[10]) { | |||
default: break; | ||||
case '1': // 1 string to match. | ||||
if (NameR[11] != '6') | ||||
break; | ||||
return Intrinsic::x86_rdseed_16; // "86.rdseed.16" | ||||
case '3': // 1 string to match. | ||||
if (NameR[11] != '2') | ||||
break; | ||||
return Intrinsic::x86_rdseed_32; // "86.rdseed.32" | ||||
case '6': // 1 string to match. | ||||
if (NameR[11] != '4') | ||||
break; | ||||
return Intrinsic::x86_rdseed_64; // "86.rdseed.64" | ||||
} | ||||
break; | ||||
} | } | |||
break; | break; | |||
} | } | |||
break; | break; | |||
case 13: // 53 strings to match. | case 13: // 53 strings to match. | |||
if (memcmp(NameR.data()+0, "86.", 3)) | if (memcmp(NameR.data()+0, "86.", 3)) | |||
break; | break; | |||
switch (NameR[3]) { | switch (NameR[3]) { | |||
default: break; | default: break; | |||
case 'a': // 1 string to match. | case 'a': // 1 string to match. | |||
skipping to change at line 22523 | skipping to change at line 22006 | |||
} | } | |||
break; | break; | |||
} | } | |||
break; // end of 'x' case. | break; // end of 'x' case. | |||
} | } | |||
#endif | #endif | |||
// Global intrinsic function declaration type table. | // Global intrinsic function declaration type table. | |||
#ifdef GET_INTRINSIC_GENERATOR_GLOBAL | #ifdef GET_INTRINSIC_GENERATOR_GLOBAL | |||
static const unsigned IIT_Table[] = { | static const unsigned IIT_Table[] = { | |||
0x2E2E, (1U<<31) | 310, 0x4444440, 0x4444440, 0x4, (1U<<31) | 276, 0x4444 440, | 0x2E2E, (1U<<31) | 321, 0x4444440, 0x4444440, 0x4, (1U<<31) | 276, 0x4444 440, | |||
0x4444440, 0x444440, 0x444440, 0x444444, 0x444444, 0x2F2F2F, 0x2F2F2F, 0x 2F2F, | 0x4444440, 0x444440, 0x444440, 0x444444, 0x444444, 0x2F2F2F, 0x2F2F2F, 0x 2F2F, | |||
0x686848, 0x696949, 0x686848, 0x696949, (1U<<31) | 294, 0x2F2F2F2F, 0x2F2 | 0x797949, 0x7A7A4A, 0x797949, 0x7A7A4A, (1U<<31) | 305, 0x2F2F2F2F, 0x2F2 | |||
F, 0x2F2F, | F, 0x2F2F, | |||
0x2F2F, 0x45F0F, 0x45F0F, 0x6939, 0x44F1F, 0x44F1F, 0x3969, 0x2F2F2F, | 0x2F2F, 0x45F0F, 0x45F0F, 0x7A3A, 0x44F1F, 0x44F1F, 0x3A7A, 0x2F2F2F, | |||
0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x42E2F, (1U<<31) | 354, (1U<<31) | 401, (1 | 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x42E2F, (1U<<31) | 365, (1U<<31) | 412, (1 | |||
U<<31) | 343, (1U<<31) | 427, | U<<31) | 354, (1U<<31) | 438, | |||
(1U<<31) | 330, (1U<<31) | 459, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, ( | (1U<<31) | 341, (1U<<31) | 470, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, ( | |||
1U<<31) | 303, (1U<<31) | 303, | 1U<<31) | 314, (1U<<31) | 314, | |||
(1U<<31) | 303, 0x2F2F2F, 0x6F2F2F, 0x6F2F2F, 0x2F2F2F, 0x6F2F, 0x6F2F, 0 | (1U<<31) | 314, 0x2F2F2F, 0x6F2F2F, 0x6F2F2F, 0x2F2F2F, 0x6F2F, 0x6F2F, 0 | |||
x2F2F2F, | x2F2F2F, | |||
0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F, 0x2F2F2F, 0x2F2F2F, (1U<<31) | 301, | 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F, 0x2F2F2F, 0x2F2F2F, (1U<<31) | 312, | |||
(1U<<31) | 301, | (1U<<31) | 312, | |||
0x2F2F2F, (1U<<31) | 303, (1U<<31) | 289, (1U<<31) | 289, (1U<<31) | 289, | 0x2F2F2F, (1U<<31) | 314, (1U<<31) | 300, (1U<<31) | 300, (1U<<31) | 300, | |||
0x2F2F, 0x2F2F2F, (1U<<31) | 294, | 0x2F2F, 0x2F2F2F, (1U<<31) | 305, | |||
(1U<<31) | 294, (1U<<31) | 294, 0x2F2F2F, 0x2F2F2F, (1U<<31) | 294, (1U<< | (1U<<31) | 305, (1U<<31) | 305, 0x2F2F2F, 0x2F2F2F, (1U<<31) | 305, (1U<< | |||
31) | 294, (1U<<31) | 294, 0x2F2F2F, | 31) | 305, (1U<<31) | 305, 0x2F2F2F, | |||
0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, (1U<<31) | 294, 0x2F2F, 0x2F2F2F, | 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, (1U<<31) | 305, 0x2F2F, 0x2F2F2F, | |||
0x2F2F2F, | 0x2F2F2F, | |||
0x2F2F2F, (1U<<31) | 294, 0x2F2F2F, 0x2F2F2F, 0x2F2F, 0x2F2F2F, (1U<<31) | 0x2F2F2F, (1U<<31) | 305, 0x2F2F2F, 0x2F2F2F, 0x2F2F, 0x2F2F2F, (1U<<31) | |||
| 294, 0x2F2F2F2F, | | 305, 0x2F2F2F2F, | |||
(1U<<31) | 303, (1U<<31) | 303, (1U<<31) | 294, 0x2F2F2F, 0x2F2F2F, 0x42F | (1U<<31) | 314, (1U<<31) | 314, (1U<<31) | 305, 0x2F2F2F, 0x2F2F2F, 0x42F | |||
2E0, 0x42F2F2E0, (1U<<31) | 391, | 2E0, 0x42F2F2E0, (1U<<31) | 402, | |||
(1U<<31) | 363, (1U<<31) | 415, (1U<<31) | 374, (1U<<31) | 445, (1U<<31) | (1U<<31) | 374, (1U<<31) | 426, (1U<<31) | 385, (1U<<31) | 456, (1U<<31) | |||
| 294, 0x2A2A2A, 0x2A2A2A2A, (1U<<31) | 265, | | 305, 0x2B2B2B, 0x2B2B2B2B, (1U<<31) | 265, | |||
(1U<<31) | 263, 0x2A2A2A2A, (1U<<31) | 265, (1U<<31) | 263, (1U<<31) | 26 | (1U<<31) | 263, 0x2B2B2B2B, (1U<<31) | 265, (1U<<31) | 263, (1U<<31) | 26 | |||
1, 0x444, 0x444, 0x40, | 1, 0x444, 0x444, 0x40, | |||
0x444, 0x2E444, 0x2E, 0x444, 0x1F6, 0x1F6, 0xF0F, 0x36, | 0x444, 0x2E444, 0x2E, 0x444, 0x1F7, 0x1F7, 0xF0F, 0x1F1F, | |||
0x63, 0x445F1F, 0x444F1F, 0x444F1F, 0x445F0F, 0x444F0F, 0x444F0F, 0x445F0 | 0x37, 0x73, 0x445F1F, 0x444F1F, 0x444F1F, 0x445F0F, 0x444F0F, 0x444F0F, | |||
F, | 0x445F0F, 0x444F0F, 0x444F0F, 0x1F1F, 0x10F0F, 0xF0F, 0x10F0F, 0x0, | |||
0x444F0F, 0x444F0F, 0x1F1F, 0x10F0F, 0xF0F, 0x10F0F, 0x0, (1U<<31) | 501, | (1U<<31) | 573, (1U<<31) | 568, 0x0, 0x0, 0x42E, 0x2E40, 0x2E50, 0x40, | |||
(1U<<31) | 496, 0x0, 0x0, 0x42E, 0x2E40, 0x2E50, 0x40, 0x2E0, | 0x2E0, 0x2E0, 0x2E, 0x2E4, 0x2E4, 0x0, 0x1F1F, 0x1F1F, | |||
0x2E0, 0x2E, 0x2E4, 0x2E4, 0x0, 0x1F1F, 0x1F1F, 0xF0F0F, | 0xF0F0F, 0x1F1F, 0x1F1F, 0x4, 0x1F1F1F1F, 0x1F1F1F1F, 0x42E, 0x2EE2E2E, | |||
0x1F1F, 0x1F1F, 0x4, 0x1F1F1F1F, 0x1F1F1F1F, 0x42E, 0x2EE2E2E, 0x2E2EE0, | 0x2E2EE0, 0x2EE2E2E0, 0x44, 0x55, 0x44, 0x444, 0x444, 0x444, | |||
0x2EE2E2E0, 0x44, 0x55, 0x44, 0x444, 0x444, 0x444, 0x444, | ||||
0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | |||
0x444, 0x444, 0x555, 0x555, 0x444, 0x545, 0x444, 0x444, | 0x444, 0x444, 0x444, 0x555, 0x555, 0x444, 0x545, 0x444, | |||
0x555, 0x44, 0x44, 0x444, 0x444, 0x444, 0x444, 0x445, | 0x444, 0x555, 0x44, 0x44, 0x444, 0x444, 0x444, 0x444, | |||
0x445, 0x444, 0x555, 0x444, 0x555, 0x444, 0x555, 0x444, | 0x445, 0x445, 0x444, 0x555, 0x444, 0x555, 0x444, 0x555, | |||
0x555, 0x44, 0x55, 0x44, 0x44, 0x55, 0x444, 0x444, | 0x444, 0x555, 0x44, 0x55, 0x44, 0x44, 0x55, 0x444, | |||
0x555, 0x54, 0x54, 0x44, 0x44, 0x44, 0x44, 0x444, | 0x444, 0x555, 0x54, 0x54, 0x44, 0x44, 0x44, 0x44, | |||
0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | |||
0x444, 0x444, 0x444, 0x444, 0x555, 0x444, 0x444, 0x444, | 0x444, 0x444, 0x444, 0x444, 0x444, 0x555, 0x444, 0x444, | |||
0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | |||
0x44, 0x44, 0x44, 0x45, 0x44, 0x444, 0x444, 0x55, | 0x444, 0x44, 0x44, 0x44, 0x45, 0x44, 0x444, 0x444, | |||
0x45, 0x44, 0x55, 0x55, 0x55, 0x55, 0x555, 0x555, | 0x55, 0x45, 0x44, 0x55, 0x55, 0x55, 0x55, 0x555, | |||
0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | |||
0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | |||
0x555, 0x555, 0x551, 0x551, 0x551, 0x551, 0x551, 0x551, | 0x555, 0x555, 0x555, 0x551, 0x551, 0x551, 0x551, 0x551, | |||
0x551, 0x551, 0x55, 0x555, 0x555, 0x555, 0x555, 0x555, | 0x551, 0x551, 0x551, 0x55, 0x555, 0x555, 0x555, 0x555, | |||
0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | |||
0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x5555, 0x555, | 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x5555, | |||
0x5555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | 0x555, 0x5555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | |||
0x555, 0x444, 0x555, 0x44, 0x44, 0x444, 0x555, 0x445, | 0x555, 0x555, 0x444, 0x555, 0x44, 0x44, 0x444, 0x555, | |||
0x445, 0x541, 0x441, 0x441, 0x441, 0x441, 0x441, 0x441, | 0x445, 0x445, 0x541, 0x441, 0x441, 0x441, 0x441, 0x441, | |||
0x441, 0x441, 0x441, 0x441, 0x441, 0x441, 0x445, 0x445, | 0x441, 0x441, 0x441, 0x441, 0x441, 0x441, 0x441, 0x445, | |||
0x444, 0x444, 0x444, 0x444, 0x555, 0x444, 0x444, 0x444, | 0x445, 0x444, 0x444, 0x444, 0x444, 0x555, 0x444, 0x444, | |||
0x444, 0x444, 0x444, 0x444, 0x444, 0x451, 0x551, 0x451, | 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x451, 0x551, | |||
0x551, 0x451, 0x451, 0x451, 0x451, 0x451, 0x451, 0x451, | 0x451, 0x551, 0x451, 0x451, 0x451, 0x451, 0x451, 0x451, | |||
0x451, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, | 0x451, 0x451, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, | |||
0x4555, 0x554, 0x41, 0x441, 0x441, 0x41, 0x441, 0x441, | 0x4555, 0x4555, 0x554, 0x41, 0x441, 0x441, 0x41, 0x441, | |||
0x441, 0x441, 0x441, 0x551, 0x441, 0x441, 0x441, 0x441, | 0x441, 0x441, 0x441, 0x441, 0x551, 0x441, 0x441, 0x441, | |||
0x551, 0x441, 0x441, 0x551, 0x441, 0x441, 0x45, 0x4444, | 0x441, 0x551, 0x441, 0x441, 0x551, 0x441, 0x441, 0x45, | |||
0x4444, 0x4444, 0x4444, 0x41, 0x441, 0x441, 0x41, 0x44, | 0x4444, 0x4444, 0x4444, 0x4444, 0x41, 0x441, 0x441, 0x41, | |||
0x41, 0x444, 0x5545, 0x441, 0x4441, 0x4441, 0x4441, 0x4441, | 0x44, 0x41, 0x444, 0x5545, 0x441, 0x4441, 0x4441, 0x4441, | |||
0x441, 0x441, 0x441, 0x441, 0x441, 0x441, 0x441, 0x441, | 0x4441, 0x441, 0x441, 0x441, 0x441, 0x441, 0x441, 0x441, | |||
0x441, 0x441, 0x441, 0x4441, 0x4441, 0x4441, 0x4441, 0x57, | 0x441, 0x441, 0x441, 0x441, 0x4441, 0x4441, 0x4441, 0x4441, | |||
0x56, 0x75, 0x75, 0x76, 0x75, 0x75, 0x74, 0x74, | 0x58, 0x57, 0x85, 0x85, 0x87, 0x85, 0x85, 0x84, | |||
0x74, 0x74, 0x65, 0x65, 0x67, 0x65, 0x65, 0x64, | 0x84, 0x84, 0x84, 0x75, 0x75, 0x78, 0x75, 0x75, | |||
0x64, 0x64, 0x64, 0x57, 0x56, 0x47, 0x46, 0x47, | 0x74, 0x74, 0x74, 0x74, 0x58, 0x57, 0x48, 0x47, | |||
0x46, 0x777, 0x471, 0x771, 0x771, 0x771, 0x771, 0x777, | 0x48, 0x47, 0x888, 0x481, 0x881, 0x881, 0x881, 0x881, | |||
0x777, 0x77, 0x7777, 0x7777, 0x47777, 0x7777, 0x7777, 0x47, | 0x888, 0x888, 0x88, 0x8888, 0x8888, 0x48888, 0x8888, 0x8888, | |||
0x47, 0x777, 0x777, 0x777, 0x777, 0x666, 0x461, 0x661, | 0x48, 0x48, 0x888, 0x888, 0x888, 0x888, 0x777, 0x471, | |||
0x661, 0x661, 0x661, 0x666, 0x666, 0x66, 0x6666, 0x6666, | 0x771, 0x771, 0x771, 0x771, 0x777, 0x777, 0x77, 0x7777, | |||
0x46666, 0x6666, 0x6666, 0x46, 0x46, 0x666, 0x666, 0x666, | 0x7777, 0x47777, 0x7777, 0x7777, 0x47, 0x47, 0x777, 0x777, | |||
0x666, 0x4444, 0x4444, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, | 0x777, 0x777, 0x4444, 0x4444, 0x4455, 0x4455, 0x4455, 0x4455, | |||
0x4455, 0x445, 0x445, 0x444, 0x444, 0x444, 0x444, 0x445, | 0x4455, 0x4455, 0x445, 0x445, 0x444, 0x444, 0x444, 0x444, | |||
0x445, 0x445, 0x445, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, | 0x445, 0x445, 0x445, 0x445, 0x4455, 0x4455, 0x4455, 0x4455, | |||
0x4455, 0x444, 0x445, 0x4455, 0x4455, 0x445, 0x444, 0x444, | 0x4455, 0x4455, 0x444, 0x445, 0x4455, 0x4455, 0x445, 0x444, | |||
0x444, 0x444, 0x4444, 0x4444, 0x4444, 0x5555, 0x5555, 0x5555, | 0x444, 0x444, 0x444, 0x4444, 0x4444, 0x4444, 0x5555, 0x5555, | |||
0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, | 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, | |||
0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x555, 0x555, 0x555, | 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x555, 0x555, | |||
0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | |||
0x555, 0x555, 0x555, 0x555, 0x555, 0x4444, 0x4444, 0x4444, | 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x4444, 0x4444, | |||
0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, | 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, | |||
0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x444, 0x444, | 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x444, | |||
0x444, 0x444, 0x444, 0x444, 0x444, 0x4444, 0x4444, 0x4444, | 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x4444, 0x4444, | |||
0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, | 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, | |||
0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x444, 0x444, | 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x444, | |||
0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | |||
0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | |||
0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, | |||
0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, | 0x444, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, | |||
0x445, 0x445, 0x445, 0x445, 0x445, 0x445, 0x445, 0x445, | 0x4455, 0x445, 0x445, 0x445, 0x445, 0x445, 0x445, 0x445, | |||
0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, | 0x445, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, | |||
0x445, 0x445, 0x445, 0x445, 0x445, 0x445, 0x445, 0x445, | 0x4455, 0x445, 0x445, 0x445, 0x445, 0x445, 0x445, 0x445, | |||
0x444, 0x444, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, | 0x445, 0x444, 0x444, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, | |||
0x4444, 0x4444, 0x4444, 0x444, 0x444, 0x444, 0x444, 0x444, | 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x444, 0x444, 0x444, | |||
0x444, 0x444, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, | 0x444, 0x444, 0x444, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, | |||
0x4444, 0x4444, 0x4444, 0x444, 0x4455, 0x4455, 0x4455, 0x4455, | 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x4455, 0x4455, 0x4455, | |||
0x4455, 0x4455, 0x4455, 0x4455, 0x445, 0x445, 0x445, 0x445, | 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x445, 0x445, 0x445, | |||
0x445, 0x445, 0x445, 0x445, 0x4455, 0x4455, 0x4455, 0x4455, | 0x445, 0x445, 0x445, 0x445, 0x445, 0x4455, 0x4455, 0x4455, | |||
0x4455, 0x4455, 0x4455, 0x4455, 0x444, 0x4444, 0x4444, 0x4444, | 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x444, 0x4444, 0x4444, | |||
0x555, 0x555, 0x5555, 0x5555, 0x555, 0x555, 0x555, 0x555, | 0x4444, 0x555, 0x555, 0x5555, 0x5555, 0x555, 0x555, 0x555, | |||
0x5555, 0x5555, 0x554, 0x554, 0x555, 0x555, 0x4455, 0x5555, | 0x555, 0x5555, 0x5555, 0x554, 0x554, 0x555, 0x555, 0x4455, | |||
0x5555, 0x5555, 0x4455, 0x4455, 0x4455, 0x4455, 0x555, 0x555, | 0x5555, 0x5555, 0x5555, 0x4455, 0x4455, 0x4455, 0x4455, 0x555, | |||
0x445, 0x444, 0x445, 0x444, 0x445, 0x445, 0x554, 0x554, | 0x555, 0x445, 0x444, 0x445, 0x444, 0x445, 0x445, 0x554, | |||
0x5555, 0x5555, 0x5555, 0x5555, 0x555, 0x555, 0x555, 0x555, | 0x554, 0x5555, 0x5555, 0x5555, 0x5555, 0x555, 0x555, 0x555, | |||
0x4555, 0x455, 0x454, 0x5555, 0x555, 0x4444, 0x4444, 0x4444, | 0x555, 0x4555, 0x455, 0x454, 0x5555, 0x555, 0x4444, 0x4444, | |||
0x4444, 0x4444, 0x454, 0x454, 0x454, 0x454, 0x4444, 0x4444, | 0x4444, 0x4444, 0x4444, 0x454, 0x454, 0x454, 0x454, 0x4444, | |||
0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, | 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, | |||
0x4444, 0x445, 0x4455, 0x445, 0x4455, 0x5555, 0x5555, 0x555, | 0x4444, 0x4444, 0x445, 0x4455, 0x445, 0x4455, 0x5555, 0x5555, | |||
0x555, 0x5555, 0x5555, 0x555, 0x555, 0x4444, 0x4444, 0x4444, | 0x555, 0x555, 0x5555, 0x5555, 0x555, 0x555, 0x4444, 0x4444, | |||
0x5555, 0x5555, 0x555, 0x4455, 0x4455, 0x445, 0x445, 0x5555, | 0x4444, 0x5555, 0x5555, 0x555, 0x4455, 0x4455, 0x445, 0x445, | |||
0x5555, 0x555, 0x555, 0x4444, 0x455, 0x4555, 0x4555, 0x4555, | 0x5555, 0x5555, 0x555, 0x555, 0x4444, 0x455, 0x4555, 0x4555, | |||
0x4555, 0x4555, 0x4555, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, | ||||
0x444, 0x4444, 0x455, 0x455, 0x455, 0x4555, 0x4555, 0x4555, | ||||
0x4555, 0x4555, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, | 0x4555, 0x4555, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, | |||
0x4444, 0x455, 0x455, 0x455, 0x4555, 0x4555, 0x4555, 0x4555, | 0x455, 0x455, 0x455, 0x4555, 0x4555, 0x4555, 0x4555, 0x455, | |||
0x4555, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x455, | 0x455, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x444, | |||
0x455, 0x455, 0x4555, 0x4555, 0x4555, 0x4555, 0x455, 0x455, | 0x454, 0x455, 0x455, 0x455, 0x4555, 0x4555, 0x4555, 0x4555, | |||
0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x444, 0x454, | 0x4555, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x454, | |||
0x455, 0x455, 0x455, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, | 0x455, 0x455, 0x44, 0x55, 0x44, 0x54, 0x44, 0x54, | |||
0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x454, 0x455, | 0x44, 0x44, 0x54, 0x444, 0x444, 0x44, 0x54, 0x44, | |||
0x455, 0x44, 0x55, 0x44, 0x54, 0x44, 0x54, 0x44, | 0x54, 0x55, 0x4444, 0x544, 0x4455, 0x555, 0x44444, 0x5444, | |||
0x44, 0x54, 0x444, 0x444, 0x44, 0x54, 0x44, 0x54, | 0x44555, 0x5555, 0x55, 0x555, 0x455, 0x4555, 0x4555, 0x4555, | |||
0x55, 0x4444, 0x544, 0x4455, 0x555, 0x44444, 0x5444, 0x44555, | 0x4555, 0x4555, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x455, | |||
0x5555, 0x55, 0x555, 0x455, 0x4555, 0x4555, 0x4555, 0x4555, | 0x455, 0x455, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x444, | |||
0x4555, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x455, 0x455, | 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x455, 0x455, 0x455, | |||
0x455, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x444, 0x4444, | 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x444, 0x4444, 0x4444, | |||
0x4444, 0x4444, 0x4444, 0x4444, 0x455, 0x455, 0x455, 0x4555, | 0x4444, 0x4444, 0x455, 0x455, 0x445, 0x554, 0x444, 0x444, | |||
0x4555, 0x4555, 0x4555, 0x4555, 0x444, 0x4444, 0x4444, 0x4444, | 0x555, 0x555, 0x555, 0x555, 0x44, 0x44, 0x44444, 0x44444, | |||
0x4444, 0x455, 0x455, 0x445, 0x554, 0x444, 0x444, 0x555, | 0x44444, 0x44444, 0x444, 0x444, 0x441, 0x441, 0x4555, 0x4555, | |||
0x555, 0x555, 0x555, 0x44, 0x44, 0x44444, 0x44444, 0x44444, | 0x455, 0x455, 0x4555, 0x54, 0x54, 0x54, 0x55, 0x54, | |||
0x44444, 0x444, 0x444, 0x441, 0x441, 0x4555, 0x4555, 0x455, | 0x55, 0x54, 0x55, 0x54, 0x55, 0x44, 0x45, 0x4555, | |||
0x455, 0x4555, 0x54, 0x54, 0x54, 0x55, 0x54, 0x55, | 0x4555, 0x45, 0x45, 0x54, 0x555, 0x54, 0x555, 0x45, | |||
0x54, 0x55, 0x54, 0x55, 0x44, 0x45, 0x4555, 0x4555, | 0x45, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x454, | |||
0x45, 0x45, 0x54, 0x555, 0x54, 0x555, 0x45, 0x45, | 0x54, 0x4444, 0x544, 0x4455, 0x555, 0x444, 0x441, 0x441, | |||
0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x454, 0x54, | 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x4444, 0x4444, | |||
0x4444, 0x544, 0x4455, 0x555, 0x444, 0x441, 0x441, 0x4444, | 0x4444, 0x4455, 0x44555, 0x555, 0x555, 0x555, 0x555, 0x555, | |||
0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x4444, 0x4444, 0x4444, | 0x555, 0x454, 0x454, 0x54, 0x455, 0x44, 0x442E2E2E, 0x2E2E2E0, | |||
0x4455, 0x44555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, | (1U<<31) | 282, (1U<<31) | 283, 0x2E50, 0x2E50, 0x1F1F, 0x1F1F, 0x1F1F, 0 | |||
0x454, 0x454, 0x54, 0x455, 0x44, 0x442E2E2E, 0x2E2E2E0, (1U<<31) | 282, | x42E0, | |||
(1U<<31) | 283, 0x2E50, 0x2E50, 0x1F1F, 0x1F1F, 0x1F1F, 0x42E0, (1U<<31) | (1U<<31) | 9, (1U<<31) | 9, 0x144F23F0, 0x3939, 0x2A2A, 0x44, 0x393939, 0 | |||
| 9, | x393939, | |||
(1U<<31) | 9, 0x144F23F0, 0x3838, 0x2929, 0x44, 0x383838, 0x383838, 0x444 | 0x444, 0x393939, 0x393939, 0x444, 0x444, 0x444, 0x393939, 0x2A2A2A, | |||
, | 0x393939, 0x2A2A2A, 0x2A2A2A, 0x2A2A2A, 0x444, 0x4444, 0x4444, 0x44, | |||
0x383838, 0x383838, 0x444, 0x444, 0x444, 0x383838, 0x292929, 0x383838, | 0x4, 0x39390, 0x39390, 0x39390, 0x2A2A4, 0x2A2A4, 0x2A2A4, 0x2A2A4, | |||
0x292929, 0x292929, 0x292929, 0x444, 0x4444, 0x4444, 0x44, 0x4, | 0x2A2A4, 0x2A2A4, 0x2A2A0, 0x2A2A0, 0x2A2A0, 0x393955, 0x393955, 0x4455, | |||
0x38380, 0x38380, 0x38380, 0x29294, 0x29294, 0x29294, 0x29294, 0x29294, | 0x393955, 0x393955, 0x2A2A55, 0x2A2A55, 0x393955, 0x393955, 0x393955, 0x4 | |||
0x29294, 0x29290, 0x29290, 0x29290, 0x383855, 0x383855, 0x4455, 0x383855, | 455, | |||
0x383855, 0x292955, 0x292955, 0x383855, 0x383855, 0x383855, 0x4455, 0x383 | 0x393955, 0x393955, 0x2A2A55, 0x2A2A55, 0x393955, 0x454, 0x454, 0x454, | |||
855, | 0x454, 0x454, 0x454, 0x444, 0x42E4, 0x42E4, 0x42E4, 0x4455, | |||
0x383855, 0x292955, 0x292955, 0x383855, 0x454, 0x454, 0x454, 0x454, | 0x4455, 0x393955, 0x393955, 0x393955, 0x393955, 0x444, 0x4455, 0x4455, | |||
0x454, 0x454, 0x444, 0x42E4, 0x42E4, 0x42E4, 0x4455, 0x4455, | 0x455, 0x393939, 0x393939, 0x39394, 0x39394, 0x392A39, 0x392A39, 0x393939 | |||
0x383855, 0x383855, 0x383855, 0x383855, 0x444, 0x4455, 0x4455, 0x455, | , | |||
0x383838, 0x383838, 0x38384, 0x38384, 0x382938, 0x382938, 0x383838, 0x444 | 0x444, 0x393939, 0x444, 0x393955, 0x393955, 0x445, 0x445, 0x393939, | |||
, | 0x393939, 0x2A2A2A, 0x394, 0x394, 0x2A39, 0x2A39, 0x2A39, 0x2A39, | |||
0x383838, 0x444, 0x383855, 0x383855, 0x445, 0x445, 0x383838, 0x383838, | 0x2A39, 0x2A39, 0x2A39, 0x2A39, 0x39392A, 0x44439, 0x44439, 0x4439, | |||
0x292929, 0x384, 0x384, 0x2938, 0x2938, 0x2938, 0x2938, 0x2938, | 0x39392A, 0x4439, 0x39392A, 0x4444, 0x2A4, 0x44, 0x439, 0x42A, | |||
0x2938, 0x2938, 0x2938, 0x383829, 0x44438, 0x44438, 0x4438, 0x383829, | 0x455, 0x43939, 0x42A2A, 0x43939, 0x444, 0x43939, 0x42A2A, 0x43939, | |||
0x4438, 0x383829, 0x4444, 0x294, 0x44, 0x438, 0x429, 0x455, | 0x42A2A, 0x444, 0x43939, 0x42A2A, 0x393939, 0x393939, 0x444, 0x393939, | |||
0x43838, 0x42929, 0x43838, 0x444, 0x43838, 0x42929, 0x43838, 0x42929, | 0x393939, 0x444, 0x444, 0x393939, 0x2A2A2A, 0x393939, 0x2A2A2A, 0x2A2A2A, | |||
0x444, 0x43838, 0x42929, 0x383838, 0x383838, 0x444, 0x383838, 0x383838, | 0x2A2A2A, 0x440, 0x1F1F, 0x44, 0x55, 0x888, 0x777, 0x777, | |||
0x444, 0x444, 0x383838, 0x292929, 0x383838, 0x292929, 0x292929, 0x292929, | 0x888, 0x777, 0x777, 0x888, 0x777, 0x777, 0x888, 0x777, | |||
0x440, 0x44, 0x55, 0x777, 0x666, 0x666, 0x777, 0x666, | 0x777, 0x73F7, 0x43F4, 0x43F4, 0x0, 0x44, 0x44, 0x44, | |||
0x666, 0x777, 0x666, 0x666, 0x777, 0x666, 0x666, 0x63F6, | 0x85, 0x74, 0x47, 0x58, 0x44, 0x55, 0x88, 0x77, | |||
0x43F4, 0x43F4, 0x0, 0x44, 0x44, 0x44, 0x75, 0x64, | 0x77, 0x44, 0x54, 0x3F0, 0x3F0, 0x77, 0x77, 0x87, | |||
0x46, 0x57, 0x44, 0x55, 0x77, 0x66, 0x66, 0x44, | 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x84, | |||
0x54, 0x3F0, 0x3F0, 0x66, 0x66, 0x76, 0x76, 0x76, | 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, | |||
0x76, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x74, | 0x85, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, | |||
0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x74, | 0x85, 0x777, 0x777, 0x888, 0x777, 0x777, 0x888, 0x777, | |||
0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x666, | 0x777, 0x888, 0x777, 0x777, 0x888, 0x777, 0x777, 0x88, | |||
0x666, 0x777, 0x666, 0x666, 0x777, 0x666, 0x666, 0x777, | 0x77, 0x77, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, | |||
0x666, 0x666, 0x777, 0x666, 0x666, 0x77, 0x66, 0x66, | 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, | |||
0x63, 0x63, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, | 0x75, 0x75, 0x75, 0x75, 0x74, 0x74, 0x74, 0x74, | |||
0x64, 0x64, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, | 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, | |||
0x65, 0x65, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, | 0x75, 0x75, 0x75, 0x75, 0x88, 0x77, 0x77, 0x88, | |||
0x64, 0x64, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, | 0x77, 0x77, 0x8888, 0x7777, 0x7777, 0x8888, 0x7777, 0x7777, | |||
0x65, 0x65, 0x77, 0x66, 0x66, 0x77, 0x66, 0x66, | 0x8888, 0x7777, 0x7777, 0x8888, 0x7777, 0x7777, 0x888, 0x777, | |||
0x7777, 0x6666, 0x6666, 0x7777, 0x6666, 0x6666, 0x7777, 0x6666, | 0x777, 0x888, 0x777, 0x777, 0x37, 0x48, 0x48, 0x48, | |||
0x6666, 0x7777, 0x6666, 0x6666, 0x777, 0x666, 0x666, 0x777, | 0x48, 0x47, 0x47, 0x47, 0x47, 0x1FE1F, 0xFE0F, 0x3FE3F, | |||
0x666, 0x666, 0x36, 0x47, 0x47, 0x47, 0x47, 0x46, | 0x1FE1F, 0xFE0F, 0x3FE3F, 0x88, 0x77, 0x77, 0x58, 0x58, | |||
0x46, 0x46, 0x46, 0x1FE1F, 0xFE0F, 0x3FE3F, 0x77, 0x66, | 0x58, 0x58, 0x57, 0x57, 0x57, 0x57, 0x448, 0x444, | |||
0x66, 0x57, 0x57, 0x57, 0x57, 0x56, 0x56, 0x56, | 0x555, 0x444, 0x555, 0x0, 0x0, 0x0, 0x444, 0x555, | |||
0x56, 0x447, 0x444, 0x555, 0x444, 0x555, 0x0, 0x0, | 0x444, 0x555, 0x88, 0x77, 0x33, 0x44, 0x55, 0x22, | |||
0x0, 0x444, 0x555, 0x444, 0x555, 0x77, 0x66, 0x33, | 0x7F3F, 0x444, 0x444, 0x888, 0x777, 0x777, 0x888, 0x777, | |||
0x44, 0x55, 0x22, 0x7F3F, 0x444, 0x444, 0x777, 0x666, | 0x777, 0x888, 0x777, 0x777, 0x888, 0x777, 0x777, 0x444, | |||
0x666, 0x777, 0x666, 0x666, 0x777, 0x666, 0x666, 0x777, | 0x555, 0x444, 0x555, 0x44, 0x54, 0x4444, 0x7F3F, 0x7F3F, | |||
0x666, 0x666, 0x444, 0x555, 0x444, 0x555, 0x44, 0x54, | 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x88, | |||
0x4444, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, | 0x88, 0x77, 0x77, 0x88, 0x77, 0x77, 0x88, 0x77, | |||
0x7F3F, 0x7F3F, 0x77, 0x77, 0x66, 0x66, 0x77, 0x66, | 0x77, 0x88, 0x77, 0x77, 0x4, 0x4, 0x4, 0x4, | |||
0x66, 0x77, 0x66, 0x66, 0x77, 0x66, 0x66, 0x4, | 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, | |||
0x4, 0x88, 0x77, 0x77, 0x88, 0x77, 0x77, 0x4444, | ||||
0x4444, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, | ||||
0x77, 0x88, 0x77, 0x77, 0x88, 0x77, 0x77, 0x88, | ||||
0x77, 0x77, 0x88, 0x77, 0x77, 0x88, 0x77, 0x77, | ||||
0x48, 0x48, 0x48, 0x48, 0x47, 0x47, 0x47, 0x47, | ||||
0x58, 0x58, 0x58, 0x58, 0x57, 0x57, 0x57, 0x57, | ||||
0x12E0F, 0x40, 0x1F1F1F, 0x41F1F, 0x40, 0x0, 0x442E0, 0x442E0, | ||||
0x442E0, 0x442E0, 0x2E2C, 0x2E3B, 0x2E4A, 0x2E2C, 0x2E2C, 0x2E4A, | ||||
0x2E4A, 0x3B, 0x4A0, 0x2E2C0, 0x2E3B0, 0x2E4A0, 0x2E4A0, 0x2E4A0, | ||||
0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x2 | ||||
C2C2C, | ||||
0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x44A7A, 0x44A7A, 0x7A7 | ||||
A4A, | ||||
0x7A7A44, 0x7A7A4A, 0x7A7A44, 0x2C2C2C, 0x2C2C44, 0x3B3B3B, 0x3B3B44, 0x4 | ||||
A4A4A, | ||||
0x4A4A44, 0x7A7A4A, 0x7A7A44, 0x7A7A4A, 0x7A7A44, 0x2C2C2C, 0x2C2C44, 0x3 | ||||
B3B3B, | ||||
0x3B3B44, 0x4A4A4A, 0x4A4A44, 0x2C2C2C, 0x2C2C44, 0x3B3B3B, 0x3B3B44, 0x4 | ||||
A4A4A, | ||||
0x4A4A44, 0x47A4A, 0x47A4A, 0x7A7A, 0x7A7A, 0x7A7A7A7A, 0x7A7A7A, 0x2C2C2 | ||||
C, | ||||
0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x3B3B3B3B, 0x3B3B3B3B, | ||||
0x7A7A7A, | ||||
0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x3B3B3B3B, 0 | ||||
x4A2C2C4A, | ||||
0x4A3B3B4A, 0x4A3B3B4A, 0x4A2C2C4A, 0x4A3B3B4A, 0x4A3B3B4A, 0x2C2C3B, 0x3 | ||||
B3B4A, 0x2C2C3B, | ||||
0x3B3B4A, 0x2C2C3B, 0x3B3B4A, 0x2C2C3B, 0x3B3B4A, 0x7A7A7A7A, 0x2C4A4A4A, | ||||
0x4A4A3B, | ||||
0x3B3B2C, 0x3B3B2C, 0x4A4A2C, 0x4A4A3B, 0x3B3B2C, 0x4A4A3B, 0x7A7A, 0x7A7 | ||||
A, | ||||
0x7A7A, 0x7A7A, 0x7A7A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x7A7A, 0x4A4A4A4A, | ||||
0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x4A4A4A, 0x4A4A4A, 0x2C2C2C, 0x3 | ||||
B3B3B, | ||||
0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x4A4A4A, 0x4A4A4A, 0x2C2C2C, 0x3 | ||||
B3B3B, | ||||
0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x4A4A4A, 0x4A2C4A, 0x4A3B4A, 0x4 | ||||
A2C4A, | ||||
0x4A4A4A, 0x3B4A, 0x2C3B, 0x3B4A, 0x3B4A, 0x2C3B, 0x3B4A, 0x2E0, | ||||
0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x0, | ||||
0x4442E0, (1U<<31) | 331, 0x40, 0x4, 0x5, 0x4, 0x4, 0x4, | ||||
0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, | ||||
0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, | 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, | |||
0x4, 0x4, 0x4, 0x4, 0x77, 0x66, 0x66, 0x77, | ||||
0x66, 0x66, 0x4444, 0x4444, 0x77, 0x66, 0x66, 0x66, | ||||
0x66, 0x66, 0x66, 0x77, 0x66, 0x66, 0x77, 0x66, | ||||
0x66, 0x77, 0x66, 0x66, 0x77, 0x66, 0x66, 0x77, | ||||
0x66, 0x66, 0x47, 0x47, 0x47, 0x47, 0x46, 0x46, | ||||
0x46, 0x46, 0x57, 0x57, 0x57, 0x57, 0x56, 0x56, | ||||
0x56, 0x56, 0x12E0F, 0x40, 0x1F1F1F, 0x41F1F, 0x40, 0x0, | ||||
0x442E0, 0x442E0, 0x442E0, 0x442E0, 0x2E2B, 0x2E3A, 0x2E49, 0x2E2B, | ||||
0x2E2B, 0x2E49, 0x2E49, 0x3A, 0x490, 0x2E2B0, 0x2E3A0, 0x2E490, | ||||
0x2E490, 0x2E490, 0x494949, 0x2B2B2B, 0x3A3A3A, 0x494949, 0x2B2B2B, 0x3A3 | ||||
A3A, | ||||
0x494949, 0x2B2B2B, 0x3A3A3A, 0x494949, 0x2B2B2B, 0x3A3A3A, 0x494949, 0x4 | ||||
4969, | ||||
0x44969, 0x696949, 0x696944, 0x696949, 0x696944, 0x2B2B2B, 0x2B2B44, 0x3A | ||||
3A3A, | ||||
0x3A3A44, 0x494949, 0x494944, 0x696949, 0x696944, 0x696949, 0x696944, 0x2 | ||||
B2B2B, | ||||
0x2B2B44, 0x3A3A3A, 0x3A3A44, 0x494949, 0x494944, 0x2B2B2B, 0x2B2B44, 0x3 | ||||
A3A3A, | ||||
0x3A3A44, 0x494949, 0x494944, 0x46949, 0x46949, 0x6969, 0x6969, 0x6969696 | ||||
9, | ||||
0x696969, 0x2B2B2B, 0x3A3A3A, 0x494949, 0x2B2B2B, 0x3A3A3A, 0x494949, 0x3 | ||||
A3A3A3A, | ||||
0x3A3A3A3A, 0x696969, 0x2B2B2B, 0x3A3A3A, 0x494949, 0x2B2B2B, 0x3A3A3A, 0 | ||||
x494949, | ||||
0x3A3A3A3A, 0x492B2B49, 0x493A3A49, 0x493A3A49, 0x492B2B49, 0x493A3A49, 0 | ||||
x493A3A49, 0x2B2B3A, | ||||
0x3A3A49, 0x2B2B3A, 0x3A3A49, 0x2B2B3A, 0x3A3A49, 0x2B2B3A, 0x3A3A49, 0x6 | ||||
9696969, | ||||
0x2B494949, 0x49493A, 0x3A3A2B, 0x3A3A2B, 0x49492B, 0x49493A, 0x3A3A2B, 0 | ||||
x49493A, | ||||
0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x2B2B2B, 0x3A3A3A, 0x494949, | ||||
0x6969, 0x49494949, 0x494949, 0x2B2B2B, 0x3A3A3A, 0x494949, 0x494949, 0x4 | ||||
94949, | ||||
0x2B2B2B, 0x3A3A3A, 0x494949, 0x2B2B2B, 0x3A3A3A, 0x494949, 0x494949, 0x4 | ||||
94949, | ||||
0x2B2B2B, 0x3A3A3A, 0x494949, 0x2B2B2B, 0x3A3A3A, 0x494949, 0x494949, 0x4 | ||||
92B49, | ||||
0x493A49, 0x492B49, 0x494949, 0x3A49, 0x2B3A, 0x3A49, 0x3A49, 0x2B3A, | ||||
0x3A49, 0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x2E0, | ||||
0x2E0, 0x0, 0x4442E0, (1U<<31) | 320, 0x40, 0x4, 0x5, 0x4, | ||||
0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, | 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, | |||
0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, | 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, | |||
0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, | 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, | |||
0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x42E, | 0x4, 0x4, 0x4, 0x5, 0x42E, 0x1F1F, (1U<<31) | 0, 0x2E4, | |||
(1U<<31) | 0, 0x2E4, 0x42E0, 0x42E4, 0x1F1F, (1U<<31) | 0, 0x494949, 0x49 | 0x42E0, 0x42E4, 0x1F1F, (1U<<31) | 0, 0x1F1F, (1U<<31) | 0, 0x2EE2E0, 0x2 | |||
4949, | E0, | |||
0x3A3A3A, 0x33A3A, 0x34949, 0x494949, 0x22B2B, 0x494949, 0x33A3A, 0x34949 | 0x2E, 0x0, 0x1F1F, (1U<<31) | 0, (1U<<31) | 0, (1U<<31) | 0, 0x2E2E0, 0x2 | |||
, | E0, | |||
0x494949, 0x494949, 0x494949, 0x2B2B2B, 0x22B2B, 0x3A3A3A, 0x33A3A, 0x349 | 0x42E2E2E0, 0x2E0, (1U<<31) | 564, (1U<<31) | 561, (1U<<31) | 564, (1U<<3 | |||
49, | 1) | 564, (1U<<31) | 564, (1U<<31) | 564, | |||
0x494949, 0x494949, 0x2B2B2B, 0x22B2B, 0x3A3A3A, 0x33A3A, 0x34949, 0x4949 | (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | |||
49, | | 561, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, | |||
0x494949, 0x2B2B2B, 0x22B2B, 0x3A3A3A, 0x33A3A, 0x34949, 0x787878, 0x7878 | (1U<<31) | 561, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 561, (1U<<31) | |||
78, | | 564, (1U<<31) | 561, (1U<<31) | 564, (1U<<31) | 564, | |||
0x787878, 0x787878, 0x787878, 0x787878, 0x787878, 0x696969, 0x696969, 0x6 | (1U<<31) | 561, (1U<<31) | 561, 0x595959, 0x595959, 0x595959, 0x595959, 0 | |||
96969, | x5959, 0x25959, | |||
0x696969, 0x696969, 0x696969, 0x69696969, 0x69696969, 0x69696969, 0x69696 | (1U<<31) | 29, (1U<<31) | 65, (1U<<31) | 193, (1U<<31) | 227, (1U<<31) | | |||
9, 0x33A3A, | 125, (1U<<31) | 171, (1U<<31) | 77, (1U<<31) | 101, | |||
0x3A3A49, 0x3A3A3A49, 0x3A4949, 0x3A3A49, 0x3A3A49, 0x3A3A49, 0x3A3A49, 0 | (1U<<31) | 41, (1U<<31) | 53, (1U<<31) | 205, (1U<<31) | 239, (1U<<31) | | |||
x33A49, | 137, (1U<<31) | 149, (1U<<31) | 89, (1U<<31) | 113, | |||
0x3A3A49, 0x3A3A49, 0x33A49, 0x494949, 0x494949, 0x494949, 0x22B2B, 0x494 | 0x4A2E4A, 0x4B2E4B, 0x592E59, 0x5A2E5A, 0x4A4A2E0, 0x4B4B2E0, 0x59592E0, | |||
949, | 0x5A5A2E0, | |||
0x33A3A, 0x34949, 0x494949, 0x3A3A3A, 0x33A3A, 0x34949, 0x494949, 0x24949 | 0x2E5A, 0x42D2D3C, 0x2D2D, 0x4B4B, 0x3C3C, 0x4B4B3C, 0x3C3C2D, 0x4B4B3C, | |||
, | 0x3C3C2D, 0x2D2D2D, 0x3C3C3C, 0x2D2D2D, 0x3C3C3C, 0x2D2D2D, 0x3C3C3C, 0x4 | |||
0x43A3A, 0x22B2B, 0x43A3A, 0x22B2B, 0x494949, 0x22B2B, 0x33A3A, 0x34949, | 4A4A4A, | |||
0x1F1F, (1U<<31) | 0, 0x2EE2E0, 0x2E0, 0x2E, 0x0, (1U<<31) | 0, (1U<<31) | 0x44B4B4B, 0x2D2D2D2D, 0x43C3C3C, 0x2C2C, 0x2C2D, 0x4A4A, 0x4A4B, 0x5959, | |||
| 0, | 0x595A, 0x3B3B, 0x3B3C, 0x4B4B4B, 0x7B7B7B, 0x4B4B4B, 0x3C3C3C, 0x3C3C3C, | |||
(1U<<31) | 0, 0x2E2E0, 0x2E0, 0x42E2E2E0, 0x2E0, 0xDDD, 0xDD, 0xDDD, | 0x4B4B4B, 0x3C3C3C, 0x3C3C3C, 0x2D2D3C, 0x3C3C4B, 0x2D2D2D, 0x4B4B4B, 0x3 | |||
0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDD, | C3C3C, | |||
0xDDD, 0xDDD, 0xDDD, 0xDD, 0xDDD, 0xDDD, 0xDD, 0xDDD, | 0x2D2D2D, 0x4B4B4B, 0x3C3C3C, 0x2D2D2D, 0x4B4B4B, 0x3C3C3C, 0x2D2D2D, 0x4 | |||
0xDD, 0xDDD, 0xDDD, 0xDD, 0xDD, 0x585858, 0x585858, 0x585858, | B4B4B, | |||
0x585858, 0x5858, 0x25858, (1U<<31) | 29, (1U<<31) | 65, (1U<<31) | 193, | 0x3C3C3C, 0x2D4, 0x2C4B, 0x2C5A, 0x2C3C, 0x4A5A, 0x3B4B, 0x3B5A, | |||
(1U<<31) | 227, (1U<<31) | 125, | 0x2C4B, 0x2C5A, 0x2C3C, 0x4A5A, 0x3B4B, 0x3B5A, 0x4B4B5A, 0x3C3C3C, | |||
(1U<<31) | 171, (1U<<31) | 77, (1U<<31) | 101, (1U<<31) | 41, (1U<<31) | | 0x3C3C3C, 0x3C3C3C, 0x4B4B5A, 0x2D2D5A, 0x2D2D2D, 0x2D2D2D, 0x4B4B4B, 0x3 | |||
53, (1U<<31) | 205, (1U<<31) | 239, (1U<<31) | 137, | C3C3C, | |||
(1U<<31) | 149, (1U<<31) | 89, (1U<<31) | 113, 0x492E49, 0x4A2E4A, 0x582E | 0x4A4B4B, 0x45A5A, 0x45A5A, 0x595A5A, 0x3B3C3C, 0x44B4B, 0x45A5A, 0x43C3C | |||
58, 0x592E59, 0x49492E0, | , | |||
0x4A4A2E0, 0x58582E0, 0x59592E0, 0x2E59, 0x42C2C3B, 0x2C2C, 0x4A4A, 0x3B3 | 0x4A4A4A, 0x4B4B4B, 0x595959, 0x5A5A5A, 0x4A4B4B, 0x3B3C3C, 0x44B4B, 0x43 | |||
B, | C3C, | |||
0x4A4A3B, 0x3B3B2C, 0x4A4A3B, 0x3B3B2C, 0x2C2C2C, 0x3B3B3B, 0x2C2C2C, 0x3 | 0x4A4A4A, 0x4B4B4B, 0x4A4B4B, 0x45A5A, 0x45A5A, 0x595A5A, 0x3B3C3C, 0x44B | |||
B3B3B, | 4B, | |||
0x2C2C2C, 0x3B3B3B, 0x4494949, 0x44A4A4A, 0x2C2C2C2C, 0x43B3B3B, 0x2B2B, | 0x45A5A, 0x43C3C, 0x4A4A4A, 0x4B4B4B, 0x595959, 0x5A5A5A, 0x2D2D2D, 0x3C3 | |||
0x2B2C, | C3C, | |||
0x4949, 0x494A, 0x5858, 0x5859, 0x3A3A, 0x3A3B, 0x4A4A4A, 0x6A6A6A, | 0x2D2D2D, 0x3C3C3C, 0x898A, 0x7A7A, 0x7A7B, 0x2E5A, 0x25A59, 0x2595A5A, | |||
0x4A4A4A, 0x3B3B3B, 0x3B3B3B, 0x4A4A4A, 0x3B3B3B, 0x3B3B3B, 0x2C2C3B, 0x3 | 0x25A5A5A, 0x8A8A8A, 0x7B7B7B, 0x48A8A8A, 0x47B7B7B, (1U<<31) | 537, 0x7B | |||
B3B4A, | 7B7B7B, 0x28A8A8A, | |||
0x2C2C2C, 0x4A4A4A, 0x3B3B3B, 0x2C2C2C, 0x4A4A4A, 0x3B3B3B, 0x2C2C2C, 0x4 | 0x27B7B7B, 0x8A7A, 0x8A4A, 0x7A8A, 0x7B4B, 0x4A8A, 0x4B7B, 0x8A4A, | |||
A4A4A, | 0x7B4B, 0x47B7B7B, 0x8A8A8A, 0x7B7B7B, 0x8A8A8A, 0x7B7B7B, 0x2E2D, 0x892E | |||
0x3B3B3B, 0x2C2C2C, 0x4A4A4A, 0x3B3B3B, 0x2C4, 0x2B4A, 0x2B59, 0x2B3B, | 89, | |||
0x4959, 0x3A4A, 0x3A59, 0x2B4A, 0x2B59, 0x2B3B, 0x4959, 0x3A4A, | 0x8A2E8A, 0x7A2E7A, 0x7B2E7B, 0x89892E0, 0x8A8A2E0, 0x7A7A2E0, 0x7B7B2E0, | |||
0x3A59, 0x4A4A59, 0x3B3B3B, 0x3B3B3B, 0x3B3B3B, 0x4A4A59, 0x2C2C59, 0x2C2 | 0x8A8A8A, | |||
C2C, | 0x7B7B7B, 0x8A8A8A, 0x7B7B7B, 0x8A4, 0x7B4, 0x5A5A4, 0x5A5A4, 0x5A5A4, | |||
0x2C2C2C, 0x4A4A4A, 0x3B3B3B, 0x494A4A, 0x45959, 0x45959, 0x585959, 0x3A3 | 0x7B7B, 0x48A8A, 0x47B7B, 0x7B7B, 0x8A8A, 0x7B7B, 0x2D2E0, 0x8A2E0, | |||
B3B, | 0x7B2E0, 0x2E8A, 0x2E7A, 0x2E7B, 0x2E8A, 0x2E7B, 0x28A89, 0x27B7A, | |||
0x44A4A, 0x45959, 0x43B3B, 0x494949, 0x4A4A4A, 0x585858, 0x595959, 0x494A | 0x24B4A, 0x2898A8A, 0x27A7B7B, 0x24A4B4B, 0x28A8A8A, 0x27B7B7B, 0x24B4B4B | |||
4A, | , 0x598989, | |||
0x3A3B3B, 0x44A4A, 0x43B3B, 0x494949, 0x4A4A4A, 0x494A4A, 0x45959, 0x4595 | 0x5A8A8A, 0x4A7A7A, 0x4B7B7B, 0x89894, 0x8A8A4, 0x7A7A4, 0x7B7B4, 0x89894 | |||
9, | , | |||
0x585959, 0x3A3B3B, 0x44A4A, 0x45959, 0x43B3B, 0x494949, 0x4A4A4A, 0x5858 | 0x8A8A4, 0x7A7A4, 0x7B7B4, 0x89894, 0x8A8A4, 0x7A7A4, 0x7B7B4, 0x0, | |||
58, | 0x0, 0x444, 0x555, 0x444, 0x555, 0x444, 0x555, 0x444, | |||
0x595959, 0x2C2C2C, 0x3B3B3B, 0x2C2C2C, 0x3B3B3B, 0x7879, 0x6969, 0x696A, | 0x555, (1U<<31) | 524, (1U<<31) | 537, 0x7A7A7A7A, 0x7B7B7B7B, (1U<<31) | | |||
0x2E59, 0x25958, 0x2585959, 0x2595959, 0x797979, 0x6A6A6A, 0x4797979, 0x4 | 524, 0x7A7A7A7A, (1U<<31) | 524, | |||
6A6A6A, | (1U<<31) | 537, 0x7A7A7A7A, 0x7B7B7B7B, (1U<<31) | 524, (1U<<31) | 537, 0 | |||
0x79797979, 0x6A6A6A6A, 0x2797979, 0x26A6A6A, 0x7969, 0x7949, 0x6979, 0x6 | x7A7A7A7A, 0x7B7B7B7B, (1U<<31) | 524, | |||
A4A, | 0x7A7A7A7A, (1U<<31) | 524, (1U<<31) | 537, 0x7A7A7A7A, 0x7B7B7B7B, (1U<< | |||
0x4979, 0x4A6A, 0x7949, 0x6A4A, 0x46A6A6A, 0x797979, 0x6A6A6A, 0x797979, | 31) | 524, (1U<<31) | 537, 0x7A7A7A7A, | |||
0x6A6A6A, 0x2E2C, 0x782E78, 0x792E79, 0x692E69, 0x6A2E6A, 0x78782E0, 0x79 | 0x7B7B7B7B, (1U<<31) | 524, 0x7A7A7A7A, (1U<<31) | 524, (1U<<31) | 537, 0 | |||
792E0, | x7A7A7A7A, 0x7B7B7B7B, (1U<<31) | 524, | |||
0x69692E0, 0x6A6A2E0, 0x797979, 0x6A6A6A, 0x797979, 0x6A6A6A, 0x794, 0x6A | 0x7A7A7A7A, 0x20, 0x0, 0x0, (1U<<31) | 289, (1U<<31) | 559, (1U<<31) | 56 | |||
4, | 4, (1U<<31) | 564, | |||
0x59594, 0x59594, 0x59594, 0x6A6A, 0x47979, 0x46A6A, 0x6A6A, 0x7979, | (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | |||
0x6A6A, 0x2C2E0, 0x792E0, 0x6A2E0, 0x2E79, 0x2E69, 0x2E6A, 0x2E79, | | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, | |||
0x2E6A, 0x27978, 0x26A69, 0x24A49, 0x2787979, 0x2696A6A, 0x2494A4A, 0x279 | (1U<<31) | 564, (1U<<31) | 295, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | |||
7979, | | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, | |||
0x26A6A6A, 0x24A4A4A, 0x587878, 0x597979, 0x496969, 0x4A6A6A, 0x78784, 0x | (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | |||
79794, | | 512, (1U<<31) | 499, (1U<<31) | 564, (1U<<31) | 564, | |||
0x69694, 0x6A6A4, 0x78784, 0x79794, 0x69694, 0x6A6A4, 0x78784, 0x79794, | (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 546, (1U<<31) | |||
0x69694, 0x6A6A4, 0x0, 0x0, 0x444, 0x555, 0x444, 0x555, | | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, | |||
0x444, 0x555, 0x444, 0x555, 0x78787878, 0x79797979, 0x69696969, 0x6A6A6A6 | (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | |||
A, | | 564, (1U<<31) | 516, (1U<<31) | 516, (1U<<31) | 516, | |||
0x78787878, 0x69696969, 0x78787878, 0x79797979, 0x69696969, 0x6A6A6A6A, 0 | (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 516, (1U<<31) | 516, (1U<<31) | |||
x78787878, 0x79797979, | | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 516, | |||
0x69696969, 0x6A6A6A6A, 0x78787878, 0x69696969, 0x78787878, 0x79797979, 0 | (1U<<31) | 516, (1U<<31) | 516, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | |||
x69696969, 0x6A6A6A6A, | | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, | |||
0x78787878, 0x79797979, 0x69696969, 0x6A6A6A6A, 0x78787878, 0x69696969, 0 | (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | |||
x78787878, 0x79797979, | | 564, (1U<<31) | 564, (1U<<31) | 564, (1U<<31) | 564, | |||
0x69696969, 0x6A6A6A6A, 0x78787878, 0x69696969, 0x20, 0x0, 0x0, 0x2EDD0, | (1U<<31) | 564, 0x2595959, 0x4, 0x5, 0x4, 0x5, (1U<<31) | 398, (1U<<31) | | |||
0xDDE0, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, | 504, | |||
0xDDD, 0xDDD, 0xDDD, 0xDDD, 0x2DDD, 0xDDD, 0xDDD, 0xDDD, | (1U<<31) | 508, (1U<<31) | 398, (1U<<31) | 504, (1U<<31) | 508, 0x898989, | |||
0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0x4D4, | 0x2E0, 0x2898989, 0x2898989, | |||
0x44DD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xD4, 0xDDD, | 0x89894, 0x89894, 0x89894, 0x89894, 0x89894, 0x89894, 0x4A89, 0x4A7A, | |||
0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, | 0x894A, 0x897A, 0x7A4A, 0x7A89, 0x894, 0x895, 0x897A7A, 0x48989, | |||
0x4DD, 0x4DD, 0x4DD, 0xDDD, 0xDDD, 0x4DD, 0x4DD, 0xDDD, | 0x58989, 0x7A8989, 0x894A, 0x7A4A, 0x894, 0x895, 0x898989, 0x0, | |||
0xDDD, 0xDDD, 0x4DD, 0x4DD, 0x4DD, 0xDDD, 0xDDD, 0xDDD, | 0x2E2C2C0, 0x898989, 0x898989, 0x0, 0x898989, 0x898989, 0x894, 0x898989, | |||
0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, 0xDDD, | 0x4A4A3B, 0x3B3B2C, 0x3B3B2C, 0x2C2C2C, 0x3B3B3B, 0x2C2C2C, 0x3B3B3B, 0x2 | |||
0xDDD, 0xDDD, 0xDDD, 0xDDD, 0x2585858, 0x4, 0x5, 0x4, | C2C2C, | |||
0x5, (1U<<31) | 387, (1U<<31) | 488, (1U<<31) | 492, 0x787878, 0x2E0, 0x2 | 0x3B3B3B, 0x3B3B4A, 0x3B3B3B, 0x2C2C2C, 0x3B3B3B, 0x2C2C2C, 0x2C4, 0x3B3B | |||
787878, 0x2787878, | 3B, | |||
0x78784, 0x78784, 0x78784, 0x78784, 0x78784, 0x78784, 0x4978, 0x4969, | 0x3B3B3B, 0x4A4A59, 0x2C2C59, 0x4A4A4A, 0x45959, 0x45959, 0x595959, 0x3B3 | |||
0x7849, 0x7869, 0x6949, 0x6978, 0x784, 0x785, 0x786969, 0x47878, | B3B, | |||
0x57878, 0x697878, 0x7849, 0x6949, 0x784, 0x785, 0x787878, 0x0, | 0x44A4A, 0x45959, 0x43B3B, 0x4A4A4A, 0x3B3B3B, 0x44A4A, 0x43B3B, 0x4A4A4A | |||
0x2E2B2B0, 0x787878, 0x787878, 0x0, 0x787878, 0x787878, 0x784, 0x787878, | , | |||
0x49493A, 0x3A3A2B, 0x3A3A2B, 0x2B2B2B, 0x3A3A3A, 0x2B2B2B, 0x3A3A3A, 0x2 | 0x45959, 0x45959, 0x595959, 0x3B3B3B, 0x44A4A, 0x45959, 0x43B3B, 0x2C2C2C | |||
B2B2B, | , | |||
0x3A3A3A, 0x3A3A49, 0x3A3A3A, 0x2B2B2B, 0x3A3A3A, 0x2B2B2B, 0x2B4, 0x3A3A | 0x3B3B3B, 0x2C2C2C, 0x3B3B3B, 0x8989, 0x8989, 0x4A2E0, 0x2C2E0, 0x892E0, | |||
3A, | 0x898989, 0x89894, 0x89894, 0x89894, 0x89894, 0x89894, 0x89894, 0x898989, | |||
0x3A3A3A, 0x494958, 0x2B2B58, 0x494949, 0x45858, 0x45858, 0x585858, 0x3A3 | 0x7A7A7A, 0x898989, 0x7A7A7A, 0x898989, 0x7A7A7A, 0x2E2C, 0x442E0, 0x440, | |||
A3A, | 0x4898989, 0x47A7A7A, (1U<<31) | 524, 0x7A7A7A7A, 0x4898989, 0x47A7A7A, 0 | |||
0x44949, 0x45858, 0x43A3A, 0x494949, 0x3A3A3A, 0x44949, 0x43A3A, 0x494949 | x47A4, 0x47A7A7A, | |||
, | 0x2E59, 0x42C2C3B, 0x4A4A3B, 0x2C2C2C2C, 0x43B3B3B, 0x42C4, 0x44A4, 0x459 | |||
0x45858, 0x45858, 0x585858, 0x3A3A3A, 0x44949, 0x45858, 0x43A3A, 0x2B2B2B | 5, | |||
, | 0x3B3B, 0x2C2C2C, 0x4A4A4A, 0x4A4A4A, 0x3B3B3B, 0x2C2C2C, 0x4A4A4A, 0x4A4 | |||
0x3A3A3A, 0x2B2B2B, 0x3A3A3A, 0x7878, 0x7878, 0x492E0, 0x2B2E0, 0x782E0, | A4A, | |||
0x787878, 0x78784, 0x78784, 0x78784, 0x78784, 0x78784, 0x78784, 0x787878, | 0x3B3B3B, 0x2C4A, 0x2C59, 0x2C3B, 0x4A59, 0x3B4A, 0x3B59, 0x2C4A, | |||
0x696969, 0x787878, 0x696969, 0x787878, 0x696969, 0x2E2B, 0x442E0, 0x440, | 0x2C59, 0x2C3B, 0x4A59, 0x3B4A, 0x3B59, 0x4A4A59, 0x59594, 0x59594, | |||
0x4787878, 0x4696969, 0x78787878, 0x69696969, 0x4787878, 0x4696969, 0x469 | 0x59594, 0x48989, 0x47A7A, 0x4898989, 0x47A7A7A, 0x344, 0x444, 0x244, | |||
4, 0x4696969, | 0x555, 0x255, 0x242C42C4, 0x242C42C4, 0x242C42C4, 0x242C42C4, 0x242C42C4, | |||
0x2E58, 0x42B2B3A, 0x49493A, 0x2B2B2B2B, 0x43A3A3A, 0x42B4, 0x4494, 0x458 | 0x242C42C4, | |||
5, | (1U<<31) | 19, 0x22C2C4, 0x22C2C4, 0x22C2C4, 0x22C2C4, 0x22C2C4, 0x22C2C4 | |||
0x3A3A, 0x2B2B2B, 0x494949, 0x494949, 0x3A3A3A, 0x2B2B2B, 0x494949, 0x494 | , 0x22C2C2C, | |||
949, | 0x2C5959, 0x225959, 0x595959, 0x22595959, 0x892E0, 0x7A2E0, 0x7A7A7A, 0x2 | |||
0x3A3A3A, 0x2B49, 0x2B58, 0x2B3A, 0x4958, 0x3A49, 0x3A58, 0x2B49, | 7A7A7A, | |||
0x2B58, 0x2B3A, 0x4958, 0x3A49, 0x3A58, 0x494958, 0x58584, 0x58584, | 0x27A7A7A, 0x7A7A4, 0x7A7A4, 0x7A7A4, 0x7A7A4, 0x7A7A4, 0x7A7A4, (1U<<31) | |||
0x58584, 0x47878, 0x46969, 0x4787878, 0x4696969, 0x344, 0x444, 0x244, | | 533, | |||
0x555, 0x255, 0x242B42B4, 0x242B42B4, 0x242B42B4, 0x242B42B4, 0x242B42B4, | (1U<<31) | 555, (1U<<31) | 549, (1U<<31) | 520, 0x47A7A, 0x57A7A, 0x7A4, | |||
0x242B42B4, | 0x7A5, (1U<<31) | 533, | |||
(1U<<31) | 19, 0x22B2B4, 0x22B2B4, 0x22B2B4, 0x22B2B4, 0x22B2B4, 0x22B2B4 | (1U<<31) | 520, 0x7A4, 0x7A5, 0x7A7A7A, 0x2E0, 0x7A7A7A, 0x7A7A7A, 0x7A7A | |||
, 0x22B2B2B, | 7A, | |||
0x2B5858, 0x225858, 0x585858, 0x22585858, 0x782E0, 0x692E0, 0x696969, 0x2 | 0x7A7A7A, 0x7A4, 0x7A7A7A, (1U<<31) | 296, 0x7A7A, 0x7A7A, 0x7A7A, 0x7A7A | |||
696969, | , | |||
0x2696969, 0x69694, 0x69694, 0x69694, 0x69694, 0x69694, 0x69694, 0x78D, | 0x0, 0x7A7A, 0x7A7A, 0x2E0, 0x7A2E0, 0x7A7A7A, 0x7A7A4, 0x7A7A4, | |||
0xD78, 0xD6969, 0x69D, 0x46969, 0x56969, 0x694, 0x695, 0x78D, | 0x7A7A4, 0x7A7A4, 0x7A7A4, 0x7A7A4, (1U<<31) | 561, 0x2C2C, (1U<<31) | 56 | |||
0x69D, 0x694, 0x695, 0x696969, 0x2E0, 0x696969, 0x696969, 0x696969, | 1, 0x4A4A, | |||
0x696969, 0x694, 0x696969, 0x2DD, 0x6969, 0x6969, 0x6969, 0x6969, | (1U<<31) | 561, 0x3B3B, (1U<<31) | 564, 0x4A4A4A, (1U<<31) | 564, 0x3B3B3 | |||
0x0, 0x6969, 0x6969, 0x2E0, 0x692E0, 0x696969, 0x69694, 0x69694, | B, (1U<<31) | 564, 0x3B3B3B, | |||
0x69694, 0x69694, 0x69694, 0x69694, 0xDD, 0x2B2B, 0xDD, 0x4949, | (1U<<31) | 564, 0x4A4A4A, (1U<<31) | 564, 0x3B3B3B, (1U<<31) | 564, 0x3B3 | |||
0xDD, 0x3A3A, 0xDDD, 0x494949, 0xDDD, 0x3A3A3A, 0xDDD, 0x3A3A3A, | B3B, (1U<<31) | 564, 0x2C2C3B, | |||
0xDDD, 0x494949, 0xDDD, 0x3A3A3A, 0xDDD, 0x3A3A3A, 0xDDD, 0x2B2B3A, | (1U<<31) | 564, 0x3B3B3B, (1U<<31) | 564, 0x2C2C2C, (1U<<31) | 564, 0x2C2 | |||
0xDDD, 0x3A3A3A, 0xDDD, 0x2B2B2B, 0xDDD, 0x2B2B2B, 0xDDD, 0x494949, | C2C, (1U<<31) | 564, 0x4A4A4A, | |||
0xDDD, 0x3A3A3A, 0x3A69, 0x3A6A, 0x4693A, 0x46A3A, 0x40, 0x50, | (1U<<31) | 564, 0x3B3B3B, 0x3B7A, 0x3B7B, 0x47A3B, 0x47B3B, 0x40, 0x50, | |||
0x40, 0x50, 0x20, 0x4, 0x0, 0x7878, 0x7979, 0x6969, | 0x40, 0x50, 0x20, 0x4, 0x0, 0x8989, 0x8A8A, 0x7A7A, | |||
0x6A6A, 0x7878, 0x6969, 0x58585858, 0x59595959, 0x22B2B2B, 0x2494949, 0x2 | 0x7B7B, 0x8989, 0x7A7A, 0x59595959, 0x5A5A5A5A, 0x22C2C2C, 0x24A4A4A, 0x2 | |||
585858, | 595959, | |||
0x22B2B2B, 0x2494949, 0x2585858, 0x23A3A3A, 0x23A3A3A, (1U<<31) | 217, (1 | 0x22C2C2C, 0x24A4A4A, 0x2595959, 0x23B3B3B, 0x23B3B3B, (1U<<31) | 217, (1 | |||
U<<31) | 251, (1U<<31) | 161, | U<<31) | 251, (1U<<31) | 161, | |||
(1U<<31) | 183, 0x2B49, 0x2B58, 0x2B3A, 0x4958, 0x2B49, 0x2B58, 0x2B3A, | (1U<<31) | 183, 0x2C4A, 0x2C59, 0x2C3B, 0x4A59, 0x2C4A, 0x2C59, 0x2C3B, | |||
0x4958, 0x3A49, 0x3A58, 0x3A49, 0x3A58, 0x2B3A, 0x4958, 0x3A49, | 0x4A59, 0x3B4A, 0x3B59, 0x3B4A, 0x3B59, 0x2C3B, 0x4A59, 0x3B4A, | |||
0x49494949, 0x58494958, 0x58494958, 0x49494949, 0x58494958, 0x58494958, 0 | 0x4A4A4A4A, 0x594A4A59, 0x594A4A59, 0x4A4A4A4A, 0x594A4A59, 0x594A4A59, 0 | |||
x493A3A49, 0x3A3A3A3A, | x4A3B3B4A, 0x3B3B3B3B, | |||
0x493A3A49, 0x3A3A3A3A, 0x493A3A49, 0x493A3A49, 0x2B2B2B2B, 0x2B2B2B, 0x2 | 0x4A3B3B4A, 0x3B3B3B3B, 0x4A3B3B4A, 0x4A3B3B4A, 0x2C2C2C2C, 0x2C2C2C, 0x2 | |||
2B2B, 0x494949, | 2C2C, 0x4A4A4A, | |||
0x24949, 0x585858, 0x25858, 0x3A3A3A, 0x23A3A, 0x2B2B2B, 0x494949, 0x5858 | 0x24A4A, 0x595959, 0x25959, 0x3B3B3B, 0x23B3B, 0x2C2C2C, 0x4A4A4A, 0x5959 | |||
58, | 59, | |||
0x3A3A3A, 0x2B2B2B, 0x494949, 0x585858, 0x3A3A3A, 0x44, 0x2E2E, 0x43F0, | 0x3B3B3B, 0x2C2C2C, 0x4A4A4A, 0x595959, 0x3B3B3B, 0x4, 0x44, 0x2E2E, | |||
0x0, 0x40, 0x4444, (1U<<31) | 481, 0x3F0, 0x3F4, 0x3F0, 0x4, | 0x43F0, 0x0, 0x40, 0x4444, (1U<<31) | 492, 0x3F0, 0x3F4, 0x3F0, | |||
0x4, 0x4, 0x44, 0x43F, 0x7F3F, 0x3F4, 0x3F4, 0x3F4, | 0x4, 0x4, 0x4, 0x44, 0x43F, 0x7F3F, 0x3F4, 0x3F4, | |||
0x2E3F0, 0x2E3F0, 0x2E3F0, 0x2E3F0, 0x2E3F0, 0x43F4, 0x3F4, 0x3F0, | 0x3F4, 0x2E3F0, 0x2E3F0, 0x2E3F0, 0x2E3F0, 0x2E3F0, 0x43F4, 0x3F4, | |||
0x3F0, 0x43F0, 0x43F0, 0x43F4, 0x43F0, 0x3F4, 0x43F0, 0x7F3F0, | 0x3F0, 0x3F0, 0x43F0, 0x43F0, 0x43F4, 0x43F0, 0x3F4, 0x43F0, | |||
0x43F0, 0x2E3F0, 0x440, 0x43F0, 0x43F0, 0x7F3F0, 0x40, 0x43F0, | 0x7F3F0, 0x43F0, 0x2E3F0, 0x440, 0x43F0, 0x43F0, 0x7F3F0, 0x40, | |||
0x2E3F0, 0x444, 0x0, 0x3F0, 0x3F4, 0x3F4, 0x2E, 0x444, 0 | 0x43F0, 0x2E3F0, 0x444, 0x0, 0x3F0, 0x3F4, 0x3F4, 0x2E, | |||
0x444, 0 | ||||
}; | }; | |||
static const unsigned char IIT_LongEncodingTable[] = { | static const unsigned char IIT_LongEncodingTable[] = { | |||
/* 0 */ 18, 15, 0, 1, 15, 0, 15, 0, 0, | /* 0 */ 19, 15, 0, 1, 15, 0, 15, 0, 0, | |||
/* 9 */ 0, 15, 3, 15, 7, 15, 8, 4, 1, 0, | /* 9 */ 0, 15, 3, 15, 7, 15, 8, 4, 1, 0, | |||
/* 19 */ 11, 2, 11, 2, 4, 11, 2, 4, 2, 0, | /* 19 */ 12, 2, 12, 2, 4, 12, 2, 4, 2, 0, | |||
/* 29 */ 9, 4, 9, 4, 14, 2, 9, 4, 9, 4, 2, 0, | /* 29 */ 10, 4, 10, 4, 14, 2, 10, 4, 10, 4, 2, 0, | |||
/* 41 */ 9, 4, 9, 4, 14, 2, 8, 5, 9, 4, 2, 0, | /* 41 */ 10, 4, 10, 4, 14, 2, 9, 5, 10, 4, 2, 0, | |||
/* 53 */ 9, 4, 9, 4, 14, 2, 9, 5, 9, 4, 2, 0, | /* 53 */ 10, 4, 10, 4, 14, 2, 10, 5, 10, 4, 2, 0, | |||
/* 65 */ 10, 4, 10, 4, 14, 2, 10, 4, 10, 4, 2, 0, | /* 65 */ 11, 4, 11, 4, 14, 2, 11, 4, 11, 4, 2, 0, | |||
/* 77 */ 8, 5, 8, 5, 14, 2, 9, 4, 8, 5, 2, 0, | /* 77 */ 9, 5, 9, 5, 14, 2, 10, 4, 9, 5, 2, 0, | |||
/* 89 */ 8, 5, 8, 5, 14, 2, 8, 5, 8, 5, 2, 0, | /* 89 */ 9, 5, 9, 5, 14, 2, 9, 5, 9, 5, 2, 0, | |||
/* 101 */ 9, 5, 9, 5, 14, 2, 9, 4, 9, 5, 2, 0, | /* 101 */ 10, 5, 10, 5, 14, 2, 10, 4, 10, 5, 2, 0, | |||
/* 113 */ 9, 5, 9, 5, 14, 2, 9, 5, 9, 5, 2, 0, | /* 113 */ 10, 5, 10, 5, 14, 2, 10, 5, 10, 5, 2, 0, | |||
/* 125 */ 9, 6, 9, 6, 14, 2, 9, 4, 9, 6, 2, 0, | /* 125 */ 10, 7, 10, 7, 14, 2, 10, 4, 10, 7, 2, 0, | |||
/* 137 */ 9, 6, 9, 6, 14, 2, 8, 5, 9, 6, 2, 0, | /* 137 */ 10, 7, 10, 7, 14, 2, 9, 5, 10, 7, 2, 0, | |||
/* 149 */ 9, 6, 9, 6, 14, 2, 9, 5, 9, 6, 2, 0, | /* 149 */ 10, 7, 10, 7, 14, 2, 10, 5, 10, 7, 2, 0, | |||
/* 161 */ 9, 6, 9, 6, 9, 6, 9, 6, 2, 0, | /* 161 */ 10, 7, 10, 7, 10, 7, 10, 7, 2, 0, | |||
/* 171 */ 10, 6, 10, 6, 14, 2, 10, 4, 10, 6, 2, 0, | /* 171 */ 11, 7, 11, 7, 14, 2, 11, 4, 11, 7, 2, 0, | |||
/* 183 */ 10, 6, 10, 6, 10, 6, 10, 6, 2, 0, | /* 183 */ 11, 7, 11, 7, 11, 7, 11, 7, 2, 0, | |||
/* 193 */ 8, 7, 8, 7, 14, 2, 9, 4, 8, 7, 2, 0, | /* 193 */ 9, 8, 9, 8, 14, 2, 10, 4, 9, 8, 2, 0, | |||
/* 205 */ 8, 7, 8, 7, 14, 2, 8, 5, 8, 7, 2, 0, | /* 205 */ 9, 8, 9, 8, 14, 2, 9, 5, 9, 8, 2, 0, | |||
/* 217 */ 8, 7, 8, 7, 8, 7, 8, 7, 2, 0, | /* 217 */ 9, 8, 9, 8, 9, 8, 9, 8, 2, 0, | |||
/* 227 */ 9, 7, 9, 7, 14, 2, 9, 4, 9, 7, 2, 0, | /* 227 */ 10, 8, 10, 8, 14, 2, 10, 4, 10, 8, 2, 0, | |||
/* 239 */ 9, 7, 9, 7, 14, 2, 9, 5, 9, 7, 2, 0, | /* 239 */ 10, 8, 10, 8, 14, 2, 10, 5, 10, 8, 2, 0, | |||
/* 251 */ 9, 7, 9, 7, 9, 7, 9, 7, 2, 0, | /* 251 */ 10, 8, 10, 8, 10, 8, 10, 8, 2, 0, | |||
/* 261 */ 10, 2, 10, 2, 10, 2, 10, 2, 10, 2, 10, 2, 10, 2, 0, | /* 261 */ 11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 0, | |||
/* 276 */ 18, 4, 4, 14, 2, 0, | /* 276 */ 19, 4, 4, 14, 2, 0, | |||
/* 282 */ 0, 14, 17, 5, 14, 2, 0, | /* 282 */ 0, 14, 18, 5, 14, 2, 0, | |||
/* 289 */ 15, 2, 22, 2, 0, | /* 289 */ 0, 16, 16, 14, 2, 0, | |||
/* 294 */ 15, 2, 22, 2, 22, 2, 0, | /* 295 */ 16, 16, 16, 2, 0, | |||
/* 301 */ 15, 2, 15, 2, 23, 2, 23, 2, 0, | /* 300 */ 15, 2, 23, 2, 0, | |||
/* 310 */ 15, 0, 15, 0, 14, 2, 14, 2, 4, 0, | /* 305 */ 15, 2, 23, 2, 23, 2, 0, | |||
/* 320 */ 15, 3, 15, 3, 14, 2, 14, 2, 4, 0, | /* 312 */ 15, 2, 15, 2, 24, 2, 24, 2, 0, | |||
/* 330 */ 20, 15, 2, 15, 2, 15, 2, 15, 2, 14, 2, 4, 0, | /* 321 */ 15, 0, 15, 0, 14, 2, 14, 2, 4, 0, | |||
/* 343 */ 19, 15, 2, 15, 2, 15, 2, 14, 2, 4, 0, | /* 331 */ 15, 3, 15, 3, 14, 2, 14, 2, 4, 0, | |||
/* 354 */ 18, 15, 2, 15, 2, 14, 2, 4, 0, | /* 341 */ 21, 15, 2, 15, 2, 15, 2, 15, 2, 14, 2, 4, 0, | |||
/* 363 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 4, 0, | /* 354 */ 20, 15, 2, 15, 2, 15, 2, 14, 2, 4, 0, | |||
/* 374 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 15, 2, 4, 0, | /* 365 */ 19, 15, 2, 15, 2, 14, 2, 4, 0, | |||
/* 387 */ 18, 3, 4, 0, | /* 374 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 4, 0, | |||
/* 391 */ 0, 14, 2, 15, 2, 15, 2, 4, 4, 0, | /* 385 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 15, 2, 4, 0, | |||
/* 401 */ 18, 15, 2, 15, 2, 14, 2, 15, 2, 15, 2, 4, 4, 0, | /* 398 */ 19, 3, 4, 0, | |||
/* 415 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 4, 4, 0, | /* 402 */ 0, 14, 2, 15, 2, 15, 2, 4, 4, 0, | |||
/* 427 */ 19, 15, 2, 15, 2, 15, 2, 14, 2, 15, 2, 15, 2, 15, 2, 4, 4, 0, | /* 412 */ 19, 15, 2, 15, 2, 14, 2, 15, 2, 15, 2, 4, 4, 0, | |||
/* 445 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 15, 2, 4, 4, 0, | /* 426 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 4, 4, 0, | |||
/* 459 */ 20, 15, 2, 15, 2, 15, 2, 15, 2, 14, 2, 15, 2, 15, 2, 15, 2, 15, | /* 438 */ 20, 15, 2, 15, 2, 15, 2, 14, 2, 15, 2, 15, 2, 15, 2, 4, 4, 0, | |||
2, 4, 4, 0, | /* 456 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 15, 2, 4, 4, 0, | |||
/* 481 */ 18, 4, 4, 4, 4, 4, 0, | /* 470 */ 21, 15, 2, 15, 2, 15, 2, 15, 2, 14, 2, 15, 2, 15, 2, 15, 2, 15, | |||
/* 488 */ 18, 4, 4, 0, | 2, 4, 4, 0, | |||
/* 492 */ 18, 5, 4, 0, | /* 492 */ 19, 4, 4, 4, 4, 4, 0, | |||
/* 496 */ 0, 16, 5, 16, 0, | /* 499 */ 16, 16, 4, 4, 0, | |||
/* 501 */ 0, 16, 16, 0, | /* 504 */ 19, 4, 4, 0, | |||
/* 508 */ 19, 5, 4, 0, | ||||
/* 512 */ 4, 16, 4, 0, | ||||
/* 516 */ 16, 16, 4, 0, | ||||
/* 520 */ 16, 10, 7, 0, | ||||
/* 524 */ 9, 8, 9, 8, 9, 8, 9, 8, 0, | ||||
/* 533 */ 16, 9, 8, 0, | ||||
/* 537 */ 10, 8, 10, 8, 10, 8, 10, 8, 0, | ||||
/* 546 */ 4, 16, 0, | ||||
/* 549 */ 10, 7, 10, 7, 16, 0, | ||||
/* 555 */ 9, 8, 16, 0, | ||||
/* 559 */ 0, 14, 16, 16, 0, | ||||
/* 564 */ 16, 16, 16, 0, | ||||
/* 568 */ 0, 17, 5, 17, 0, | ||||
/* 573 */ 0, 17, 17, 0, | ||||
255 | 255 | |||
}; | }; | |||
#endif | #endif | |||
// Add parameter attributes that are not common to all intrinsics. | // Add parameter attributes that are not common to all intrinsics. | |||
#ifdef GET_INTRINSIC_ATTRIBUTES | #ifdef GET_INTRINSIC_ATTRIBUTES | |||
AttrListPtr Intrinsic::getAttributes(LLVMContext &C, ID id) { | AttributeSet Intrinsic::getAttributes(LLVMContext &C, ID id) { | |||
static const uint8_t IntrinsicsToAttributesMap[] = { | static const uint8_t IntrinsicsToAttributesMap[] = { | |||
1, // llvm.adjust.trampoline | 1, // llvm.adjust.trampoline | |||
2, // llvm.annotation | 2, // llvm.annotation | |||
2, // llvm.arm.cdp | 2, // llvm.arm.cdp | |||
2, // llvm.arm.cdp2 | 2, // llvm.arm.cdp2 | |||
3, // llvm.arm.get.fpscr | 3, // llvm.arm.get.fpscr | |||
1, // llvm.arm.ldrexd | 1, // llvm.arm.ldrexd | |||
2, // llvm.arm.mcr | 2, // llvm.arm.mcr | |||
2, // llvm.arm.mcr2 | 2, // llvm.arm.mcr2 | |||
2, // llvm.arm.mcrr | 2, // llvm.arm.mcrr | |||
skipping to change at line 23020 | skipping to change at line 22511 | |||
3, // llvm.arm.qadd | 3, // llvm.arm.qadd | |||
3, // llvm.arm.qsub | 3, // llvm.arm.qsub | |||
2, // llvm.arm.set.fpscr | 2, // llvm.arm.set.fpscr | |||
3, // llvm.arm.ssat | 3, // llvm.arm.ssat | |||
2, // llvm.arm.strexd | 2, // llvm.arm.strexd | |||
3, // llvm.arm.thread.pointer | 3, // llvm.arm.thread.pointer | |||
3, // llvm.arm.usat | 3, // llvm.arm.usat | |||
3, // llvm.arm.vcvtr | 3, // llvm.arm.vcvtr | |||
3, // llvm.arm.vcvtru | 3, // llvm.arm.vcvtru | |||
3, // llvm.bswap | 3, // llvm.bswap | |||
1, // llvm.ceil | ||||
3, // llvm.convert.from.fp16 | 3, // llvm.convert.from.fp16 | |||
3, // llvm.convert.to.fp16 | 3, // llvm.convert.to.fp16 | |||
2, // llvm.convertff | 2, // llvm.convertff | |||
2, // llvm.convertfsi | 2, // llvm.convertfsi | |||
2, // llvm.convertfui | 2, // llvm.convertfui | |||
2, // llvm.convertsif | 2, // llvm.convertsif | |||
2, // llvm.convertss | 2, // llvm.convertss | |||
2, // llvm.convertsu | 2, // llvm.convertsu | |||
2, // llvm.convertuif | 2, // llvm.convertuif | |||
2, // llvm.convertus | 2, // llvm.convertus | |||
skipping to change at line 24062 | skipping to change at line 23554 | |||
3, // llvm.mips.subqh.r.ph | 3, // llvm.mips.subqh.r.ph | |||
3, // llvm.mips.subqh.r.w | 3, // llvm.mips.subqh.r.w | |||
3, // llvm.mips.subqh.w | 3, // llvm.mips.subqh.w | |||
2, // llvm.mips.subu.ph | 2, // llvm.mips.subu.ph | |||
2, // llvm.mips.subu.qb | 2, // llvm.mips.subu.qb | |||
2, // llvm.mips.subu.s.ph | 2, // llvm.mips.subu.s.ph | |||
2, // llvm.mips.subu.s.qb | 2, // llvm.mips.subu.s.qb | |||
3, // llvm.mips.subuh.qb | 3, // llvm.mips.subuh.qb | |||
3, // llvm.mips.subuh.r.qb | 3, // llvm.mips.subuh.r.qb | |||
2, // llvm.mips.wrdsp | 2, // llvm.mips.wrdsp | |||
1, // llvm.nearbyint | ||||
3, // llvm.nvvm.abs.i | 3, // llvm.nvvm.abs.i | |||
3, // llvm.nvvm.abs.ll | 3, // llvm.nvvm.abs.ll | |||
3, // llvm.nvvm.add.rm.d | 3, // llvm.nvvm.add.rm.d | |||
3, // llvm.nvvm.add.rm.f | 3, // llvm.nvvm.add.rm.f | |||
3, // llvm.nvvm.add.rm.ftz.f | 3, // llvm.nvvm.add.rm.ftz.f | |||
3, // llvm.nvvm.add.rn.d | 3, // llvm.nvvm.add.rn.d | |||
3, // llvm.nvvm.add.rn.f | 3, // llvm.nvvm.add.rn.f | |||
3, // llvm.nvvm.add.rn.ftz.f | 3, // llvm.nvvm.add.rn.ftz.f | |||
3, // llvm.nvvm.add.rp.d | 3, // llvm.nvvm.add.rp.d | |||
3, // llvm.nvvm.add.rp.f | 3, // llvm.nvvm.add.rp.f | |||
skipping to change at line 24208 | skipping to change at line 23701 | |||
3, // llvm.nvvm.fmin.ftz.f | 3, // llvm.nvvm.fmin.ftz.f | |||
3, // llvm.nvvm.h2f | 3, // llvm.nvvm.h2f | |||
3, // llvm.nvvm.i2d.rm | 3, // llvm.nvvm.i2d.rm | |||
3, // llvm.nvvm.i2d.rn | 3, // llvm.nvvm.i2d.rn | |||
3, // llvm.nvvm.i2d.rp | 3, // llvm.nvvm.i2d.rp | |||
3, // llvm.nvvm.i2d.rz | 3, // llvm.nvvm.i2d.rz | |||
3, // llvm.nvvm.i2f.rm | 3, // llvm.nvvm.i2f.rm | |||
3, // llvm.nvvm.i2f.rn | 3, // llvm.nvvm.i2f.rn | |||
3, // llvm.nvvm.i2f.rp | 3, // llvm.nvvm.i2f.rp | |||
3, // llvm.nvvm.i2f.rz | 3, // llvm.nvvm.i2f.rz | |||
10, // llvm.nvvm.ldg.global.f | ||||
10, // llvm.nvvm.ldg.global.i | ||||
10, // llvm.nvvm.ldg.global.p | ||||
10, // llvm.nvvm.ldu.global.f | 10, // llvm.nvvm.ldu.global.f | |||
10, // llvm.nvvm.ldu.global.i | 10, // llvm.nvvm.ldu.global.i | |||
10, // llvm.nvvm.ldu.global.p | 10, // llvm.nvvm.ldu.global.p | |||
3, // llvm.nvvm.lg2.approx.d | 3, // llvm.nvvm.lg2.approx.d | |||
3, // llvm.nvvm.lg2.approx.f | 3, // llvm.nvvm.lg2.approx.f | |||
3, // llvm.nvvm.lg2.approx.ftz.f | 3, // llvm.nvvm.lg2.approx.ftz.f | |||
3, // llvm.nvvm.ll2d.rm | 3, // llvm.nvvm.ll2d.rm | |||
3, // llvm.nvvm.ll2d.rn | 3, // llvm.nvvm.ll2d.rn | |||
3, // llvm.nvvm.ll2d.rp | 3, // llvm.nvvm.ll2d.rp | |||
3, // llvm.nvvm.ll2d.rz | 3, // llvm.nvvm.ll2d.rz | |||
skipping to change at line 24262 | skipping to change at line 23758 | |||
3, // llvm.nvvm.mul.rz.d | 3, // llvm.nvvm.mul.rz.d | |||
3, // llvm.nvvm.mul.rz.f | 3, // llvm.nvvm.mul.rz.f | |||
3, // llvm.nvvm.mul.rz.ftz.f | 3, // llvm.nvvm.mul.rz.ftz.f | |||
3, // llvm.nvvm.mulhi.i | 3, // llvm.nvvm.mulhi.i | |||
3, // llvm.nvvm.mulhi.ll | 3, // llvm.nvvm.mulhi.ll | |||
3, // llvm.nvvm.mulhi.ui | 3, // llvm.nvvm.mulhi.ui | |||
3, // llvm.nvvm.mulhi.ull | 3, // llvm.nvvm.mulhi.ull | |||
3, // llvm.nvvm.popc.i | 3, // llvm.nvvm.popc.i | |||
3, // llvm.nvvm.popc.ll | 3, // llvm.nvvm.popc.ll | |||
3, // llvm.nvvm.prmt | 3, // llvm.nvvm.prmt | |||
11, // llvm.nvvm.ptr.constant.to.gen | 3, // llvm.nvvm.ptr.constant.to.gen | |||
11, // llvm.nvvm.ptr.gen.to.constant | 3, // llvm.nvvm.ptr.gen.to.constant | |||
11, // llvm.nvvm.ptr.gen.to.global | 3, // llvm.nvvm.ptr.gen.to.global | |||
11, // llvm.nvvm.ptr.gen.to.local | 3, // llvm.nvvm.ptr.gen.to.local | |||
11, // llvm.nvvm.ptr.gen.to.param | 3, // llvm.nvvm.ptr.gen.to.param | |||
11, // llvm.nvvm.ptr.gen.to.shared | 3, // llvm.nvvm.ptr.gen.to.shared | |||
11, // llvm.nvvm.ptr.global.to.gen | 3, // llvm.nvvm.ptr.global.to.gen | |||
11, // llvm.nvvm.ptr.local.to.gen | 3, // llvm.nvvm.ptr.local.to.gen | |||
11, // llvm.nvvm.ptr.shared.to.gen | 3, // llvm.nvvm.ptr.shared.to.gen | |||
3, // llvm.nvvm.rcp.approx.ftz.d | 3, // llvm.nvvm.rcp.approx.ftz.d | |||
3, // llvm.nvvm.rcp.rm.d | 3, // llvm.nvvm.rcp.rm.d | |||
3, // llvm.nvvm.rcp.rm.f | 3, // llvm.nvvm.rcp.rm.f | |||
3, // llvm.nvvm.rcp.rm.ftz.f | 3, // llvm.nvvm.rcp.rm.ftz.f | |||
3, // llvm.nvvm.rcp.rn.d | 3, // llvm.nvvm.rcp.rn.d | |||
3, // llvm.nvvm.rcp.rn.f | 3, // llvm.nvvm.rcp.rn.f | |||
3, // llvm.nvvm.rcp.rn.ftz.f | 3, // llvm.nvvm.rcp.rn.ftz.f | |||
3, // llvm.nvvm.rcp.rp.d | 3, // llvm.nvvm.rcp.rp.d | |||
3, // llvm.nvvm.rcp.rp.f | 3, // llvm.nvvm.rcp.rp.f | |||
3, // llvm.nvvm.rcp.rp.ftz.f | 3, // llvm.nvvm.rcp.rp.ftz.f | |||
skipping to change at line 24312 | skipping to change at line 23808 | |||
3, // llvm.nvvm.rsqrt.approx.ftz.f | 3, // llvm.nvvm.rsqrt.approx.ftz.f | |||
3, // llvm.nvvm.sad.i | 3, // llvm.nvvm.sad.i | |||
3, // llvm.nvvm.sad.ui | 3, // llvm.nvvm.sad.ui | |||
3, // llvm.nvvm.saturate.d | 3, // llvm.nvvm.saturate.d | |||
3, // llvm.nvvm.saturate.f | 3, // llvm.nvvm.saturate.f | |||
3, // llvm.nvvm.saturate.ftz.f | 3, // llvm.nvvm.saturate.ftz.f | |||
3, // llvm.nvvm.sin.approx.f | 3, // llvm.nvvm.sin.approx.f | |||
3, // llvm.nvvm.sin.approx.ftz.f | 3, // llvm.nvvm.sin.approx.ftz.f | |||
3, // llvm.nvvm.sqrt.approx.f | 3, // llvm.nvvm.sqrt.approx.f | |||
3, // llvm.nvvm.sqrt.approx.ftz.f | 3, // llvm.nvvm.sqrt.approx.ftz.f | |||
3, // llvm.nvvm.sqrt.f | ||||
3, // llvm.nvvm.sqrt.rm.d | 3, // llvm.nvvm.sqrt.rm.d | |||
3, // llvm.nvvm.sqrt.rm.f | 3, // llvm.nvvm.sqrt.rm.f | |||
3, // llvm.nvvm.sqrt.rm.ftz.f | 3, // llvm.nvvm.sqrt.rm.ftz.f | |||
3, // llvm.nvvm.sqrt.rn.d | 3, // llvm.nvvm.sqrt.rn.d | |||
3, // llvm.nvvm.sqrt.rn.f | 3, // llvm.nvvm.sqrt.rn.f | |||
3, // llvm.nvvm.sqrt.rn.ftz.f | 3, // llvm.nvvm.sqrt.rn.ftz.f | |||
3, // llvm.nvvm.sqrt.rp.d | 3, // llvm.nvvm.sqrt.rp.d | |||
3, // llvm.nvvm.sqrt.rp.f | 3, // llvm.nvvm.sqrt.rp.f | |||
3, // llvm.nvvm.sqrt.rp.ftz.f | 3, // llvm.nvvm.sqrt.rp.ftz.f | |||
3, // llvm.nvvm.sqrt.rz.d | 3, // llvm.nvvm.sqrt.rz.d | |||
skipping to change at line 24498 | skipping to change at line 23995 | |||
3, // llvm.ppc.altivec.vupkhpx | 3, // llvm.ppc.altivec.vupkhpx | |||
3, // llvm.ppc.altivec.vupkhsb | 3, // llvm.ppc.altivec.vupkhsb | |||
3, // llvm.ppc.altivec.vupkhsh | 3, // llvm.ppc.altivec.vupkhsh | |||
3, // llvm.ppc.altivec.vupklpx | 3, // llvm.ppc.altivec.vupklpx | |||
3, // llvm.ppc.altivec.vupklsb | 3, // llvm.ppc.altivec.vupklsb | |||
3, // llvm.ppc.altivec.vupklsh | 3, // llvm.ppc.altivec.vupklsh | |||
2, // llvm.ppc.dcba | 2, // llvm.ppc.dcba | |||
2, // llvm.ppc.dcbf | 2, // llvm.ppc.dcbf | |||
2, // llvm.ppc.dcbi | 2, // llvm.ppc.dcbi | |||
2, // llvm.ppc.dcbst | 2, // llvm.ppc.dcbst | |||
2, // llvm.ppc.dcbt | 6, // llvm.ppc.dcbt | |||
2, // llvm.ppc.dcbtst | 2, // llvm.ppc.dcbtst | |||
2, // llvm.ppc.dcbz | 2, // llvm.ppc.dcbz | |||
2, // llvm.ppc.dcbzl | 2, // llvm.ppc.dcbzl | |||
2, // llvm.ppc.sync | 2, // llvm.ppc.sync | |||
6, // llvm.prefetch | 6, // llvm.prefetch | |||
2, // llvm.ptr.annotation | 2, // llvm.ptr.annotation | |||
2, // llvm.ptx.bar.sync | 2, // llvm.ptx.bar.sync | |||
3, // llvm.ptx.read.clock | 3, // llvm.ptx.read.clock | |||
3, // llvm.ptx.read.clock64 | 3, // llvm.ptx.read.clock64 | |||
3, // llvm.ptx.read.ctaid.w | 3, // llvm.ptx.read.ctaid.w | |||
skipping to change at line 24539 | skipping to change at line 24036 | |||
3, // llvm.ptx.read.pm0 | 3, // llvm.ptx.read.pm0 | |||
3, // llvm.ptx.read.pm1 | 3, // llvm.ptx.read.pm1 | |||
3, // llvm.ptx.read.pm2 | 3, // llvm.ptx.read.pm2 | |||
3, // llvm.ptx.read.pm3 | 3, // llvm.ptx.read.pm3 | |||
3, // llvm.ptx.read.smid | 3, // llvm.ptx.read.smid | |||
3, // llvm.ptx.read.tid.w | 3, // llvm.ptx.read.tid.w | |||
3, // llvm.ptx.read.tid.x | 3, // llvm.ptx.read.tid.x | |||
3, // llvm.ptx.read.tid.y | 3, // llvm.ptx.read.tid.y | |||
3, // llvm.ptx.read.tid.z | 3, // llvm.ptx.read.tid.z | |||
3, // llvm.ptx.read.warpid | 3, // llvm.ptx.read.warpid | |||
3, // llvm.r600.read.global.size.x | ||||
3, // llvm.r600.read.global.size.y | ||||
3, // llvm.r600.read.global.size.z | ||||
3, // llvm.r600.read.local.size.x | ||||
3, // llvm.r600.read.local.size.y | ||||
3, // llvm.r600.read.local.size.z | ||||
3, // llvm.r600.read.ngroups.x | ||||
3, // llvm.r600.read.ngroups.y | ||||
3, // llvm.r600.read.ngroups.z | ||||
3, // llvm.r600.read.tgid.x | ||||
3, // llvm.r600.read.tgid.y | ||||
3, // llvm.r600.read.tgid.z | ||||
3, // llvm.r600.read.tidig.x | ||||
3, // llvm.r600.read.tidig.y | ||||
3, // llvm.r600.read.tidig.z | ||||
2, // llvm.readcyclecounter | 2, // llvm.readcyclecounter | |||
3, // llvm.returnaddress | 3, // llvm.returnaddress | |||
1, // llvm.rint | ||||
3, // llvm.sadd.with.overflow | 3, // llvm.sadd.with.overflow | |||
2, // llvm.setjmp | 2, // llvm.setjmp | |||
4, // llvm.siglongjmp | 4, // llvm.siglongjmp | |||
2, // llvm.sigsetjmp | 2, // llvm.sigsetjmp | |||
1, // llvm.sin | 1, // llvm.sin | |||
3, // llvm.smul.with.overflow | 3, // llvm.smul.with.overflow | |||
3, // llvm.spu.si.a | ||||
3, // llvm.spu.si.addx | ||||
3, // llvm.spu.si.ah | ||||
3, // llvm.spu.si.ahi | ||||
3, // llvm.spu.si.ai | ||||
3, // llvm.spu.si.and | ||||
3, // llvm.spu.si.andbi | ||||
3, // llvm.spu.si.andc | ||||
3, // llvm.spu.si.andhi | ||||
3, // llvm.spu.si.andi | ||||
3, // llvm.spu.si.bg | ||||
3, // llvm.spu.si.bgx | ||||
3, // llvm.spu.si.ceq | ||||
3, // llvm.spu.si.ceqb | ||||
3, // llvm.spu.si.ceqbi | ||||
3, // llvm.spu.si.ceqh | ||||
3, // llvm.spu.si.ceqhi | ||||
3, // llvm.spu.si.ceqi | ||||
3, // llvm.spu.si.cg | ||||
3, // llvm.spu.si.cgt | ||||
3, // llvm.spu.si.cgtb | ||||
3, // llvm.spu.si.cgtbi | ||||
3, // llvm.spu.si.cgth | ||||
3, // llvm.spu.si.cgthi | ||||
3, // llvm.spu.si.cgti | ||||
3, // llvm.spu.si.cgx | ||||
3, // llvm.spu.si.clgt | ||||
3, // llvm.spu.si.clgtb | ||||
3, // llvm.spu.si.clgtbi | ||||
3, // llvm.spu.si.clgth | ||||
3, // llvm.spu.si.clgthi | ||||
3, // llvm.spu.si.clgti | ||||
3, // llvm.spu.si.dfa | ||||
3, // llvm.spu.si.dfm | ||||
3, // llvm.spu.si.dfma | ||||
3, // llvm.spu.si.dfms | ||||
3, // llvm.spu.si.dfnma | ||||
3, // llvm.spu.si.dfnms | ||||
3, // llvm.spu.si.dfs | ||||
3, // llvm.spu.si.fa | ||||
3, // llvm.spu.si.fceq | ||||
3, // llvm.spu.si.fcgt | ||||
3, // llvm.spu.si.fcmeq | ||||
3, // llvm.spu.si.fcmgt | ||||
3, // llvm.spu.si.fm | ||||
3, // llvm.spu.si.fma | ||||
3, // llvm.spu.si.fms | ||||
3, // llvm.spu.si.fnms | ||||
3, // llvm.spu.si.fs | ||||
3, // llvm.spu.si.fsmbi | ||||
3, // llvm.spu.si.mpy | ||||
3, // llvm.spu.si.mpya | ||||
3, // llvm.spu.si.mpyh | ||||
3, // llvm.spu.si.mpyhh | ||||
3, // llvm.spu.si.mpyhha | ||||
3, // llvm.spu.si.mpyhhau | ||||
3, // llvm.spu.si.mpyhhu | ||||
3, // llvm.spu.si.mpyi | ||||
3, // llvm.spu.si.mpys | ||||
3, // llvm.spu.si.mpyu | ||||
3, // llvm.spu.si.mpyui | ||||
3, // llvm.spu.si.nand | ||||
3, // llvm.spu.si.nor | ||||
3, // llvm.spu.si.or | ||||
3, // llvm.spu.si.orbi | ||||
3, // llvm.spu.si.orc | ||||
3, // llvm.spu.si.orhi | ||||
3, // llvm.spu.si.ori | ||||
3, // llvm.spu.si.sf | ||||
3, // llvm.spu.si.sfh | ||||
3, // llvm.spu.si.sfhi | ||||
3, // llvm.spu.si.sfi | ||||
3, // llvm.spu.si.sfx | ||||
3, // llvm.spu.si.shli | ||||
3, // llvm.spu.si.shlqbi | ||||
3, // llvm.spu.si.shlqbii | ||||
3, // llvm.spu.si.shlqby | ||||
3, // llvm.spu.si.shlqbyi | ||||
3, // llvm.spu.si.xor | ||||
3, // llvm.spu.si.xorbi | ||||
3, // llvm.spu.si.xorhi | ||||
3, // llvm.spu.si.xori | ||||
1, // llvm.sqrt | 1, // llvm.sqrt | |||
3, // llvm.ssub.with.overflow | 3, // llvm.ssub.with.overflow | |||
2, // llvm.stackprotector | 2, // llvm.stackprotector | |||
2, // llvm.stackrestore | 2, // llvm.stackrestore | |||
2, // llvm.stacksave | 2, // llvm.stacksave | |||
4, // llvm.trap | 4, // llvm.trap | |||
1, // llvm.trunc | ||||
3, // llvm.uadd.with.overflow | 3, // llvm.uadd.with.overflow | |||
3, // llvm.umul.with.overflow | 3, // llvm.umul.with.overflow | |||
3, // llvm.usub.with.overflow | 3, // llvm.usub.with.overflow | |||
2, // llvm.va_copy | 2, // llvm.va_copy | |||
2, // llvm.va_end | 2, // llvm.va_end | |||
2, // llvm.var.annotation | 2, // llvm.var.annotation | |||
2, // llvm.va_start | 2, // llvm.va_start | |||
3, // llvm.x86.3dnow.pavgusb | 3, // llvm.x86.3dnow.pavgusb | |||
3, // llvm.x86.3dnow.pf2id | 3, // llvm.x86.3dnow.pf2id | |||
3, // llvm.x86.3dnow.pfacc | 3, // llvm.x86.3dnow.pfacc | |||
skipping to change at line 25009 | skipping to change at line 24441 | |||
3, // llvm.x86.mmx.punpcklwd | 3, // llvm.x86.mmx.punpcklwd | |||
3, // llvm.x86.mmx.pxor | 3, // llvm.x86.mmx.pxor | |||
3, // llvm.x86.pclmulqdq | 3, // llvm.x86.pclmulqdq | |||
2, // llvm.x86.rdfsbase.32 | 2, // llvm.x86.rdfsbase.32 | |||
2, // llvm.x86.rdfsbase.64 | 2, // llvm.x86.rdfsbase.64 | |||
2, // llvm.x86.rdgsbase.32 | 2, // llvm.x86.rdgsbase.32 | |||
2, // llvm.x86.rdgsbase.64 | 2, // llvm.x86.rdgsbase.64 | |||
2, // llvm.x86.rdrand.16 | 2, // llvm.x86.rdrand.16 | |||
2, // llvm.x86.rdrand.32 | 2, // llvm.x86.rdrand.32 | |||
2, // llvm.x86.rdrand.64 | 2, // llvm.x86.rdrand.64 | |||
2, // llvm.x86.rdseed.16 | ||||
2, // llvm.x86.rdseed.32 | ||||
2, // llvm.x86.rdseed.64 | ||||
3, // llvm.x86.sse2.add.sd | 3, // llvm.x86.sse2.add.sd | |||
2, // llvm.x86.sse2.clflush | 2, // llvm.x86.sse2.clflush | |||
3, // llvm.x86.sse2.cmp.pd | 3, // llvm.x86.sse2.cmp.pd | |||
3, // llvm.x86.sse2.cmp.sd | 3, // llvm.x86.sse2.cmp.sd | |||
3, // llvm.x86.sse2.comieq.sd | 3, // llvm.x86.sse2.comieq.sd | |||
3, // llvm.x86.sse2.comige.sd | 3, // llvm.x86.sse2.comige.sd | |||
3, // llvm.x86.sse2.comigt.sd | 3, // llvm.x86.sse2.comigt.sd | |||
3, // llvm.x86.sse2.comile.sd | 3, // llvm.x86.sse2.comile.sd | |||
3, // llvm.x86.sse2.comilt.sd | 3, // llvm.x86.sse2.comilt.sd | |||
3, // llvm.x86.sse2.comineq.sd | 3, // llvm.x86.sse2.comineq.sd | |||
skipping to change at line 25330 | skipping to change at line 24765 | |||
3, // llvm.x86.xop.vprotw | 3, // llvm.x86.xop.vprotw | |||
3, // llvm.x86.xop.vprotwi | 3, // llvm.x86.xop.vprotwi | |||
3, // llvm.x86.xop.vpshab | 3, // llvm.x86.xop.vpshab | |||
3, // llvm.x86.xop.vpshad | 3, // llvm.x86.xop.vpshad | |||
3, // llvm.x86.xop.vpshaq | 3, // llvm.x86.xop.vpshaq | |||
3, // llvm.x86.xop.vpshaw | 3, // llvm.x86.xop.vpshaw | |||
3, // llvm.x86.xop.vpshlb | 3, // llvm.x86.xop.vpshlb | |||
3, // llvm.x86.xop.vpshld | 3, // llvm.x86.xop.vpshld | |||
3, // llvm.x86.xop.vpshlq | 3, // llvm.x86.xop.vpshlq | |||
3, // llvm.x86.xop.vpshlw | 3, // llvm.x86.xop.vpshlw | |||
2, // llvm.x86.xtest | ||||
3, // llvm.xcore.bitrev | 3, // llvm.xcore.bitrev | |||
2, // llvm.xcore.checkevent | 2, // llvm.xcore.checkevent | |||
6, // llvm.xcore.chkct | 6, // llvm.xcore.chkct | |||
2, // llvm.xcore.clre | 2, // llvm.xcore.clre | |||
2, // llvm.xcore.clrsr | 2, // llvm.xcore.clrsr | |||
3, // llvm.xcore.crc32 | 3, // llvm.xcore.crc32 | |||
3, // llvm.xcore.crc8 | 3, // llvm.xcore.crc8 | |||
6, // llvm.xcore.eeu | 6, // llvm.xcore.eeu | |||
6, // llvm.xcore.endin | 6, // llvm.xcore.endin | |||
6, // llvm.xcore.freer | 6, // llvm.xcore.freer | |||
skipping to change at line 25383 | skipping to change at line 24819 | |||
6, // llvm.xcore.setv | 6, // llvm.xcore.setv | |||
3, // llvm.xcore.sext | 3, // llvm.xcore.sext | |||
2, // llvm.xcore.ssync | 2, // llvm.xcore.ssync | |||
6, // llvm.xcore.syncr | 6, // llvm.xcore.syncr | |||
6, // llvm.xcore.testct | 6, // llvm.xcore.testct | |||
6, // llvm.xcore.testwct | 6, // llvm.xcore.testwct | |||
1, // llvm.xcore.waitevent | 1, // llvm.xcore.waitevent | |||
3, // llvm.xcore.zext | 3, // llvm.xcore.zext | |||
}; | }; | |||
AttributeWithIndex AWI[3]; | AttributeSet AS[3]; | |||
unsigned NumAttrs = 0; | unsigned NumAttrs = 0; | |||
if (id != 0) { | if (id != 0) { | |||
SmallVector<Attributes::AttrVal, 8> AttrVec; | SmallVector<Attribute::AttrKind, 8> AttrVec; | |||
switch(IntrinsicsToAttributesMap[id - 1]) { | switch(IntrinsicsToAttributesMap[id - 1]) { | |||
default: llvm_unreachable("Invalid attribute number"); | default: llvm_unreachable("Invalid attribute number"); | |||
case 3: | case 3: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AttrVec.push_back(Attributes::ReadNone); | AttrVec.push_back(Attribute::ReadNone); | |||
AWI[0] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[0] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 1; | NumAttrs = 1; | |||
break; | break; | |||
case 11: | case 11: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoCapture); | AttrVec.push_back(Attribute::NoCapture); | |||
AWI[0] = AttributeWithIndex::get(C, 1, AttrVec); | AS[0] = AttributeSet::get(C, 1, AttrVec); | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AttrVec.push_back(Attributes::ReadNone); | AttrVec.push_back(Attribute::ReadNone); | |||
AWI[1] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 2; | NumAttrs = 2; | |||
break; | break; | |||
case 1: | case 1: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AttrVec.push_back(Attributes::ReadOnly); | AttrVec.push_back(Attribute::ReadOnly); | |||
AWI[0] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[0] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 1; | NumAttrs = 1; | |||
break; | break; | |||
case 10: | case 10: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoCapture); | AttrVec.push_back(Attribute::NoCapture); | |||
AWI[0] = AttributeWithIndex::get(C, 1, AttrVec); | AS[0] = AttributeSet::get(C, 1, AttrVec); | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AttrVec.push_back(Attributes::ReadOnly); | AttrVec.push_back(Attribute::ReadOnly); | |||
AWI[1] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 2; | NumAttrs = 2; | |||
break; | break; | |||
case 2: | case 2: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AWI[0] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[0] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 1; | NumAttrs = 1; | |||
break; | break; | |||
case 6: | case 6: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoCapture); | AttrVec.push_back(Attribute::NoCapture); | |||
AWI[0] = AttributeWithIndex::get(C, 1, AttrVec); | AS[0] = AttributeSet::get(C, 1, AttrVec); | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AWI[1] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 2; | NumAttrs = 2; | |||
break; | break; | |||
case 9: | case 9: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoCapture); | AttrVec.push_back(Attribute::NoCapture); | |||
AWI[0] = AttributeWithIndex::get(C, 1, AttrVec); | AS[0] = AttributeSet::get(C, 1, AttrVec); | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoCapture); | AttrVec.push_back(Attribute::NoCapture); | |||
AWI[1] = AttributeWithIndex::get(C, 2, AttrVec); | AS[1] = AttributeSet::get(C, 2, AttrVec); | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AWI[2] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[2] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 3; | NumAttrs = 3; | |||
break; | break; | |||
case 8: | case 8: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoCapture); | AttrVec.push_back(Attribute::NoCapture); | |||
AWI[0] = AttributeWithIndex::get(C, 2, AttrVec); | AS[0] = AttributeSet::get(C, 2, AttrVec); | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AWI[1] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 2; | NumAttrs = 2; | |||
break; | break; | |||
case 5: | case 5: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoCapture); | AttrVec.push_back(Attribute::NoCapture); | |||
AWI[0] = AttributeWithIndex::get(C, 2, AttrVec); | AS[0] = AttributeSet::get(C, 2, AttrVec); | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoCapture); | AttrVec.push_back(Attribute::NoCapture); | |||
AWI[1] = AttributeWithIndex::get(C, 3, AttrVec); | AS[1] = AttributeSet::get(C, 3, AttrVec); | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AWI[2] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[2] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 3; | NumAttrs = 3; | |||
break; | break; | |||
case 7: | case 7: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoCapture); | AttrVec.push_back(Attribute::NoCapture); | |||
AWI[0] = AttributeWithIndex::get(C, 3, AttrVec); | AS[0] = AttributeSet::get(C, 3, AttrVec); | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AWI[1] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 2; | NumAttrs = 2; | |||
break; | break; | |||
case 4: | case 4: | |||
AttrVec.clear(); | AttrVec.clear(); | |||
AttrVec.push_back(Attributes::NoUnwind); | AttrVec.push_back(Attribute::NoUnwind); | |||
AttrVec.push_back(Attributes::NoReturn); | AttrVec.push_back(Attribute::NoReturn); | |||
AWI[0] = AttributeWithIndex::get(C, AttrListPtr::FunctionIndex, AttrV | AS[0] = AttributeSet::get(C, AttributeSet::FunctionIndex, AttrVec); | |||
ec); | ||||
NumAttrs = 1; | NumAttrs = 1; | |||
break; | break; | |||
} | } | |||
} | } | |||
return AttrListPtr::get(C, ArrayRef<AttributeWithIndex>(AWI, NumAttrs)); | return AttributeSet::get(C, ArrayRef<AttributeSet>(AS, NumAttrs)); | |||
} | } | |||
#endif // GET_INTRINSIC_ATTRIBUTES | #endif // GET_INTRINSIC_ATTRIBUTES | |||
// Determine intrinsic alias analysis mod/ref behavior. | // Determine intrinsic alias analysis mod/ref behavior. | |||
#ifdef GET_INTRINSIC_MODREF_BEHAVIOR | #ifdef GET_INTRINSIC_MODREF_BEHAVIOR | |||
assert(iid <= Intrinsic::xcore_zext && "Unknown intrinsic."); | assert(iid <= Intrinsic::xcore_zext && "Unknown intrinsic."); | |||
static const uint8_t IntrinsicModRefBehavior[] = { | static const uint8_t IntrinsicModRefBehavior[] = { | |||
/* invalid */ UnknownModRefBehavior, | /* invalid */ UnknownModRefBehavior, | |||
/* adjust_trampoline */ OnlyReadsArgumentPointees, | /* adjust_trampoline */ OnlyReadsArgumentPointees, | |||
skipping to change at line 25625 | skipping to change at line 25061 | |||
/* arm_qadd */ DoesNotAccessMemory, | /* arm_qadd */ DoesNotAccessMemory, | |||
/* arm_qsub */ DoesNotAccessMemory, | /* arm_qsub */ DoesNotAccessMemory, | |||
/* arm_set_fpscr */ UnknownModRefBehavior, | /* arm_set_fpscr */ UnknownModRefBehavior, | |||
/* arm_ssat */ DoesNotAccessMemory, | /* arm_ssat */ DoesNotAccessMemory, | |||
/* arm_strexd */ OnlyAccessesArgumentPointees, | /* arm_strexd */ OnlyAccessesArgumentPointees, | |||
/* arm_thread_pointer */ DoesNotAccessMemory, | /* arm_thread_pointer */ DoesNotAccessMemory, | |||
/* arm_usat */ DoesNotAccessMemory, | /* arm_usat */ DoesNotAccessMemory, | |||
/* arm_vcvtr */ DoesNotAccessMemory, | /* arm_vcvtr */ DoesNotAccessMemory, | |||
/* arm_vcvtru */ DoesNotAccessMemory, | /* arm_vcvtru */ DoesNotAccessMemory, | |||
/* bswap */ DoesNotAccessMemory, | /* bswap */ DoesNotAccessMemory, | |||
/* ceil */ OnlyReadsMemory, | ||||
/* convert_from_fp16 */ DoesNotAccessMemory, | /* convert_from_fp16 */ DoesNotAccessMemory, | |||
/* convert_to_fp16 */ DoesNotAccessMemory, | /* convert_to_fp16 */ DoesNotAccessMemory, | |||
/* convertff */ UnknownModRefBehavior, | /* convertff */ UnknownModRefBehavior, | |||
/* convertfsi */ UnknownModRefBehavior, | /* convertfsi */ UnknownModRefBehavior, | |||
/* convertfui */ UnknownModRefBehavior, | /* convertfui */ UnknownModRefBehavior, | |||
/* convertsif */ UnknownModRefBehavior, | /* convertsif */ UnknownModRefBehavior, | |||
/* convertss */ UnknownModRefBehavior, | /* convertss */ UnknownModRefBehavior, | |||
/* convertsu */ UnknownModRefBehavior, | /* convertsu */ UnknownModRefBehavior, | |||
/* convertuif */ UnknownModRefBehavior, | /* convertuif */ UnknownModRefBehavior, | |||
/* convertus */ UnknownModRefBehavior, | /* convertus */ UnknownModRefBehavior, | |||
skipping to change at line 26667 | skipping to change at line 26104 | |||
/* mips_subqh_r_ph */ DoesNotAccessMemory, | /* mips_subqh_r_ph */ DoesNotAccessMemory, | |||
/* mips_subqh_r_w */ DoesNotAccessMemory, | /* mips_subqh_r_w */ DoesNotAccessMemory, | |||
/* mips_subqh_w */ DoesNotAccessMemory, | /* mips_subqh_w */ DoesNotAccessMemory, | |||
/* mips_subu_ph */ UnknownModRefBehavior, | /* mips_subu_ph */ UnknownModRefBehavior, | |||
/* mips_subu_qb */ UnknownModRefBehavior, | /* mips_subu_qb */ UnknownModRefBehavior, | |||
/* mips_subu_s_ph */ UnknownModRefBehavior, | /* mips_subu_s_ph */ UnknownModRefBehavior, | |||
/* mips_subu_s_qb */ UnknownModRefBehavior, | /* mips_subu_s_qb */ UnknownModRefBehavior, | |||
/* mips_subuh_qb */ DoesNotAccessMemory, | /* mips_subuh_qb */ DoesNotAccessMemory, | |||
/* mips_subuh_r_qb */ DoesNotAccessMemory, | /* mips_subuh_r_qb */ DoesNotAccessMemory, | |||
/* mips_wrdsp */ UnknownModRefBehavior, | /* mips_wrdsp */ UnknownModRefBehavior, | |||
/* nearbyint */ OnlyReadsMemory, | ||||
/* nvvm_abs_i */ DoesNotAccessMemory, | /* nvvm_abs_i */ DoesNotAccessMemory, | |||
/* nvvm_abs_ll */ DoesNotAccessMemory, | /* nvvm_abs_ll */ DoesNotAccessMemory, | |||
/* nvvm_add_rm_d */ DoesNotAccessMemory, | /* nvvm_add_rm_d */ DoesNotAccessMemory, | |||
/* nvvm_add_rm_f */ DoesNotAccessMemory, | /* nvvm_add_rm_f */ DoesNotAccessMemory, | |||
/* nvvm_add_rm_ftz_f */ DoesNotAccessMemory, | /* nvvm_add_rm_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_add_rn_d */ DoesNotAccessMemory, | /* nvvm_add_rn_d */ DoesNotAccessMemory, | |||
/* nvvm_add_rn_f */ DoesNotAccessMemory, | /* nvvm_add_rn_f */ DoesNotAccessMemory, | |||
/* nvvm_add_rn_ftz_f */ DoesNotAccessMemory, | /* nvvm_add_rn_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_add_rp_d */ DoesNotAccessMemory, | /* nvvm_add_rp_d */ DoesNotAccessMemory, | |||
/* nvvm_add_rp_f */ DoesNotAccessMemory, | /* nvvm_add_rp_f */ DoesNotAccessMemory, | |||
skipping to change at line 26813 | skipping to change at line 26251 | |||
/* nvvm_fmin_ftz_f */ DoesNotAccessMemory, | /* nvvm_fmin_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_h2f */ DoesNotAccessMemory, | /* nvvm_h2f */ DoesNotAccessMemory, | |||
/* nvvm_i2d_rm */ DoesNotAccessMemory, | /* nvvm_i2d_rm */ DoesNotAccessMemory, | |||
/* nvvm_i2d_rn */ DoesNotAccessMemory, | /* nvvm_i2d_rn */ DoesNotAccessMemory, | |||
/* nvvm_i2d_rp */ DoesNotAccessMemory, | /* nvvm_i2d_rp */ DoesNotAccessMemory, | |||
/* nvvm_i2d_rz */ DoesNotAccessMemory, | /* nvvm_i2d_rz */ DoesNotAccessMemory, | |||
/* nvvm_i2f_rm */ DoesNotAccessMemory, | /* nvvm_i2f_rm */ DoesNotAccessMemory, | |||
/* nvvm_i2f_rn */ DoesNotAccessMemory, | /* nvvm_i2f_rn */ DoesNotAccessMemory, | |||
/* nvvm_i2f_rp */ DoesNotAccessMemory, | /* nvvm_i2f_rp */ DoesNotAccessMemory, | |||
/* nvvm_i2f_rz */ DoesNotAccessMemory, | /* nvvm_i2f_rz */ DoesNotAccessMemory, | |||
/* nvvm_ldg_global_f */ OnlyReadsMemory, | ||||
/* nvvm_ldg_global_i */ OnlyReadsMemory, | ||||
/* nvvm_ldg_global_p */ OnlyReadsMemory, | ||||
/* nvvm_ldu_global_f */ OnlyReadsMemory, | /* nvvm_ldu_global_f */ OnlyReadsMemory, | |||
/* nvvm_ldu_global_i */ OnlyReadsMemory, | /* nvvm_ldu_global_i */ OnlyReadsMemory, | |||
/* nvvm_ldu_global_p */ OnlyReadsMemory, | /* nvvm_ldu_global_p */ OnlyReadsMemory, | |||
/* nvvm_lg2_approx_d */ DoesNotAccessMemory, | /* nvvm_lg2_approx_d */ DoesNotAccessMemory, | |||
/* nvvm_lg2_approx_f */ DoesNotAccessMemory, | /* nvvm_lg2_approx_f */ DoesNotAccessMemory, | |||
/* nvvm_lg2_approx_ftz_f */ DoesNotAccessMemory, | /* nvvm_lg2_approx_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_ll2d_rm */ DoesNotAccessMemory, | /* nvvm_ll2d_rm */ DoesNotAccessMemory, | |||
/* nvvm_ll2d_rn */ DoesNotAccessMemory, | /* nvvm_ll2d_rn */ DoesNotAccessMemory, | |||
/* nvvm_ll2d_rp */ DoesNotAccessMemory, | /* nvvm_ll2d_rp */ DoesNotAccessMemory, | |||
/* nvvm_ll2d_rz */ DoesNotAccessMemory, | /* nvvm_ll2d_rz */ DoesNotAccessMemory, | |||
skipping to change at line 26917 | skipping to change at line 26358 | |||
/* nvvm_rsqrt_approx_ftz_f */ DoesNotAccessMemory, | /* nvvm_rsqrt_approx_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_sad_i */ DoesNotAccessMemory, | /* nvvm_sad_i */ DoesNotAccessMemory, | |||
/* nvvm_sad_ui */ DoesNotAccessMemory, | /* nvvm_sad_ui */ DoesNotAccessMemory, | |||
/* nvvm_saturate_d */ DoesNotAccessMemory, | /* nvvm_saturate_d */ DoesNotAccessMemory, | |||
/* nvvm_saturate_f */ DoesNotAccessMemory, | /* nvvm_saturate_f */ DoesNotAccessMemory, | |||
/* nvvm_saturate_ftz_f */ DoesNotAccessMemory, | /* nvvm_saturate_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_sin_approx_f */ DoesNotAccessMemory, | /* nvvm_sin_approx_f */ DoesNotAccessMemory, | |||
/* nvvm_sin_approx_ftz_f */ DoesNotAccessMemory, | /* nvvm_sin_approx_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_approx_f */ DoesNotAccessMemory, | /* nvvm_sqrt_approx_f */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_approx_ftz_f */ DoesNotAccessMemory, | /* nvvm_sqrt_approx_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_f */ DoesNotAccessMemory, | ||||
/* nvvm_sqrt_rm_d */ DoesNotAccessMemory, | /* nvvm_sqrt_rm_d */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_rm_f */ DoesNotAccessMemory, | /* nvvm_sqrt_rm_f */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_rm_ftz_f */ DoesNotAccessMemory, | /* nvvm_sqrt_rm_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_rn_d */ DoesNotAccessMemory, | /* nvvm_sqrt_rn_d */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_rn_f */ DoesNotAccessMemory, | /* nvvm_sqrt_rn_f */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_rn_ftz_f */ DoesNotAccessMemory, | /* nvvm_sqrt_rn_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_rp_d */ DoesNotAccessMemory, | /* nvvm_sqrt_rp_d */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_rp_f */ DoesNotAccessMemory, | /* nvvm_sqrt_rp_f */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_rp_ftz_f */ DoesNotAccessMemory, | /* nvvm_sqrt_rp_ftz_f */ DoesNotAccessMemory, | |||
/* nvvm_sqrt_rz_d */ DoesNotAccessMemory, | /* nvvm_sqrt_rz_d */ DoesNotAccessMemory, | |||
skipping to change at line 26958 | skipping to change at line 26400 | |||
/* objectsize */ DoesNotAccessMemory, | /* objectsize */ DoesNotAccessMemory, | |||
/* pcmarker */ UnknownModRefBehavior, | /* pcmarker */ UnknownModRefBehavior, | |||
/* pow */ OnlyReadsMemory, | /* pow */ OnlyReadsMemory, | |||
/* powi */ OnlyReadsMemory, | /* powi */ OnlyReadsMemory, | |||
/* ppc_altivec_dss */ UnknownModRefBehavior, | /* ppc_altivec_dss */ UnknownModRefBehavior, | |||
/* ppc_altivec_dssall */ UnknownModRefBehavior, | /* ppc_altivec_dssall */ UnknownModRefBehavior, | |||
/* ppc_altivec_dst */ UnknownModRefBehavior, | /* ppc_altivec_dst */ UnknownModRefBehavior, | |||
/* ppc_altivec_dstst */ UnknownModRefBehavior, | /* ppc_altivec_dstst */ UnknownModRefBehavior, | |||
/* ppc_altivec_dststt */ UnknownModRefBehavior, | /* ppc_altivec_dststt */ UnknownModRefBehavior, | |||
/* ppc_altivec_dstt */ UnknownModRefBehavior, | /* ppc_altivec_dstt */ UnknownModRefBehavior, | |||
/* ppc_altivec_lvebx */ OnlyReadsMemory, | /* ppc_altivec_lvebx */ OnlyReadsArgumentPointees, | |||
/* ppc_altivec_lvehx */ OnlyReadsMemory, | /* ppc_altivec_lvehx */ OnlyReadsArgumentPointees, | |||
/* ppc_altivec_lvewx */ OnlyReadsMemory, | /* ppc_altivec_lvewx */ OnlyReadsArgumentPointees, | |||
/* ppc_altivec_lvsl */ DoesNotAccessMemory, | /* ppc_altivec_lvsl */ DoesNotAccessMemory, | |||
/* ppc_altivec_lvsr */ DoesNotAccessMemory, | /* ppc_altivec_lvsr */ DoesNotAccessMemory, | |||
/* ppc_altivec_lvx */ OnlyReadsMemory, | /* ppc_altivec_lvx */ OnlyReadsArgumentPointees, | |||
/* ppc_altivec_lvxl */ OnlyReadsMemory, | /* ppc_altivec_lvxl */ OnlyReadsArgumentPointees, | |||
/* ppc_altivec_mfvscr */ OnlyReadsMemory, | /* ppc_altivec_mfvscr */ OnlyReadsMemory, | |||
/* ppc_altivec_mtvscr */ UnknownModRefBehavior, | /* ppc_altivec_mtvscr */ UnknownModRefBehavior, | |||
/* ppc_altivec_stvebx */ UnknownModRefBehavior, | /* ppc_altivec_stvebx */ OnlyAccessesArgumentPointees, | |||
/* ppc_altivec_stvehx */ UnknownModRefBehavior, | /* ppc_altivec_stvehx */ OnlyAccessesArgumentPointees, | |||
/* ppc_altivec_stvewx */ UnknownModRefBehavior, | /* ppc_altivec_stvewx */ OnlyAccessesArgumentPointees, | |||
/* ppc_altivec_stvx */ UnknownModRefBehavior, | /* ppc_altivec_stvx */ OnlyAccessesArgumentPointees, | |||
/* ppc_altivec_stvxl */ UnknownModRefBehavior, | /* ppc_altivec_stvxl */ OnlyAccessesArgumentPointees, | |||
/* ppc_altivec_vaddcuw */ DoesNotAccessMemory, | /* ppc_altivec_vaddcuw */ DoesNotAccessMemory, | |||
/* ppc_altivec_vaddsbs */ DoesNotAccessMemory, | /* ppc_altivec_vaddsbs */ DoesNotAccessMemory, | |||
/* ppc_altivec_vaddshs */ DoesNotAccessMemory, | /* ppc_altivec_vaddshs */ DoesNotAccessMemory, | |||
/* ppc_altivec_vaddsws */ DoesNotAccessMemory, | /* ppc_altivec_vaddsws */ DoesNotAccessMemory, | |||
/* ppc_altivec_vaddubs */ DoesNotAccessMemory, | /* ppc_altivec_vaddubs */ DoesNotAccessMemory, | |||
/* ppc_altivec_vadduhs */ DoesNotAccessMemory, | /* ppc_altivec_vadduhs */ DoesNotAccessMemory, | |||
/* ppc_altivec_vadduws */ DoesNotAccessMemory, | /* ppc_altivec_vadduws */ DoesNotAccessMemory, | |||
/* ppc_altivec_vavgsb */ DoesNotAccessMemory, | /* ppc_altivec_vavgsb */ DoesNotAccessMemory, | |||
/* ppc_altivec_vavgsh */ DoesNotAccessMemory, | /* ppc_altivec_vavgsh */ DoesNotAccessMemory, | |||
/* ppc_altivec_vavgsw */ DoesNotAccessMemory, | /* ppc_altivec_vavgsw */ DoesNotAccessMemory, | |||
skipping to change at line 27103 | skipping to change at line 26545 | |||
/* ppc_altivec_vupkhpx */ DoesNotAccessMemory, | /* ppc_altivec_vupkhpx */ DoesNotAccessMemory, | |||
/* ppc_altivec_vupkhsb */ DoesNotAccessMemory, | /* ppc_altivec_vupkhsb */ DoesNotAccessMemory, | |||
/* ppc_altivec_vupkhsh */ DoesNotAccessMemory, | /* ppc_altivec_vupkhsh */ DoesNotAccessMemory, | |||
/* ppc_altivec_vupklpx */ DoesNotAccessMemory, | /* ppc_altivec_vupklpx */ DoesNotAccessMemory, | |||
/* ppc_altivec_vupklsb */ DoesNotAccessMemory, | /* ppc_altivec_vupklsb */ DoesNotAccessMemory, | |||
/* ppc_altivec_vupklsh */ DoesNotAccessMemory, | /* ppc_altivec_vupklsh */ DoesNotAccessMemory, | |||
/* ppc_dcba */ UnknownModRefBehavior, | /* ppc_dcba */ UnknownModRefBehavior, | |||
/* ppc_dcbf */ UnknownModRefBehavior, | /* ppc_dcbf */ UnknownModRefBehavior, | |||
/* ppc_dcbi */ UnknownModRefBehavior, | /* ppc_dcbi */ UnknownModRefBehavior, | |||
/* ppc_dcbst */ UnknownModRefBehavior, | /* ppc_dcbst */ UnknownModRefBehavior, | |||
/* ppc_dcbt */ UnknownModRefBehavior, | /* ppc_dcbt */ OnlyAccessesArgumentPointees, | |||
/* ppc_dcbtst */ UnknownModRefBehavior, | /* ppc_dcbtst */ UnknownModRefBehavior, | |||
/* ppc_dcbz */ UnknownModRefBehavior, | /* ppc_dcbz */ UnknownModRefBehavior, | |||
/* ppc_dcbzl */ UnknownModRefBehavior, | /* ppc_dcbzl */ UnknownModRefBehavior, | |||
/* ppc_sync */ UnknownModRefBehavior, | /* ppc_sync */ UnknownModRefBehavior, | |||
/* prefetch */ OnlyAccessesArgumentPointees, | /* prefetch */ OnlyAccessesArgumentPointees, | |||
/* ptr_annotation */ UnknownModRefBehavior, | /* ptr_annotation */ UnknownModRefBehavior, | |||
/* ptx_bar_sync */ UnknownModRefBehavior, | /* ptx_bar_sync */ UnknownModRefBehavior, | |||
/* ptx_read_clock */ DoesNotAccessMemory, | /* ptx_read_clock */ DoesNotAccessMemory, | |||
/* ptx_read_clock64 */ DoesNotAccessMemory, | /* ptx_read_clock64 */ DoesNotAccessMemory, | |||
/* ptx_read_ctaid_w */ DoesNotAccessMemory, | /* ptx_read_ctaid_w */ DoesNotAccessMemory, | |||
skipping to change at line 27144 | skipping to change at line 26586 | |||
/* ptx_read_pm0 */ DoesNotAccessMemory, | /* ptx_read_pm0 */ DoesNotAccessMemory, | |||
/* ptx_read_pm1 */ DoesNotAccessMemory, | /* ptx_read_pm1 */ DoesNotAccessMemory, | |||
/* ptx_read_pm2 */ DoesNotAccessMemory, | /* ptx_read_pm2 */ DoesNotAccessMemory, | |||
/* ptx_read_pm3 */ DoesNotAccessMemory, | /* ptx_read_pm3 */ DoesNotAccessMemory, | |||
/* ptx_read_smid */ DoesNotAccessMemory, | /* ptx_read_smid */ DoesNotAccessMemory, | |||
/* ptx_read_tid_w */ DoesNotAccessMemory, | /* ptx_read_tid_w */ DoesNotAccessMemory, | |||
/* ptx_read_tid_x */ DoesNotAccessMemory, | /* ptx_read_tid_x */ DoesNotAccessMemory, | |||
/* ptx_read_tid_y */ DoesNotAccessMemory, | /* ptx_read_tid_y */ DoesNotAccessMemory, | |||
/* ptx_read_tid_z */ DoesNotAccessMemory, | /* ptx_read_tid_z */ DoesNotAccessMemory, | |||
/* ptx_read_warpid */ DoesNotAccessMemory, | /* ptx_read_warpid */ DoesNotAccessMemory, | |||
/* r600_read_global_size_x */ DoesNotAccessMemory, | ||||
/* r600_read_global_size_y */ DoesNotAccessMemory, | ||||
/* r600_read_global_size_z */ DoesNotAccessMemory, | ||||
/* r600_read_local_size_x */ DoesNotAccessMemory, | ||||
/* r600_read_local_size_y */ DoesNotAccessMemory, | ||||
/* r600_read_local_size_z */ DoesNotAccessMemory, | ||||
/* r600_read_ngroups_x */ DoesNotAccessMemory, | ||||
/* r600_read_ngroups_y */ DoesNotAccessMemory, | ||||
/* r600_read_ngroups_z */ DoesNotAccessMemory, | ||||
/* r600_read_tgid_x */ DoesNotAccessMemory, | ||||
/* r600_read_tgid_y */ DoesNotAccessMemory, | ||||
/* r600_read_tgid_z */ DoesNotAccessMemory, | ||||
/* r600_read_tidig_x */ DoesNotAccessMemory, | ||||
/* r600_read_tidig_y */ DoesNotAccessMemory, | ||||
/* r600_read_tidig_z */ DoesNotAccessMemory, | ||||
/* readcyclecounter */ UnknownModRefBehavior, | /* readcyclecounter */ UnknownModRefBehavior, | |||
/* returnaddress */ DoesNotAccessMemory, | /* returnaddress */ DoesNotAccessMemory, | |||
/* rint */ OnlyReadsMemory, | ||||
/* sadd_with_overflow */ DoesNotAccessMemory, | /* sadd_with_overflow */ DoesNotAccessMemory, | |||
/* setjmp */ UnknownModRefBehavior, | /* setjmp */ UnknownModRefBehavior, | |||
/* siglongjmp */ UnknownModRefBehavior, | /* siglongjmp */ UnknownModRefBehavior, | |||
/* sigsetjmp */ UnknownModRefBehavior, | /* sigsetjmp */ UnknownModRefBehavior, | |||
/* sin */ OnlyReadsMemory, | /* sin */ OnlyReadsMemory, | |||
/* smul_with_overflow */ DoesNotAccessMemory, | /* smul_with_overflow */ DoesNotAccessMemory, | |||
/* spu_si_a */ DoesNotAccessMemory, | ||||
/* spu_si_addx */ DoesNotAccessMemory, | ||||
/* spu_si_ah */ DoesNotAccessMemory, | ||||
/* spu_si_ahi */ DoesNotAccessMemory, | ||||
/* spu_si_ai */ DoesNotAccessMemory, | ||||
/* spu_si_and */ DoesNotAccessMemory, | ||||
/* spu_si_andbi */ DoesNotAccessMemory, | ||||
/* spu_si_andc */ DoesNotAccessMemory, | ||||
/* spu_si_andhi */ DoesNotAccessMemory, | ||||
/* spu_si_andi */ DoesNotAccessMemory, | ||||
/* spu_si_bg */ DoesNotAccessMemory, | ||||
/* spu_si_bgx */ DoesNotAccessMemory, | ||||
/* spu_si_ceq */ DoesNotAccessMemory, | ||||
/* spu_si_ceqb */ DoesNotAccessMemory, | ||||
/* spu_si_ceqbi */ DoesNotAccessMemory, | ||||
/* spu_si_ceqh */ DoesNotAccessMemory, | ||||
/* spu_si_ceqhi */ DoesNotAccessMemory, | ||||
/* spu_si_ceqi */ DoesNotAccessMemory, | ||||
/* spu_si_cg */ DoesNotAccessMemory, | ||||
/* spu_si_cgt */ DoesNotAccessMemory, | ||||
/* spu_si_cgtb */ DoesNotAccessMemory, | ||||
/* spu_si_cgtbi */ DoesNotAccessMemory, | ||||
/* spu_si_cgth */ DoesNotAccessMemory, | ||||
/* spu_si_cgthi */ DoesNotAccessMemory, | ||||
/* spu_si_cgti */ DoesNotAccessMemory, | ||||
/* spu_si_cgx */ DoesNotAccessMemory, | ||||
/* spu_si_clgt */ DoesNotAccessMemory, | ||||
/* spu_si_clgtb */ DoesNotAccessMemory, | ||||
/* spu_si_clgtbi */ DoesNotAccessMemory, | ||||
/* spu_si_clgth */ DoesNotAccessMemory, | ||||
/* spu_si_clgthi */ DoesNotAccessMemory, | ||||
/* spu_si_clgti */ DoesNotAccessMemory, | ||||
/* spu_si_dfa */ DoesNotAccessMemory, | ||||
/* spu_si_dfm */ DoesNotAccessMemory, | ||||
/* spu_si_dfma */ DoesNotAccessMemory, | ||||
/* spu_si_dfms */ DoesNotAccessMemory, | ||||
/* spu_si_dfnma */ DoesNotAccessMemory, | ||||
/* spu_si_dfnms */ DoesNotAccessMemory, | ||||
/* spu_si_dfs */ DoesNotAccessMemory, | ||||
/* spu_si_fa */ DoesNotAccessMemory, | ||||
/* spu_si_fceq */ DoesNotAccessMemory, | ||||
/* spu_si_fcgt */ DoesNotAccessMemory, | ||||
/* spu_si_fcmeq */ DoesNotAccessMemory, | ||||
/* spu_si_fcmgt */ DoesNotAccessMemory, | ||||
/* spu_si_fm */ DoesNotAccessMemory, | ||||
/* spu_si_fma */ DoesNotAccessMemory, | ||||
/* spu_si_fms */ DoesNotAccessMemory, | ||||
/* spu_si_fnms */ DoesNotAccessMemory, | ||||
/* spu_si_fs */ DoesNotAccessMemory, | ||||
/* spu_si_fsmbi */ DoesNotAccessMemory, | ||||
/* spu_si_mpy */ DoesNotAccessMemory, | ||||
/* spu_si_mpya */ DoesNotAccessMemory, | ||||
/* spu_si_mpyh */ DoesNotAccessMemory, | ||||
/* spu_si_mpyhh */ DoesNotAccessMemory, | ||||
/* spu_si_mpyhha */ DoesNotAccessMemory, | ||||
/* spu_si_mpyhhau */ DoesNotAccessMemory, | ||||
/* spu_si_mpyhhu */ DoesNotAccessMemory, | ||||
/* spu_si_mpyi */ DoesNotAccessMemory, | ||||
/* spu_si_mpys */ DoesNotAccessMemory, | ||||
/* spu_si_mpyu */ DoesNotAccessMemory, | ||||
/* spu_si_mpyui */ DoesNotAccessMemory, | ||||
/* spu_si_nand */ DoesNotAccessMemory, | ||||
/* spu_si_nor */ DoesNotAccessMemory, | ||||
/* spu_si_or */ DoesNotAccessMemory, | ||||
/* spu_si_orbi */ DoesNotAccessMemory, | ||||
/* spu_si_orc */ DoesNotAccessMemory, | ||||
/* spu_si_orhi */ DoesNotAccessMemory, | ||||
/* spu_si_ori */ DoesNotAccessMemory, | ||||
/* spu_si_sf */ DoesNotAccessMemory, | ||||
/* spu_si_sfh */ DoesNotAccessMemory, | ||||
/* spu_si_sfhi */ DoesNotAccessMemory, | ||||
/* spu_si_sfi */ DoesNotAccessMemory, | ||||
/* spu_si_sfx */ DoesNotAccessMemory, | ||||
/* spu_si_shli */ DoesNotAccessMemory, | ||||
/* spu_si_shlqbi */ DoesNotAccessMemory, | ||||
/* spu_si_shlqbii */ DoesNotAccessMemory, | ||||
/* spu_si_shlqby */ DoesNotAccessMemory, | ||||
/* spu_si_shlqbyi */ DoesNotAccessMemory, | ||||
/* spu_si_xor */ DoesNotAccessMemory, | ||||
/* spu_si_xorbi */ DoesNotAccessMemory, | ||||
/* spu_si_xorhi */ DoesNotAccessMemory, | ||||
/* spu_si_xori */ DoesNotAccessMemory, | ||||
/* sqrt */ OnlyReadsMemory, | /* sqrt */ OnlyReadsMemory, | |||
/* ssub_with_overflow */ DoesNotAccessMemory, | /* ssub_with_overflow */ DoesNotAccessMemory, | |||
/* stackprotector */ UnknownModRefBehavior, | /* stackprotector */ UnknownModRefBehavior, | |||
/* stackrestore */ UnknownModRefBehavior, | /* stackrestore */ UnknownModRefBehavior, | |||
/* stacksave */ UnknownModRefBehavior, | /* stacksave */ UnknownModRefBehavior, | |||
/* trap */ UnknownModRefBehavior, | /* trap */ UnknownModRefBehavior, | |||
/* trunc */ OnlyReadsMemory, | ||||
/* uadd_with_overflow */ DoesNotAccessMemory, | /* uadd_with_overflow */ DoesNotAccessMemory, | |||
/* umul_with_overflow */ DoesNotAccessMemory, | /* umul_with_overflow */ DoesNotAccessMemory, | |||
/* usub_with_overflow */ DoesNotAccessMemory, | /* usub_with_overflow */ DoesNotAccessMemory, | |||
/* vacopy */ UnknownModRefBehavior, | /* vacopy */ UnknownModRefBehavior, | |||
/* vaend */ UnknownModRefBehavior, | /* vaend */ UnknownModRefBehavior, | |||
/* var_annotation */ UnknownModRefBehavior, | /* var_annotation */ UnknownModRefBehavior, | |||
/* vastart */ UnknownModRefBehavior, | /* vastart */ UnknownModRefBehavior, | |||
/* x86_3dnow_pavgusb */ DoesNotAccessMemory, | /* x86_3dnow_pavgusb */ DoesNotAccessMemory, | |||
/* x86_3dnow_pf2id */ DoesNotAccessMemory, | /* x86_3dnow_pf2id */ DoesNotAccessMemory, | |||
/* x86_3dnow_pfacc */ DoesNotAccessMemory, | /* x86_3dnow_pfacc */ DoesNotAccessMemory, | |||
skipping to change at line 27614 | skipping to change at line 26991 | |||
/* x86_mmx_punpcklwd */ DoesNotAccessMemory, | /* x86_mmx_punpcklwd */ DoesNotAccessMemory, | |||
/* x86_mmx_pxor */ DoesNotAccessMemory, | /* x86_mmx_pxor */ DoesNotAccessMemory, | |||
/* x86_pclmulqdq */ DoesNotAccessMemory, | /* x86_pclmulqdq */ DoesNotAccessMemory, | |||
/* x86_rdfsbase_32 */ UnknownModRefBehavior, | /* x86_rdfsbase_32 */ UnknownModRefBehavior, | |||
/* x86_rdfsbase_64 */ UnknownModRefBehavior, | /* x86_rdfsbase_64 */ UnknownModRefBehavior, | |||
/* x86_rdgsbase_32 */ UnknownModRefBehavior, | /* x86_rdgsbase_32 */ UnknownModRefBehavior, | |||
/* x86_rdgsbase_64 */ UnknownModRefBehavior, | /* x86_rdgsbase_64 */ UnknownModRefBehavior, | |||
/* x86_rdrand_16 */ UnknownModRefBehavior, | /* x86_rdrand_16 */ UnknownModRefBehavior, | |||
/* x86_rdrand_32 */ UnknownModRefBehavior, | /* x86_rdrand_32 */ UnknownModRefBehavior, | |||
/* x86_rdrand_64 */ UnknownModRefBehavior, | /* x86_rdrand_64 */ UnknownModRefBehavior, | |||
/* x86_rdseed_16 */ UnknownModRefBehavior, | ||||
/* x86_rdseed_32 */ UnknownModRefBehavior, | ||||
/* x86_rdseed_64 */ UnknownModRefBehavior, | ||||
/* x86_sse2_add_sd */ DoesNotAccessMemory, | /* x86_sse2_add_sd */ DoesNotAccessMemory, | |||
/* x86_sse2_clflush */ UnknownModRefBehavior, | /* x86_sse2_clflush */ UnknownModRefBehavior, | |||
/* x86_sse2_cmp_pd */ DoesNotAccessMemory, | /* x86_sse2_cmp_pd */ DoesNotAccessMemory, | |||
/* x86_sse2_cmp_sd */ DoesNotAccessMemory, | /* x86_sse2_cmp_sd */ DoesNotAccessMemory, | |||
/* x86_sse2_comieq_sd */ DoesNotAccessMemory, | /* x86_sse2_comieq_sd */ DoesNotAccessMemory, | |||
/* x86_sse2_comige_sd */ DoesNotAccessMemory, | /* x86_sse2_comige_sd */ DoesNotAccessMemory, | |||
/* x86_sse2_comigt_sd */ DoesNotAccessMemory, | /* x86_sse2_comigt_sd */ DoesNotAccessMemory, | |||
/* x86_sse2_comile_sd */ DoesNotAccessMemory, | /* x86_sse2_comile_sd */ DoesNotAccessMemory, | |||
/* x86_sse2_comilt_sd */ DoesNotAccessMemory, | /* x86_sse2_comilt_sd */ DoesNotAccessMemory, | |||
/* x86_sse2_comineq_sd */ DoesNotAccessMemory, | /* x86_sse2_comineq_sd */ DoesNotAccessMemory, | |||
skipping to change at line 27935 | skipping to change at line 27315 | |||
/* x86_xop_vprotw */ DoesNotAccessMemory, | /* x86_xop_vprotw */ DoesNotAccessMemory, | |||
/* x86_xop_vprotwi */ DoesNotAccessMemory, | /* x86_xop_vprotwi */ DoesNotAccessMemory, | |||
/* x86_xop_vpshab */ DoesNotAccessMemory, | /* x86_xop_vpshab */ DoesNotAccessMemory, | |||
/* x86_xop_vpshad */ DoesNotAccessMemory, | /* x86_xop_vpshad */ DoesNotAccessMemory, | |||
/* x86_xop_vpshaq */ DoesNotAccessMemory, | /* x86_xop_vpshaq */ DoesNotAccessMemory, | |||
/* x86_xop_vpshaw */ DoesNotAccessMemory, | /* x86_xop_vpshaw */ DoesNotAccessMemory, | |||
/* x86_xop_vpshlb */ DoesNotAccessMemory, | /* x86_xop_vpshlb */ DoesNotAccessMemory, | |||
/* x86_xop_vpshld */ DoesNotAccessMemory, | /* x86_xop_vpshld */ DoesNotAccessMemory, | |||
/* x86_xop_vpshlq */ DoesNotAccessMemory, | /* x86_xop_vpshlq */ DoesNotAccessMemory, | |||
/* x86_xop_vpshlw */ DoesNotAccessMemory, | /* x86_xop_vpshlw */ DoesNotAccessMemory, | |||
/* x86_xtest */ UnknownModRefBehavior, | ||||
/* xcore_bitrev */ DoesNotAccessMemory, | /* xcore_bitrev */ DoesNotAccessMemory, | |||
/* xcore_checkevent */ UnknownModRefBehavior, | /* xcore_checkevent */ UnknownModRefBehavior, | |||
/* xcore_chkct */ UnknownModRefBehavior, | /* xcore_chkct */ UnknownModRefBehavior, | |||
/* xcore_clre */ UnknownModRefBehavior, | /* xcore_clre */ UnknownModRefBehavior, | |||
/* xcore_clrsr */ UnknownModRefBehavior, | /* xcore_clrsr */ UnknownModRefBehavior, | |||
/* xcore_crc32 */ DoesNotAccessMemory, | /* xcore_crc32 */ DoesNotAccessMemory, | |||
/* xcore_crc8 */ DoesNotAccessMemory, | /* xcore_crc8 */ DoesNotAccessMemory, | |||
/* xcore_eeu */ UnknownModRefBehavior, | /* xcore_eeu */ UnknownModRefBehavior, | |||
/* xcore_endin */ UnknownModRefBehavior, | /* xcore_endin */ UnknownModRefBehavior, | |||
/* xcore_freer */ UnknownModRefBehavior, | /* xcore_freer */ UnknownModRefBehavior, | |||
skipping to change at line 28054 | skipping to change at line 27435 | |||
break; | break; | |||
return Intrinsic::nvvm_min_i; // "__nvvm_min_i" | return Intrinsic::nvvm_min_i; // "__nvvm_min_i" | |||
} | } | |||
break; | break; | |||
case 's': // 1 string to match. | case 's': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+8, "ad_i", 4)) | if (memcmp(BuiltinName.data()+8, "ad_i", 4)) | |||
break; | break; | |||
return Intrinsic::nvvm_sad_i; // "__nvvm_sad_i" | return Intrinsic::nvvm_sad_i; // "__nvvm_sad_i" | |||
} | } | |||
break; | break; | |||
case 13: // 42 strings to match. | case 13: // 43 strings to match. | |||
if (memcmp(BuiltinName.data()+0, "__", 2)) | if (memcmp(BuiltinName.data()+0, "__", 2)) | |||
break; | break; | |||
switch (BuiltinName[2]) { | switch (BuiltinName[2]) { | |||
default: break; | default: break; | |||
case 'n': // 41 strings to match. | case 'n': // 42 strings to match. | |||
if (memcmp(BuiltinName.data()+3, "vvm_", 4)) | if (memcmp(BuiltinName.data()+3, "vvm_", 4)) | |||
break; | break; | |||
switch (BuiltinName[7]) { | switch (BuiltinName[7]) { | |||
default: break; | default: break; | |||
case 'a': // 1 string to match. | case 'a': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+8, "bs_ll", 5)) | if (memcmp(BuiltinName.data()+8, "bs_ll", 5)) | |||
break; | break; | |||
return Intrinsic::nvvm_abs_ll; // "__nvvm_abs_ll" | return Intrinsic::nvvm_abs_ll; // "__nvvm_abs_ll" | |||
case 'b': // 2 strings to match. | case 'b': // 2 strings to match. | |||
if (memcmp(BuiltinName.data()+8, "rev", 3)) | if (memcmp(BuiltinName.data()+8, "rev", 3)) | |||
skipping to change at line 28296 | skipping to change at line 27677 | |||
break; | break; | |||
return Intrinsic::nvvm_min_ui; // "__nvvm_min_ui" | return Intrinsic::nvvm_min_ui; // "__nvvm_min_ui" | |||
} | } | |||
break; | break; | |||
} | } | |||
break; | break; | |||
case 'p': // 1 string to match. | case 'p': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+8, "opc_i", 5)) | if (memcmp(BuiltinName.data()+8, "opc_i", 5)) | |||
break; | break; | |||
return Intrinsic::nvvm_popc_i; // "__nvvm_popc_i" | return Intrinsic::nvvm_popc_i; // "__nvvm_popc_i" | |||
case 's': // 1 string to match. | case 's': // 2 strings to match. | |||
if (memcmp(BuiltinName.data()+8, "ad_ui", 5)) | switch (BuiltinName[8]) { | |||
break; | default: break; | |||
return Intrinsic::nvvm_sad_ui; // "__nvvm_sad_ui" | case 'a': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+9, "d_ui", 4)) | ||||
break; | ||||
return Intrinsic::nvvm_sad_ui; // "__nvvm_sad_ui" | ||||
case 'q': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+9, "rt_f", 4)) | ||||
break; | ||||
return Intrinsic::nvvm_sqrt_f; // "__nvvm_sqrt_f" | ||||
} | ||||
break; | ||||
} | } | |||
break; | break; | |||
case 's': // 1 string to match. | case 's': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+3, "yncthreads", 10)) | if (memcmp(BuiltinName.data()+3, "yncthreads", 10)) | |||
break; | break; | |||
return Intrinsic::cuda_syncthreads; // "__syncthreads" | return Intrinsic::cuda_syncthreads; // "__syncthreads" | |||
} | } | |||
break; | break; | |||
case 14: // 47 strings to match. | case 14: // 47 strings to match. | |||
if (memcmp(BuiltinName.data()+0, "__", 2)) | if (memcmp(BuiltinName.data()+0, "__", 2)) | |||
skipping to change at line 39159 | skipping to change at line 38549 | |||
} | } | |||
break; | break; | |||
case 'm': // 1 string to match. | case 'm': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+20, "hraddshs", 8)) | if (memcmp(BuiltinName.data()+20, "hraddshs", 8)) | |||
break; | break; | |||
return Intrinsic::ppc_altivec_vmhraddshs; // "__builtin_altiv ec_vmhraddshs" | return Intrinsic::ppc_altivec_vmhraddshs; // "__builtin_altiv ec_vmhraddshs" | |||
} | } | |||
break; | break; | |||
} | } | |||
} | } | |||
if (TargetPrefix == "spu") { | if (TargetPrefix == "r600") { | |||
switch (BuiltinName.size()) { | switch (BuiltinName.size()) { | |||
default: break; | default: break; | |||
case 14: // 1 string to match. | case 26: // 3 strings to match. | |||
if (memcmp(BuiltinName.data()+0, "__builtin_si_a", 14)) | if (memcmp(BuiltinName.data()+0, "__builtin_r600_read_tgid_", 25)) | |||
break; | ||||
return Intrinsic::spu_si_a; // "__builtin_si_a" | ||||
case 15: // 9 strings to match. | ||||
if (memcmp(BuiltinName.data()+0, "__builtin_si_", 13)) | ||||
break; | break; | |||
switch (BuiltinName[13]) { | switch (BuiltinName[25]) { | |||
default: break; | ||||
case 'a': // 2 strings to match. | ||||
switch (BuiltinName[14]) { | ||||
default: break; | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_ah; // "__builtin_si_ah" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_ai; // "__builtin_si_ai" | ||||
} | ||||
break; | ||||
case 'b': // 1 string to match. | ||||
if (BuiltinName[14] != 'g') | ||||
break; | ||||
return Intrinsic::spu_si_bg; // "__builtin_si_bg" | ||||
case 'c': // 1 string to match. | ||||
if (BuiltinName[14] != 'g') | ||||
break; | ||||
return Intrinsic::spu_si_cg; // "__builtin_si_cg" | ||||
case 'f': // 3 strings to match. | ||||
switch (BuiltinName[14]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_fa; // "__builtin_si_fa" | ||||
case 'm': // 1 string to match. | ||||
return Intrinsic::spu_si_fm; // "__builtin_si_fm" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_fs; // "__builtin_si_fs" | ||||
} | ||||
break; | ||||
case 'o': // 1 string to match. | ||||
if (BuiltinName[14] != 'r') | ||||
break; | ||||
return Intrinsic::spu_si_or; // "__builtin_si_or" | ||||
case 's': // 1 string to match. | ||||
if (BuiltinName[14] != 'f') | ||||
break; | ||||
return Intrinsic::spu_si_sf; // "__builtin_si_sf" | ||||
} | ||||
break; | ||||
case 16: // 19 strings to match. | ||||
if (memcmp(BuiltinName.data()+0, "__builtin_si_", 13)) | ||||
break; | ||||
switch (BuiltinName[13]) { | ||||
default: break; | default: break; | |||
case 'a': // 2 strings to match. | ||||
switch (BuiltinName[14]) { | ||||
default: break; | ||||
case 'h': // 1 string to match. | ||||
if (BuiltinName[15] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_ahi; // "__builtin_si_ahi" | ||||
case 'n': // 1 string to match. | ||||
if (BuiltinName[15] != 'd') | ||||
break; | ||||
return Intrinsic::spu_si_and; // "__builtin_si_and" | ||||
} | ||||
break; | ||||
case 'b': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+14, "gx", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_bgx; // "__builtin_si_bgx" | ||||
case 'c': // 3 strings to match. | ||||
switch (BuiltinName[14]) { | ||||
default: break; | ||||
case 'e': // 1 string to match. | ||||
if (BuiltinName[15] != 'q') | ||||
break; | ||||
return Intrinsic::spu_si_ceq; // "__builtin_si_ceq" | ||||
case 'g': // 2 strings to match. | ||||
switch (BuiltinName[15]) { | ||||
default: break; | ||||
case 't': // 1 string to match. | ||||
return Intrinsic::spu_si_cgt; // "__builtin_si_cgt" | ||||
case 'x': // 1 string to match. | ||||
return Intrinsic::spu_si_cgx; // "__builtin_si_cgx" | ||||
} | ||||
break; | ||||
} | ||||
break; | ||||
case 'd': // 3 strings to match. | ||||
if (BuiltinName[14] != 'f') | ||||
break; | ||||
switch (BuiltinName[15]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_dfa; // "__builtin_si_dfa" | ||||
case 'm': // 1 string to match. | ||||
return Intrinsic::spu_si_dfm; // "__builtin_si_dfm" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_dfs; // "__builtin_si_dfs" | ||||
} | ||||
break; | ||||
case 'f': // 2 strings to match. | ||||
if (BuiltinName[14] != 'm') | ||||
break; | ||||
switch (BuiltinName[15]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_fma; // "__builtin_si_fma" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_fms; // "__builtin_si_fms" | ||||
} | ||||
break; | ||||
case 'm': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+14, "py", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_mpy; // "__builtin_si_mpy" | ||||
case 'n': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+14, "or", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_nor; // "__builtin_si_nor" | ||||
case 'o': // 2 strings to match. | ||||
if (BuiltinName[14] != 'r') | ||||
break; | ||||
switch (BuiltinName[15]) { | ||||
default: break; | ||||
case 'c': // 1 string to match. | ||||
return Intrinsic::spu_si_orc; // "__builtin_si_orc" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_ori; // "__builtin_si_ori" | ||||
} | ||||
break; | ||||
case 's': // 3 strings to match. | ||||
if (BuiltinName[14] != 'f') | ||||
break; | ||||
switch (BuiltinName[15]) { | ||||
default: break; | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_sfh; // "__builtin_si_sfh" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_sfi; // "__builtin_si_sfi" | ||||
case 'x': // 1 string to match. | ||||
return Intrinsic::spu_si_sfx; // "__builtin_si_sfx" | ||||
} | ||||
break; | ||||
case 'x': // 1 string to match. | case 'x': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+14, "or", 2)) | return Intrinsic::r600_read_tgid_x; // "__builtin_r600_read_tgi | |||
break; | d_x" | |||
return Intrinsic::spu_si_xor; // "__builtin_si_xor" | case 'y': // 1 string to match. | |||
return Intrinsic::r600_read_tgid_y; // "__builtin_r600_read_tgi | ||||
d_y" | ||||
case 'z': // 1 string to match. | ||||
return Intrinsic::r600_read_tgid_z; // "__builtin_r600_read_tgi | ||||
d_z" | ||||
} | } | |||
break; | break; | |||
case 17: // 26 strings to match. | case 27: // 3 strings to match. | |||
if (memcmp(BuiltinName.data()+0, "__builtin_si_", 13)) | if (memcmp(BuiltinName.data()+0, "__builtin_r600_read_tidig_", 26)) | |||
break; | break; | |||
switch (BuiltinName[13]) { | switch (BuiltinName[26]) { | |||
default: break; | default: break; | |||
case 'a': // 3 strings to match. | ||||
switch (BuiltinName[14]) { | ||||
default: break; | ||||
case 'd': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+15, "dx", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_addx; // "__builtin_si_addx" | ||||
case 'n': // 2 strings to match. | ||||
if (BuiltinName[15] != 'd') | ||||
break; | ||||
switch (BuiltinName[16]) { | ||||
default: break; | ||||
case 'c': // 1 string to match. | ||||
return Intrinsic::spu_si_andc; // "__builtin_si_andc" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_andi; // "__builtin_si_andi" | ||||
} | ||||
break; | ||||
} | ||||
break; | ||||
case 'c': // 7 strings to match. | ||||
switch (BuiltinName[14]) { | ||||
default: break; | ||||
case 'e': // 3 strings to match. | ||||
if (BuiltinName[15] != 'q') | ||||
break; | ||||
switch (BuiltinName[16]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
return Intrinsic::spu_si_ceqb; // "__builtin_si_ceqb" | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_ceqh; // "__builtin_si_ceqh" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_ceqi; // "__builtin_si_ceqi" | ||||
} | ||||
break; | ||||
case 'g': // 3 strings to match. | ||||
if (BuiltinName[15] != 't') | ||||
break; | ||||
switch (BuiltinName[16]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
return Intrinsic::spu_si_cgtb; // "__builtin_si_cgtb" | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_cgth; // "__builtin_si_cgth" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_cgti; // "__builtin_si_cgti" | ||||
} | ||||
break; | ||||
case 'l': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+15, "gt", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_clgt; // "__builtin_si_clgt" | ||||
} | ||||
break; | ||||
case 'd': // 2 strings to match. | ||||
if (memcmp(BuiltinName.data()+14, "fm", 2)) | ||||
break; | ||||
switch (BuiltinName[16]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_dfma; // "__builtin_si_dfma" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_dfms; // "__builtin_si_dfms" | ||||
} | ||||
break; | ||||
case 'f': // 3 strings to match. | ||||
switch (BuiltinName[14]) { | ||||
default: break; | ||||
case 'c': // 2 strings to match. | ||||
switch (BuiltinName[15]) { | ||||
default: break; | ||||
case 'e': // 1 string to match. | ||||
if (BuiltinName[16] != 'q') | ||||
break; | ||||
return Intrinsic::spu_si_fceq; // "__builtin_si_fceq" | ||||
case 'g': // 1 string to match. | ||||
if (BuiltinName[16] != 't') | ||||
break; | ||||
return Intrinsic::spu_si_fcgt; // "__builtin_si_fcgt" | ||||
} | ||||
break; | ||||
case 'n': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+15, "ms", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_fnms; // "__builtin_si_fnms" | ||||
} | ||||
break; | ||||
case 'm': // 5 strings to match. | ||||
if (memcmp(BuiltinName.data()+14, "py", 2)) | ||||
break; | ||||
switch (BuiltinName[16]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_mpya; // "__builtin_si_mpya" | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_mpyh; // "__builtin_si_mpyh" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_mpyi; // "__builtin_si_mpyi" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_mpys; // "__builtin_si_mpys" | ||||
case 'u': // 1 string to match. | ||||
return Intrinsic::spu_si_mpyu; // "__builtin_si_mpyu" | ||||
} | ||||
break; | ||||
case 'n': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+14, "and", 3)) | ||||
break; | ||||
return Intrinsic::spu_si_nand; // "__builtin_si_nand" | ||||
case 'o': // 2 strings to match. | ||||
if (BuiltinName[14] != 'r') | ||||
break; | ||||
switch (BuiltinName[15]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
if (BuiltinName[16] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_orbi; // "__builtin_si_orbi" | ||||
case 'h': // 1 string to match. | ||||
if (BuiltinName[16] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_orhi; // "__builtin_si_orhi" | ||||
} | ||||
break; | ||||
case 's': // 2 strings to match. | ||||
switch (BuiltinName[14]) { | ||||
default: break; | ||||
case 'f': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+15, "hi", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_sfhi; // "__builtin_si_sfhi" | ||||
case 'h': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+15, "li", 2)) | ||||
break; | ||||
return Intrinsic::spu_si_shli; // "__builtin_si_shli" | ||||
} | ||||
break; | ||||
case 'x': // 1 string to match. | case 'x': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+14, "ori", 3)) | return Intrinsic::r600_read_tidig_x; // "__builtin_r600_read_tid | |||
break; | ig_x" | |||
return Intrinsic::spu_si_xori; // "__builtin_si_xori" | case 'y': // 1 string to match. | |||
return Intrinsic::r600_read_tidig_y; // "__builtin_r600_read_tid | ||||
ig_y" | ||||
case 'z': // 1 string to match. | ||||
return Intrinsic::r600_read_tidig_z; // "__builtin_r600_read_tid | ||||
ig_z" | ||||
} | } | |||
break; | break; | |||
case 18: // 18 strings to match. | case 29: // 3 strings to match. | |||
if (memcmp(BuiltinName.data()+0, "__builtin_si_", 13)) | if (memcmp(BuiltinName.data()+0, "__builtin_r600_read_ngroups_", 28)) | |||
break; | break; | |||
switch (BuiltinName[13]) { | switch (BuiltinName[28]) { | |||
default: break; | default: break; | |||
case 'a': // 2 strings to match. | case 'x': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+14, "nd", 2)) | return Intrinsic::r600_read_ngroups_x; // "__builtin_r600_read_ngr | |||
break; | oups_x" | |||
switch (BuiltinName[16]) { | case 'y': // 1 string to match. | |||
default: break; | return Intrinsic::r600_read_ngroups_y; // "__builtin_r600_read_ngr | |||
case 'b': // 1 string to match. | oups_y" | |||
if (BuiltinName[17] != 'i') | case 'z': // 1 string to match. | |||
break; | return Intrinsic::r600_read_ngroups_z; // "__builtin_r600_read_ngr | |||
return Intrinsic::spu_si_andbi; // "__builtin_si_andbi" | oups_z" | |||
case 'h': // 1 string to match. | ||||
if (BuiltinName[17] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_andhi; // "__builtin_si_andhi" | ||||
} | ||||
break; | ||||
case 'c': // 7 strings to match. | ||||
switch (BuiltinName[14]) { | ||||
default: break; | ||||
case 'e': // 2 strings to match. | ||||
if (BuiltinName[15] != 'q') | ||||
break; | ||||
switch (BuiltinName[16]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
if (BuiltinName[17] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_ceqbi; // "__builtin_si_ceqbi" | ||||
case 'h': // 1 string to match. | ||||
if (BuiltinName[17] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_ceqhi; // "__builtin_si_ceqhi" | ||||
} | ||||
break; | ||||
case 'g': // 2 strings to match. | ||||
if (BuiltinName[15] != 't') | ||||
break; | ||||
switch (BuiltinName[16]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
if (BuiltinName[17] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_cgtbi; // "__builtin_si_cgtbi" | ||||
case 'h': // 1 string to match. | ||||
if (BuiltinName[17] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_cgthi; // "__builtin_si_cgthi" | ||||
} | ||||
break; | ||||
case 'l': // 3 strings to match. | ||||
if (memcmp(BuiltinName.data()+15, "gt", 2)) | ||||
break; | ||||
switch (BuiltinName[17]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
return Intrinsic::spu_si_clgtb; // "__builtin_si_clgtb" | ||||
case 'h': // 1 string to match. | ||||
return Intrinsic::spu_si_clgth; // "__builtin_si_clgth" | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_clgti; // "__builtin_si_clgti" | ||||
} | ||||
break; | ||||
} | ||||
break; | ||||
case 'd': // 2 strings to match. | ||||
if (memcmp(BuiltinName.data()+14, "fnm", 3)) | ||||
break; | ||||
switch (BuiltinName[17]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_dfnma; // "__builtin_si_dfnma" | ||||
case 's': // 1 string to match. | ||||
return Intrinsic::spu_si_dfnms; // "__builtin_si_dfnms" | ||||
} | ||||
break; | ||||
case 'f': // 3 strings to match. | ||||
switch (BuiltinName[14]) { | ||||
default: break; | ||||
case 'c': // 2 strings to match. | ||||
if (BuiltinName[15] != 'm') | ||||
break; | ||||
switch (BuiltinName[16]) { | ||||
default: break; | ||||
case 'e': // 1 string to match. | ||||
if (BuiltinName[17] != 'q') | ||||
break; | ||||
return Intrinsic::spu_si_fcmeq; // "__builtin_si_fcmeq" | ||||
case 'g': // 1 string to match. | ||||
if (BuiltinName[17] != 't') | ||||
break; | ||||
return Intrinsic::spu_si_fcmgt; // "__builtin_si_fcmgt" | ||||
} | ||||
break; | ||||
case 's': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+15, "mbi", 3)) | ||||
break; | ||||
return Intrinsic::spu_si_fsmbi; // "__builtin_si_fsmbi" | ||||
} | ||||
break; | ||||
case 'm': // 2 strings to match. | ||||
if (memcmp(BuiltinName.data()+14, "py", 2)) | ||||
break; | ||||
switch (BuiltinName[16]) { | ||||
default: break; | ||||
case 'h': // 1 string to match. | ||||
if (BuiltinName[17] != 'h') | ||||
break; | ||||
return Intrinsic::spu_si_mpyhh; // "__builtin_si_mpyhh" | ||||
case 'u': // 1 string to match. | ||||
if (BuiltinName[17] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_mpyui; // "__builtin_si_mpyui" | ||||
} | ||||
break; | ||||
case 'x': // 2 strings to match. | ||||
if (memcmp(BuiltinName.data()+14, "or", 2)) | ||||
break; | ||||
switch (BuiltinName[16]) { | ||||
default: break; | ||||
case 'b': // 1 string to match. | ||||
if (BuiltinName[17] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_xorbi; // "__builtin_si_xorbi" | ||||
case 'h': // 1 string to match. | ||||
if (BuiltinName[17] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_xorhi; // "__builtin_si_xorhi" | ||||
} | ||||
break; | ||||
} | } | |||
break; | break; | |||
case 19: // 6 strings to match. | case 32: // 3 strings to match. | |||
if (memcmp(BuiltinName.data()+0, "__builtin_si_", 13)) | if (memcmp(BuiltinName.data()+0, "__builtin_r600_read_local_size_", 31) | |||
) | ||||
break; | break; | |||
switch (BuiltinName[13]) { | switch (BuiltinName[31]) { | |||
default: break; | default: break; | |||
case 'c': // 2 strings to match. | case 'x': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+14, "lgt", 3)) | return Intrinsic::r600_read_local_size_x; // "__builtin_r600_ | |||
break; | read_local_size_x" | |||
switch (BuiltinName[17]) { | case 'y': // 1 string to match. | |||
default: break; | return Intrinsic::r600_read_local_size_y; // "__builtin_r600_ | |||
case 'b': // 1 string to match. | read_local_size_y" | |||
if (BuiltinName[18] != 'i') | case 'z': // 1 string to match. | |||
break; | return Intrinsic::r600_read_local_size_z; // "__builtin_r600_ | |||
return Intrinsic::spu_si_clgtbi; // "__builtin_si_clgtbi" | read_local_size_z" | |||
case 'h': // 1 string to match. | ||||
if (BuiltinName[18] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_clgthi; // "__builtin_si_clgthi" | ||||
} | ||||
break; | ||||
case 'm': // 2 strings to match. | ||||
if (memcmp(BuiltinName.data()+14, "pyhh", 4)) | ||||
break; | ||||
switch (BuiltinName[18]) { | ||||
default: break; | ||||
case 'a': // 1 string to match. | ||||
return Intrinsic::spu_si_mpyhha; // "__builtin_si_mpyhha" | ||||
case 'u': // 1 string to match. | ||||
return Intrinsic::spu_si_mpyhhu; // "__builtin_si_mpyhhu" | ||||
} | ||||
break; | ||||
case 's': // 2 strings to match. | ||||
if (memcmp(BuiltinName.data()+14, "hlqb", 4)) | ||||
break; | ||||
switch (BuiltinName[18]) { | ||||
default: break; | ||||
case 'i': // 1 string to match. | ||||
return Intrinsic::spu_si_shlqbi; // "__builtin_si_shlqbi" | ||||
case 'y': // 1 string to match. | ||||
return Intrinsic::spu_si_shlqby; // "__builtin_si_shlqby" | ||||
} | ||||
break; | ||||
} | } | |||
break; | break; | |||
case 20: // 3 strings to match. | case 33: // 3 strings to match. | |||
if (memcmp(BuiltinName.data()+0, "__builtin_si_", 13)) | if (memcmp(BuiltinName.data()+0, "__builtin_r600_read_global_size_", 32 | |||
)) | ||||
break; | break; | |||
switch (BuiltinName[13]) { | switch (BuiltinName[32]) { | |||
default: break; | default: break; | |||
case 'm': // 1 string to match. | case 'x': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+14, "pyhhau", 6)) | return Intrinsic::r600_read_global_size_x; // "__builtin_r600_ | |||
break; | read_global_size_x" | |||
return Intrinsic::spu_si_mpyhhau; // "__builtin_si_mpyhhau" | case 'y': // 1 string to match. | |||
case 's': // 2 strings to match. | return Intrinsic::r600_read_global_size_y; // "__builtin_r600_ | |||
if (memcmp(BuiltinName.data()+14, "hlqb", 4)) | read_global_size_y" | |||
break; | case 'z': // 1 string to match. | |||
switch (BuiltinName[18]) { | return Intrinsic::r600_read_global_size_z; // "__builtin_r600_ | |||
default: break; | read_global_size_z" | |||
case 'i': // 1 string to match. | ||||
if (BuiltinName[19] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_shlqbii; // "__builtin_si_shlqbii" | ||||
case 'y': // 1 string to match. | ||||
if (BuiltinName[19] != 'i') | ||||
break; | ||||
return Intrinsic::spu_si_shlqbyi; // "__builtin_si_shlqbyi" | ||||
} | ||||
break; | ||||
} | } | |||
break; | break; | |||
} | } | |||
} | } | |||
if (TargetPrefix == "x86") { | if (TargetPrefix == "x86") { | |||
switch (BuiltinName.size()) { | switch (BuiltinName.size()) { | |||
default: break; | default: break; | |||
case 18: // 1 string to match. | case 18: // 1 string to match. | |||
if (memcmp(BuiltinName.data()+0, "__builtin_ia32_por", 18)) | if (memcmp(BuiltinName.data()+0, "__builtin_ia32_por", 18)) | |||
break; | break; | |||
skipping to change at line 39712 | skipping to change at line 38665 | |||
break; | break; | |||
return Intrinsic::x86_mmx_pxor; // "__builtin_ia32_pxor" | return Intrinsic::x86_mmx_pxor; // "__builtin_ia32_pxor" | |||
} | } | |||
break; | break; | |||
case 'x': // 1 string to match. | case 'x': // 1 string to match. | |||
if (memcmp(BuiltinName.data()+16, "end", 3)) | if (memcmp(BuiltinName.data()+16, "end", 3)) | |||
break; | break; | |||
return Intrinsic::x86_xend; // "__builtin_ia32_xend" | return Intrinsic::x86_xend; // "__builtin_ia32_xend" | |||
} | } | |||
break; | break; | |||
case 20: // 59 strings to match. | case 20: // 60 strings to match. | |||
if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15)) | if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15)) | |||
break; | break; | |||
switch (BuiltinName[15]) { | switch (BuiltinName[15]) { | |||
default: break; | default: break; | |||
case 'a': // 2 strings to match. | case 'a': // 2 strings to match. | |||
if (memcmp(BuiltinName.data()+16, "dds", 3)) | if (memcmp(BuiltinName.data()+16, "dds", 3)) | |||
break; | break; | |||
switch (BuiltinName[19]) { | switch (BuiltinName[19]) { | |||
default: break; | default: break; | |||
case 'd': // 1 string to match. | case 'd': // 1 string to match. | |||
skipping to change at line 40048 | skipping to change at line 39001 | |||
if (memcmp(BuiltinName.data()+16, "ubs", 3)) | if (memcmp(BuiltinName.data()+16, "ubs", 3)) | |||
break; | break; | |||
switch (BuiltinName[19]) { | switch (BuiltinName[19]) { | |||
default: break; | default: break; | |||
case 'd': // 1 string to match. | case 'd': // 1 string to match. | |||
return Intrinsic::x86_sse2_sub_sd; // "__builtin_ia32_subsd" | return Intrinsic::x86_sse2_sub_sd; // "__builtin_ia32_subsd" | |||
case 's': // 1 string to match. | case 's': // 1 string to match. | |||
return Intrinsic::x86_sse_sub_ss; // "__builtin_ia32_subss" | return Intrinsic::x86_sse_sub_ss; // "__builtin_ia32_subss" | |||
} | } | |||
break; | break; | |||
case 'x': // 1 string to match. | ||||
if (memcmp(BuiltinName.data()+16, "test", 4)) | ||||
break; | ||||
return Intrinsic::x86_xtest; // "__builtin_ia32_xtest" | ||||
} | } | |||
break; | break; | |||
case 21: // 50 strings to match. | case 21: // 50 strings to match. | |||
if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15)) | if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15)) | |||
break; | break; | |||
switch (BuiltinName[15]) { | switch (BuiltinName[15]) { | |||
default: break; | default: break; | |||
case 'c': // 5 strings to match. | case 'c': // 5 strings to match. | |||
if (memcmp(BuiltinName.data()+16, "omi", 3)) | if (memcmp(BuiltinName.data()+16, "omi", 3)) | |||
break; | break; | |||
End of changes. 173 change blocks. | ||||
1901 lines changed or deleted | 888 lines changed or added | |||
Intrinsics.h | Intrinsics.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines a set of enums which allow processing of intrinsic | // This file defines a set of enums which allow processing of intrinsic | |||
// functions. Values of these enum types are returned by | // functions. Values of these enum types are returned by | |||
// Function::getIntrinsicID. | // Function::getIntrinsicID. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_INTRINSICS_H | #ifndef LLVM_IR_INTRINSICS_H | |||
#define LLVM_INTRINSICS_H | #define LLVM_IR_INTRINSICS_H | |||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class Type; | class Type; | |||
class FunctionType; | class FunctionType; | |||
class Function; | class Function; | |||
class LLVMContext; | class LLVMContext; | |||
class Module; | class Module; | |||
class AttrListPtr; | class AttributeSet; | |||
/// Intrinsic Namespace - This namespace contains an enum with a value for | /// Intrinsic Namespace - This namespace contains an enum with a value for | |||
/// every intrinsic/builtin function known by LLVM. These enum values are | /// every intrinsic/builtin function known by LLVM. These enum values are | |||
/// returned by Function::getIntrinsicID(). | /// returned by Function::getIntrinsicID(). | |||
/// | /// | |||
namespace Intrinsic { | namespace Intrinsic { | |||
enum ID { | enum ID { | |||
not_intrinsic = 0, // Must be zero | not_intrinsic = 0, // Must be zero | |||
// Get the intrinsic enums generated from Intrinsics.td | // Get the intrinsic enums generated from Intrinsics.td | |||
#define GET_INTRINSIC_ENUM_VALUES | #define GET_INTRINSIC_ENUM_VALUES | |||
#include "llvm/Intrinsics.gen" | #include "llvm/IR/Intrinsics.gen" | |||
#undef GET_INTRINSIC_ENUM_VALUES | #undef GET_INTRINSIC_ENUM_VALUES | |||
, num_intrinsics | , num_intrinsics | |||
}; | }; | |||
/// Intrinsic::getName(ID) - Return the LLVM name for an intrinsic, such as | /// Intrinsic::getName(ID) - Return the LLVM name for an intrinsic, such as | |||
/// "llvm.ppc.altivec.lvx". | /// "llvm.ppc.altivec.lvx". | |||
std::string getName(ID id, ArrayRef<Type*> Tys = ArrayRef<Type*>()); | std::string getName(ID id, ArrayRef<Type*> Tys = None); | |||
/// Intrinsic::getType(ID) - Return the function type for an intrinsic. | /// Intrinsic::getType(ID) - Return the function type for an intrinsic. | |||
/// | /// | |||
FunctionType *getType(LLVMContext &Context, ID id, | FunctionType *getType(LLVMContext &Context, ID id, | |||
ArrayRef<Type*> Tys = ArrayRef<Type*>()); | ArrayRef<Type*> Tys = None); | |||
/// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be | /// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be | |||
/// overloaded. | /// overloaded. | |||
bool isOverloaded(ID id); | bool isOverloaded(ID id); | |||
/// Intrinsic::getAttributes(ID) - Return the attributes for an intrinsic . | /// Intrinsic::getAttributes(ID) - Return the attributes for an intrinsic . | |||
/// | /// | |||
AttrListPtr getAttributes(LLVMContext &C, ID id); | AttributeSet getAttributes(LLVMContext &C, ID id); | |||
/// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function | /// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function | |||
/// declaration for an intrinsic, and return it. | /// declaration for an intrinsic, and return it. | |||
/// | /// | |||
/// The Tys and numTys parameters are for intrinsics with overloaded type | /// The Tys parameter is for intrinsics with overloaded types (e.g., thos | |||
s | e | |||
/// (e.g., those using iAny, fAny, vAny, or iPTRAny). For a declaration f | /// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloa | |||
or an | ded | |||
/// overloaded intrinsic, Tys should point to an array of numTys pointers | /// intrinsic, Tys must provide exactly one type for each overloaded type | |||
to | in | |||
/// Type, and must provide exactly one type for each overloaded type in t | /// the intrinsic. | |||
he | Function *getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys = None); | |||
/// intrinsic. | ||||
Function *getDeclaration(Module *M, ID id, | ||||
ArrayRef<Type*> Tys = ArrayRef<Type*>()); | ||||
/// Map a GCC builtin name to an intrinsic ID. | /// Map a GCC builtin name to an intrinsic ID. | |||
ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName) ; | ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName) ; | |||
/// IITDescriptor - This is a type descriptor which explains the type | /// IITDescriptor - This is a type descriptor which explains the type | |||
/// requirements of an intrinsic. This is returned by | /// requirements of an intrinsic. This is returned by | |||
/// getIntrinsicInfoTableEntries. | /// getIntrinsicInfoTableEntries. | |||
struct IITDescriptor { | struct IITDescriptor { | |||
enum IITDescriptorKind { | enum IITDescriptorKind { | |||
Void, MMX, Metadata, Float, Double, | Void, MMX, Metadata, Half, Float, Double, | |||
Integer, Vector, Pointer, Struct, | Integer, Vector, Pointer, Struct, | |||
Argument, ExtendVecArgument, TruncVecArgument | Argument, ExtendVecArgument, TruncVecArgument | |||
} Kind; | } Kind; | |||
union { | union { | |||
unsigned Integer_Width; | unsigned Integer_Width; | |||
unsigned Float_Width; | unsigned Float_Width; | |||
unsigned Vector_Width; | unsigned Vector_Width; | |||
unsigned Pointer_AddressSpace; | unsigned Pointer_AddressSpace; | |||
unsigned Struct_NumElements; | unsigned Struct_NumElements; | |||
End of changes. 8 change blocks. | ||||
19 lines changed or deleted | 16 lines changed or added | |||
Intrinsics.td | Intrinsics.td | |||
---|---|---|---|---|
skipping to change at line 109 | skipping to change at line 109 | |||
def llvm_void_ty : LLVMType<isVoid>; | def llvm_void_ty : LLVMType<isVoid>; | |||
def llvm_anyint_ty : LLVMType<iAny>; | def llvm_anyint_ty : LLVMType<iAny>; | |||
def llvm_anyfloat_ty : LLVMType<fAny>; | def llvm_anyfloat_ty : LLVMType<fAny>; | |||
def llvm_anyvector_ty : LLVMType<vAny>; | def llvm_anyvector_ty : LLVMType<vAny>; | |||
def llvm_i1_ty : LLVMType<i1>; | def llvm_i1_ty : LLVMType<i1>; | |||
def llvm_i8_ty : LLVMType<i8>; | def llvm_i8_ty : LLVMType<i8>; | |||
def llvm_i16_ty : LLVMType<i16>; | def llvm_i16_ty : LLVMType<i16>; | |||
def llvm_i32_ty : LLVMType<i32>; | def llvm_i32_ty : LLVMType<i32>; | |||
def llvm_i64_ty : LLVMType<i64>; | def llvm_i64_ty : LLVMType<i64>; | |||
def llvm_half_ty : LLVMType<f16>; | ||||
def llvm_float_ty : LLVMType<f32>; | def llvm_float_ty : LLVMType<f32>; | |||
def llvm_double_ty : LLVMType<f64>; | def llvm_double_ty : LLVMType<f64>; | |||
def llvm_f80_ty : LLVMType<f80>; | def llvm_f80_ty : LLVMType<f80>; | |||
def llvm_f128_ty : LLVMType<f128>; | def llvm_f128_ty : LLVMType<f128>; | |||
def llvm_ppcf128_ty : LLVMType<ppcf128>; | def llvm_ppcf128_ty : LLVMType<ppcf128>; | |||
def llvm_ptr_ty : LLVMPointerType<llvm_i8_ty>; // i8* | def llvm_ptr_ty : LLVMPointerType<llvm_i8_ty>; // i8* | |||
def llvm_ptrptr_ty : LLVMPointerType<llvm_ptr_ty>; // i8** | def llvm_ptrptr_ty : LLVMPointerType<llvm_ptr_ty>; // i8** | |||
def llvm_anyptr_ty : LLVMAnyPointerType<llvm_i8_ty>; // (space )i8* | def llvm_anyptr_ty : LLVMAnyPointerType<llvm_i8_ty>; // (space )i8* | |||
def llvm_empty_ty : LLVMType<OtherVT>; // { } | def llvm_empty_ty : LLVMType<OtherVT>; // { } | |||
def llvm_descriptor_ty : LLVMPointerType<llvm_empty_ty>; // { }* | def llvm_descriptor_ty : LLVMPointerType<llvm_empty_ty>; // { }* | |||
def llvm_metadata_ty : LLVMType<MetadataVT>; // !{...} | def llvm_metadata_ty : LLVMType<MetadataVT>; // !{...} | |||
def llvm_x86mmx_ty : LLVMType<x86mmx>; | def llvm_x86mmx_ty : LLVMType<x86mmx>; | |||
def llvm_ptrx86mmx_ty : LLVMPointerType<llvm_x86mmx_ty>; // <1 x i 64>* | def llvm_ptrx86mmx_ty : LLVMPointerType<llvm_x86mmx_ty>; // <1 x i 64>* | |||
def llvm_v2i1_ty : LLVMType<v2i1>; // 2 x i1 | def llvm_v2i1_ty : LLVMType<v2i1>; // 2 x i1 | |||
def llvm_v4i1_ty : LLVMType<v4i1>; // 4 x i1 | def llvm_v4i1_ty : LLVMType<v4i1>; // 4 x i1 | |||
def llvm_v8i1_ty : LLVMType<v8i1>; // 8 x i1 | def llvm_v8i1_ty : LLVMType<v8i1>; // 8 x i1 | |||
def llvm_v16i1_ty : LLVMType<v16i1>; // 16 x i1 | def llvm_v16i1_ty : LLVMType<v16i1>; // 16 x i1 | |||
def llvm_v32i1_ty : LLVMType<v32i1>; // 32 x i1 | ||||
def llvm_v64i1_ty : LLVMType<v64i1>; // 64 x i1 | ||||
def llvm_v2i8_ty : LLVMType<v2i8>; // 2 x i8 | def llvm_v2i8_ty : LLVMType<v2i8>; // 2 x i8 | |||
def llvm_v4i8_ty : LLVMType<v4i8>; // 4 x i8 | def llvm_v4i8_ty : LLVMType<v4i8>; // 4 x i8 | |||
def llvm_v8i8_ty : LLVMType<v8i8>; // 8 x i8 | def llvm_v8i8_ty : LLVMType<v8i8>; // 8 x i8 | |||
def llvm_v16i8_ty : LLVMType<v16i8>; // 16 x i8 | def llvm_v16i8_ty : LLVMType<v16i8>; // 16 x i8 | |||
def llvm_v32i8_ty : LLVMType<v32i8>; // 32 x i8 | def llvm_v32i8_ty : LLVMType<v32i8>; // 32 x i8 | |||
def llvm_v64i8_ty : LLVMType<v64i8>; // 64 x i8 | ||||
def llvm_v1i16_ty : LLVMType<v1i16>; // 1 x i16 | def llvm_v1i16_ty : LLVMType<v1i16>; // 1 x i16 | |||
def llvm_v2i16_ty : LLVMType<v2i16>; // 2 x i16 | def llvm_v2i16_ty : LLVMType<v2i16>; // 2 x i16 | |||
def llvm_v4i16_ty : LLVMType<v4i16>; // 4 x i16 | def llvm_v4i16_ty : LLVMType<v4i16>; // 4 x i16 | |||
def llvm_v8i16_ty : LLVMType<v8i16>; // 8 x i16 | def llvm_v8i16_ty : LLVMType<v8i16>; // 8 x i16 | |||
def llvm_v16i16_ty : LLVMType<v16i16>; // 16 x i16 | def llvm_v16i16_ty : LLVMType<v16i16>; // 16 x i16 | |||
def llvm_v32i16_ty : LLVMType<v32i16>; // 32 x i16 | ||||
def llvm_v1i32_ty : LLVMType<v1i32>; // 1 x i32 | def llvm_v1i32_ty : LLVMType<v1i32>; // 1 x i32 | |||
def llvm_v2i32_ty : LLVMType<v2i32>; // 2 x i32 | def llvm_v2i32_ty : LLVMType<v2i32>; // 2 x i32 | |||
def llvm_v4i32_ty : LLVMType<v4i32>; // 4 x i32 | def llvm_v4i32_ty : LLVMType<v4i32>; // 4 x i32 | |||
def llvm_v8i32_ty : LLVMType<v8i32>; // 8 x i32 | def llvm_v8i32_ty : LLVMType<v8i32>; // 8 x i32 | |||
def llvm_v16i32_ty : LLVMType<v16i32>; // 16 x i32 | def llvm_v16i32_ty : LLVMType<v16i32>; // 16 x i32 | |||
def llvm_v1i64_ty : LLVMType<v1i64>; // 1 x i64 | def llvm_v1i64_ty : LLVMType<v1i64>; // 1 x i64 | |||
def llvm_v2i64_ty : LLVMType<v2i64>; // 2 x i64 | def llvm_v2i64_ty : LLVMType<v2i64>; // 2 x i64 | |||
def llvm_v4i64_ty : LLVMType<v4i64>; // 4 x i64 | def llvm_v4i64_ty : LLVMType<v4i64>; // 4 x i64 | |||
def llvm_v8i64_ty : LLVMType<v8i64>; // 8 x i64 | def llvm_v8i64_ty : LLVMType<v8i64>; // 8 x i64 | |||
def llvm_v16i64_ty : LLVMType<v16i64>; // 16 x i64 | def llvm_v16i64_ty : LLVMType<v16i64>; // 16 x i64 | |||
def llvm_v2f32_ty : LLVMType<v2f32>; // 2 x float | def llvm_v2f32_ty : LLVMType<v2f32>; // 2 x float | |||
def llvm_v4f32_ty : LLVMType<v4f32>; // 4 x float | def llvm_v4f32_ty : LLVMType<v4f32>; // 4 x float | |||
def llvm_v8f32_ty : LLVMType<v8f32>; // 8 x float | def llvm_v8f32_ty : LLVMType<v8f32>; // 8 x float | |||
def llvm_v16f32_ty : LLVMType<v16f32>; // 16 x float | ||||
def llvm_v2f64_ty : LLVMType<v2f64>; // 2 x double | def llvm_v2f64_ty : LLVMType<v2f64>; // 2 x double | |||
def llvm_v4f64_ty : LLVMType<v4f64>; // 4 x double | def llvm_v4f64_ty : LLVMType<v4f64>; // 4 x double | |||
def llvm_v8f64_ty : LLVMType<v8f64>; // 8 x double | ||||
def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here | def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Intrinsic Definitions. | // Intrinsic Definitions. | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Intrinsic class - This is used to define one LLVM intrinsic. The name o f the | // Intrinsic class - This is used to define one LLVM intrinsic. The name o f the | |||
// intrinsic definition should start with "int_", then match the LLVM intri nsic | // intrinsic definition should start with "int_", then match the LLVM intri nsic | |||
// name with the "llvm." prefix removed, and all "."s turned into "_"s. Fo r | // name with the "llvm." prefix removed, and all "."s turned into "_"s. Fo r | |||
skipping to change at line 272 | skipping to change at line 281 | |||
def int_cos : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | def int_cos : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | |||
def int_pow : Intrinsic<[llvm_anyfloat_ty], | def int_pow : Intrinsic<[llvm_anyfloat_ty], | |||
[LLVMMatchType<0>, LLVMMatchType<0>]>; | [LLVMMatchType<0>, LLVMMatchType<0>]>; | |||
def int_log : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | def int_log : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | |||
def int_log10: Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | def int_log10: Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | |||
def int_log2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | def int_log2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | |||
def int_exp : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | def int_exp : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | |||
def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | |||
def int_fabs : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | def int_fabs : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | |||
def int_floor : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | def int_floor : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | |||
def int_ceil : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | ||||
def int_trunc : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | ||||
def int_rint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | ||||
def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; | ||||
} | } | |||
let Properties = [IntrNoMem] in { | let Properties = [IntrNoMem] in { | |||
def int_fma : Intrinsic<[llvm_anyfloat_ty], | def int_fma : Intrinsic<[llvm_anyfloat_ty], | |||
[LLVMMatchType<0>, LLVMMatchType<0>, | [LLVMMatchType<0>, LLVMMatchType<0>, | |||
LLVMMatchType<0>]>; | LLVMMatchType<0>]>; | |||
def int_fmuladd : Intrinsic<[llvm_anyfloat_ty], | def int_fmuladd : Intrinsic<[llvm_anyfloat_ty], | |||
[LLVMMatchType<0>, LLVMMatchType<0>, | [LLVMMatchType<0>, LLVMMatchType<0>, | |||
LLVMMatchType<0>]>; | LLVMMatchType<0>]>; | |||
skipping to change at line 462 | skipping to change at line 475 | |||
[llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>; | [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>; | |||
def int_convertus : Intrinsic<[llvm_anyint_ty], | def int_convertus : Intrinsic<[llvm_anyint_ty], | |||
[llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>; | [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>; | |||
def int_convertuu : Intrinsic<[llvm_anyint_ty], | def int_convertuu : Intrinsic<[llvm_anyint_ty], | |||
[llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>; | [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Target-specific intrinsics | // Target-specific intrinsics | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
include "llvm/IntrinsicsPowerPC.td" | include "llvm/IR/IntrinsicsPowerPC.td" | |||
include "llvm/IntrinsicsX86.td" | include "llvm/IR/IntrinsicsX86.td" | |||
include "llvm/IntrinsicsARM.td" | include "llvm/IR/IntrinsicsARM.td" | |||
include "llvm/IntrinsicsCellSPU.td" | include "llvm/IR/IntrinsicsXCore.td" | |||
include "llvm/IntrinsicsXCore.td" | include "llvm/IR/IntrinsicsHexagon.td" | |||
include "llvm/IntrinsicsHexagon.td" | include "llvm/IR/IntrinsicsNVVM.td" | |||
include "llvm/IntrinsicsNVVM.td" | include "llvm/IR/IntrinsicsMips.td" | |||
include "llvm/IntrinsicsMips.td" | include "llvm/IR/IntrinsicsR600.td" | |||
End of changes. 8 change blocks. | ||||
0 lines changed or deleted | 13 lines changed or added | |||
IntrinsicsMips.td | IntrinsicsMips.td | |||
---|---|---|---|---|
skipping to change at line 198 | skipping to change at line 198 | |||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_q31_ty, mips_q31_ty], []>; | Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_q31_ty, mips_q31_ty], []>; | |||
def int_mips_dpsq_sa_l_w: GCCBuiltin<"__builtin_mips_dpsq_sa_l_w">, | def int_mips_dpsq_sa_l_w: GCCBuiltin<"__builtin_mips_dpsq_sa_l_w">, | |||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_q31_ty, mips_q31_ty], []>; | Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_q31_ty, mips_q31_ty], []>; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Comparison | // Comparison | |||
def int_mips_cmpu_eq_qb: GCCBuiltin<"__builtin_mips_cmpu_eq_qb">, | def int_mips_cmpu_eq_qb: GCCBuiltin<"__builtin_mips_cmpu_eq_qb">, | |||
Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | |||
def int_mips_cmpu_lt_qb: GCCBuiltin<"__builtin_mips_cmpu_lt_qb">, | def int_mips_cmpu_lt_qb: GCCBuiltin<"__builtin_mips_cmpu_lt_qb">, | |||
Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], []>; | |||
def int_mips_cmpu_le_qb: GCCBuiltin<"__builtin_mips_cmpu_le_qb">, | def int_mips_cmpu_le_qb: GCCBuiltin<"__builtin_mips_cmpu_le_qb">, | |||
Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], []>; | |||
def int_mips_cmpgu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgu_eq_qb">, | def int_mips_cmpgu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgu_eq_qb">, | |||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | |||
def int_mips_cmpgu_lt_qb: GCCBuiltin<"__builtin_mips_cmpgu_lt_qb">, | def int_mips_cmpgu_lt_qb: GCCBuiltin<"__builtin_mips_cmpgu_lt_qb">, | |||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>; | |||
def int_mips_cmpgu_le_qb: GCCBuiltin<"__builtin_mips_cmpgu_le_qb">, | def int_mips_cmpgu_le_qb: GCCBuiltin<"__builtin_mips_cmpgu_le_qb">, | |||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>; | |||
def int_mips_cmp_eq_ph: GCCBuiltin<"__builtin_mips_cmp_eq_ph">, | def int_mips_cmp_eq_ph: GCCBuiltin<"__builtin_mips_cmp_eq_ph">, | |||
Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>; | Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>; | |||
def int_mips_cmp_lt_ph: GCCBuiltin<"__builtin_mips_cmp_lt_ph">, | def int_mips_cmp_lt_ph: GCCBuiltin<"__builtin_mips_cmp_lt_ph">, | |||
Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>; | Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], []>; | |||
def int_mips_cmp_le_ph: GCCBuiltin<"__builtin_mips_cmp_le_ph">, | def int_mips_cmp_le_ph: GCCBuiltin<"__builtin_mips_cmp_le_ph">, | |||
Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>; | Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], []>; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Extracting | // Extracting | |||
def int_mips_extr_s_h: GCCBuiltin<"__builtin_mips_extr_s_h">, | def int_mips_extr_s_h: GCCBuiltin<"__builtin_mips_extr_s_h">, | |||
Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>; | Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>; | |||
def int_mips_extr_w: GCCBuiltin<"__builtin_mips_extr_w">, | def int_mips_extr_w: GCCBuiltin<"__builtin_mips_extr_w">, | |||
Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>; | Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>; | |||
def int_mips_extr_rs_w: GCCBuiltin<"__builtin_mips_extr_rs_w">, | def int_mips_extr_rs_w: GCCBuiltin<"__builtin_mips_extr_rs_w">, | |||
Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>; | Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>; | |||
skipping to change at line 310 | skipping to change at line 310 | |||
def int_mips_append: GCCBuiltin<"__builtin_mips_append">, | def int_mips_append: GCCBuiltin<"__builtin_mips_append">, | |||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], | Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], | |||
[IntrNoMem]>; | [IntrNoMem]>; | |||
def int_mips_balign: GCCBuiltin<"__builtin_mips_balign">, | def int_mips_balign: GCCBuiltin<"__builtin_mips_balign">, | |||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], | Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], | |||
[IntrNoMem]>; | [IntrNoMem]>; | |||
def int_mips_cmpgdu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgdu_eq_qb">, | def int_mips_cmpgdu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgdu_eq_qb">, | |||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | |||
def int_mips_cmpgdu_lt_qb: GCCBuiltin<"__builtin_mips_cmpgdu_lt_qb">, | def int_mips_cmpgdu_lt_qb: GCCBuiltin<"__builtin_mips_cmpgdu_lt_qb">, | |||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>; | |||
def int_mips_cmpgdu_le_qb: GCCBuiltin<"__builtin_mips_cmpgdu_le_qb">, | def int_mips_cmpgdu_le_qb: GCCBuiltin<"__builtin_mips_cmpgdu_le_qb">, | |||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>; | Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>; | |||
def int_mips_dpa_w_ph: GCCBuiltin<"__builtin_mips_dpa_w_ph">, | def int_mips_dpa_w_ph: GCCBuiltin<"__builtin_mips_dpa_w_ph">, | |||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty], | Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty], | |||
[IntrNoMem]>; | [IntrNoMem]>; | |||
def int_mips_dps_w_ph: GCCBuiltin<"__builtin_mips_dps_w_ph">, | def int_mips_dps_w_ph: GCCBuiltin<"__builtin_mips_dps_w_ph">, | |||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty], | Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty], | |||
[IntrNoMem]>; | [IntrNoMem]>; | |||
def int_mips_dpaqx_s_w_ph: GCCBuiltin<"__builtin_mips_dpaqx_s_w_ph">, | def int_mips_dpaqx_s_w_ph: GCCBuiltin<"__builtin_mips_dpaqx_s_w_ph">, | |||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []> ; | Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []> ; | |||
End of changes. 8 change blocks. | ||||
8 lines changed or deleted | 8 lines changed or added | |||
IntrinsicsNVVM.td | IntrinsicsNVVM.td | |||
---|---|---|---|---|
skipping to change at line 408 | skipping to change at line 408 | |||
def int_nvvm_rcp_rp_d : GCCBuiltin<"__nvvm_rcp_rp_d">, | def int_nvvm_rcp_rp_d : GCCBuiltin<"__nvvm_rcp_rp_d">, | |||
Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>; | Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>; | |||
def int_nvvm_rcp_approx_ftz_d : GCCBuiltin<"__nvvm_rcp_approx_ftz_d">, | def int_nvvm_rcp_approx_ftz_d : GCCBuiltin<"__nvvm_rcp_approx_ftz_d">, | |||
Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>; | Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>; | |||
// | // | |||
// Sqrt | // Sqrt | |||
// | // | |||
def int_nvvm_sqrt_f : GCCBuiltin<"__nvvm_sqrt_f">, | ||||
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | ||||
def int_nvvm_sqrt_rn_ftz_f : GCCBuiltin<"__nvvm_sqrt_rn_ftz_f">, | def int_nvvm_sqrt_rn_ftz_f : GCCBuiltin<"__nvvm_sqrt_rn_ftz_f">, | |||
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | |||
def int_nvvm_sqrt_rn_f : GCCBuiltin<"__nvvm_sqrt_rn_f">, | def int_nvvm_sqrt_rn_f : GCCBuiltin<"__nvvm_sqrt_rn_f">, | |||
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | |||
def int_nvvm_sqrt_rz_ftz_f : GCCBuiltin<"__nvvm_sqrt_rz_ftz_f">, | def int_nvvm_sqrt_rz_ftz_f : GCCBuiltin<"__nvvm_sqrt_rz_ftz_f">, | |||
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | |||
def int_nvvm_sqrt_rz_f : GCCBuiltin<"__nvvm_sqrt_rz_f">, | def int_nvvm_sqrt_rz_f : GCCBuiltin<"__nvvm_sqrt_rz_f">, | |||
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | |||
def int_nvvm_sqrt_rm_ftz_f : GCCBuiltin<"__nvvm_sqrt_rm_ftz_f">, | def int_nvvm_sqrt_rm_ftz_f : GCCBuiltin<"__nvvm_sqrt_rm_ftz_f">, | |||
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; | |||
skipping to change at line 805 | skipping to change at line 807 | |||
def int_nvvm_ldu_global_i : Intrinsic<[llvm_anyint_ty], | def int_nvvm_ldu_global_i : Intrinsic<[llvm_anyint_ty], | |||
[LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], | [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], | |||
"llvm.nvvm.ldu.global.i">; | "llvm.nvvm.ldu.global.i">; | |||
def int_nvvm_ldu_global_f : Intrinsic<[llvm_anyfloat_ty], | def int_nvvm_ldu_global_f : Intrinsic<[llvm_anyfloat_ty], | |||
[LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], | [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], | |||
"llvm.nvvm.ldu.global.f">; | "llvm.nvvm.ldu.global.f">; | |||
def int_nvvm_ldu_global_p : Intrinsic<[llvm_anyptr_ty], | def int_nvvm_ldu_global_p : Intrinsic<[llvm_anyptr_ty], | |||
[LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], | [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], | |||
"llvm.nvvm.ldu.global.p">; | "llvm.nvvm.ldu.global.p">; | |||
// Generated within nvvm. Use for ldg on sm_35 or later | ||||
def int_nvvm_ldg_global_i : Intrinsic<[llvm_anyint_ty], | ||||
[LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], | ||||
"llvm.nvvm.ldg.global.i">; | ||||
def int_nvvm_ldg_global_f : Intrinsic<[llvm_anyfloat_ty], | ||||
[LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], | ||||
"llvm.nvvm.ldg.global.f">; | ||||
def int_nvvm_ldg_global_p : Intrinsic<[llvm_anyptr_ty], | ||||
[LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], | ||||
"llvm.nvvm.ldg.global.p">; | ||||
// Use for generic pointers | // Use for generic pointers | |||
// - These intrinsics are used to convert address spaces. | // - These intrinsics are used to convert address spaces. | |||
// - The input pointer and output pointer must have the same type, except f or | // - The input pointer and output pointer must have the same type, except f or | |||
// the address-space. (This restriction is not enforced here as there is | // the address-space. (This restriction is not enforced here as there is | |||
// currently no way to describe it). | // currently no way to describe it). | |||
// - This complements the llvm bitcast, which can be used to cast one type | // - This complements the llvm bitcast, which can be used to cast one type | |||
// of pointer to another type of pointer, while the address space remains | // of pointer to another type of pointer, while the address space remains | |||
// the same. | // the same. | |||
def int_nvvm_ptr_local_to_gen: Intrinsic<[llvm_anyptr_ty], | def int_nvvm_ptr_local_to_gen: Intrinsic<[llvm_anyptr_ty], | |||
[llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], | [llvm_anyptr_ty], [IntrNoMem], | |||
"llvm.nvvm.ptr.local.to.gen">; | "llvm.nvvm.ptr.local.to.gen">; | |||
def int_nvvm_ptr_shared_to_gen: Intrinsic<[llvm_anyptr_ty], | def int_nvvm_ptr_shared_to_gen: Intrinsic<[llvm_anyptr_ty], | |||
[llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], | [llvm_anyptr_ty], [IntrNoMem], | |||
"llvm.nvvm.ptr.shared.to.gen">; | "llvm.nvvm.ptr.shared.to.gen">; | |||
def int_nvvm_ptr_global_to_gen: Intrinsic<[llvm_anyptr_ty], | def int_nvvm_ptr_global_to_gen: Intrinsic<[llvm_anyptr_ty], | |||
[llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], | [llvm_anyptr_ty], [IntrNoMem], | |||
"llvm.nvvm.ptr.global.to.gen">; | "llvm.nvvm.ptr.global.to.gen">; | |||
def int_nvvm_ptr_constant_to_gen: Intrinsic<[llvm_anyptr_ty], | def int_nvvm_ptr_constant_to_gen: Intrinsic<[llvm_anyptr_ty], | |||
[llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], | [llvm_anyptr_ty], [IntrNoMem], | |||
"llvm.nvvm.ptr.constant.to.gen">; | "llvm.nvvm.ptr.constant.to.gen">; | |||
def int_nvvm_ptr_gen_to_global: Intrinsic<[llvm_anyptr_ty], | def int_nvvm_ptr_gen_to_global: Intrinsic<[llvm_anyptr_ty], | |||
[llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], | [llvm_anyptr_ty], [IntrNoMem], | |||
"llvm.nvvm.ptr.gen.to.global">; | "llvm.nvvm.ptr.gen.to.global">; | |||
def int_nvvm_ptr_gen_to_shared: Intrinsic<[llvm_anyptr_ty], | def int_nvvm_ptr_gen_to_shared: Intrinsic<[llvm_anyptr_ty], | |||
[llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], | [llvm_anyptr_ty], [IntrNoMem], | |||
"llvm.nvvm.ptr.gen.to.shared">; | "llvm.nvvm.ptr.gen.to.shared">; | |||
def int_nvvm_ptr_gen_to_local: Intrinsic<[llvm_anyptr_ty], | def int_nvvm_ptr_gen_to_local: Intrinsic<[llvm_anyptr_ty], | |||
[llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], | [llvm_anyptr_ty], [IntrNoMem], | |||
"llvm.nvvm.ptr.gen.to.local">; | "llvm.nvvm.ptr.gen.to.local">; | |||
def int_nvvm_ptr_gen_to_constant: Intrinsic<[llvm_anyptr_ty], | def int_nvvm_ptr_gen_to_constant: Intrinsic<[llvm_anyptr_ty], | |||
[llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], | [llvm_anyptr_ty], [IntrNoMem], | |||
"llvm.nvvm.ptr.gen.to.constant">; | "llvm.nvvm.ptr.gen.to.constant">; | |||
// Used in nvvm internally to help address space opt and ptx code generatio n | // Used in nvvm internally to help address space opt and ptx code generatio n | |||
// This is for params that are passed to kernel functions by pointer by-val . | // This is for params that are passed to kernel functions by pointer by-val . | |||
def int_nvvm_ptr_gen_to_param: Intrinsic<[llvm_anyptr_ty], | def int_nvvm_ptr_gen_to_param: Intrinsic<[llvm_anyptr_ty], | |||
[llvm_anyptr_ty], | [llvm_anyptr_ty], | |||
[IntrNoMem, NoCapture<0>], | [IntrNoMem], | |||
"llvm.nvvm.ptr.gen.to.param">; | "llvm.nvvm.ptr.gen.to.param">; | |||
// Move intrinsics, used in nvvm internally | // Move intrinsics, used in nvvm internally | |||
def int_nvvm_move_i8 : Intrinsic<[llvm_i8_ty], [llvm_i8_ty], [IntrNoMem], | def int_nvvm_move_i8 : Intrinsic<[llvm_i8_ty], [llvm_i8_ty], [IntrNoMem], | |||
"llvm.nvvm.move.i8">; | "llvm.nvvm.move.i8">; | |||
def int_nvvm_move_i16 : Intrinsic<[llvm_i16_ty], [llvm_i16_ty], [IntrNoMem] , | def int_nvvm_move_i16 : Intrinsic<[llvm_i16_ty], [llvm_i16_ty], [IntrNoMem] , | |||
"llvm.nvvm.move.i16">; | "llvm.nvvm.move.i16">; | |||
def int_nvvm_move_i32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem] , | def int_nvvm_move_i32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem] , | |||
"llvm.nvvm.move.i32">; | "llvm.nvvm.move.i32">; | |||
End of changes. 11 change blocks. | ||||
9 lines changed or deleted | 22 lines changed or added | |||
IntrinsicsPowerPC.td | IntrinsicsPowerPC.td | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
// Definitions for all PowerPC intrinsics. | // Definitions for all PowerPC intrinsics. | |||
// | // | |||
// Non-altivec intrinsics. | // Non-altivec intrinsics. | |||
let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". | let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". | |||
// dcba/dcbf/dcbi/dcbst/dcbt/dcbz/dcbzl(PPC970) instructions. | // dcba/dcbf/dcbi/dcbst/dcbt/dcbz/dcbzl(PPC970) instructions. | |||
def int_ppc_dcba : Intrinsic<[], [llvm_ptr_ty], []>; | def int_ppc_dcba : Intrinsic<[], [llvm_ptr_ty], []>; | |||
def int_ppc_dcbf : Intrinsic<[], [llvm_ptr_ty], []>; | def int_ppc_dcbf : Intrinsic<[], [llvm_ptr_ty], []>; | |||
def int_ppc_dcbi : Intrinsic<[], [llvm_ptr_ty], []>; | def int_ppc_dcbi : Intrinsic<[], [llvm_ptr_ty], []>; | |||
def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>; | def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>; | |||
def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty], []>; | def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty], | |||
[IntrReadWriteArgMem, NoCapture<0>]>; | ||||
def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty], []>; | def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty], []>; | |||
def int_ppc_dcbz : Intrinsic<[], [llvm_ptr_ty], []>; | def int_ppc_dcbz : Intrinsic<[], [llvm_ptr_ty], []>; | |||
def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>; | def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>; | |||
// sync instruction | // sync instruction | |||
def int_ppc_sync : Intrinsic<[], [], []>; | def int_ppc_sync : Intrinsic<[], [], []>; | |||
} | } | |||
let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc." . | let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc." . | |||
/// PowerPC_Vec_Intrinsic - Base class for all altivec intrinsics. | /// PowerPC_Vec_Intrinsic - Base class for all altivec intrinsics. | |||
skipping to change at line 116 | skipping to change at line 117 | |||
// VSCR access. | // VSCR access. | |||
def int_ppc_altivec_mfvscr : GCCBuiltin<"__builtin_altivec_mfvscr">, | def int_ppc_altivec_mfvscr : GCCBuiltin<"__builtin_altivec_mfvscr">, | |||
Intrinsic<[llvm_v8i16_ty], [], [IntrReadMem]>; | Intrinsic<[llvm_v8i16_ty], [], [IntrReadMem]>; | |||
def int_ppc_altivec_mtvscr : GCCBuiltin<"__builtin_altivec_mtvscr">, | def int_ppc_altivec_mtvscr : GCCBuiltin<"__builtin_altivec_mtvscr">, | |||
Intrinsic<[], [llvm_v4i32_ty], []>; | Intrinsic<[], [llvm_v4i32_ty], []>; | |||
// Loads. These don't map directly to GCC builtins because they represen t the | // Loads. These don't map directly to GCC builtins because they represen t the | |||
// source address with a single pointer. | // source address with a single pointer. | |||
def int_ppc_altivec_lvx : | def int_ppc_altivec_lvx : | |||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>; | Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadArgMem]>; | |||
def int_ppc_altivec_lvxl : | def int_ppc_altivec_lvxl : | |||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>; | Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadArgMem]>; | |||
def int_ppc_altivec_lvebx : | def int_ppc_altivec_lvebx : | |||
Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadMem]>; | Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadArgMem]>; | |||
def int_ppc_altivec_lvehx : | def int_ppc_altivec_lvehx : | |||
Intrinsic<[llvm_v8i16_ty], [llvm_ptr_ty], [IntrReadMem]>; | Intrinsic<[llvm_v8i16_ty], [llvm_ptr_ty], [IntrReadArgMem]>; | |||
def int_ppc_altivec_lvewx : | def int_ppc_altivec_lvewx : | |||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>; | Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadArgMem]>; | |||
// Stores. These don't map directly to GCC builtins because they represe nt the | // Stores. These don't map directly to GCC builtins because they represe nt the | |||
// source address with a single pointer. | // source address with a single pointer. | |||
def int_ppc_altivec_stvx : | def int_ppc_altivec_stvx : | |||
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], []>; | Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], | |||
[IntrReadWriteArgMem]>; | ||||
def int_ppc_altivec_stvxl : | def int_ppc_altivec_stvxl : | |||
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], []>; | Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], | |||
[IntrReadWriteArgMem]>; | ||||
def int_ppc_altivec_stvebx : | def int_ppc_altivec_stvebx : | |||
Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty], []>; | Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty], | |||
[IntrReadWriteArgMem]>; | ||||
def int_ppc_altivec_stvehx : | def int_ppc_altivec_stvehx : | |||
Intrinsic<[], [llvm_v8i16_ty, llvm_ptr_ty], []>; | Intrinsic<[], [llvm_v8i16_ty, llvm_ptr_ty], | |||
[IntrReadWriteArgMem]>; | ||||
def int_ppc_altivec_stvewx : | def int_ppc_altivec_stvewx : | |||
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], []>; | Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], | |||
[IntrReadWriteArgMem]>; | ||||
// Comparisons setting a vector. | // Comparisons setting a vector. | |||
def int_ppc_altivec_vcmpbfp : GCCBuiltin<"__builtin_altivec_vcmpbfp">, | def int_ppc_altivec_vcmpbfp : GCCBuiltin<"__builtin_altivec_vcmpbfp">, | |||
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], | Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], | |||
[IntrNoMem]>; | [IntrNoMem]>; | |||
def int_ppc_altivec_vcmpeqfp : GCCBuiltin<"__builtin_altivec_vcmpeqfp">, | def int_ppc_altivec_vcmpeqfp : GCCBuiltin<"__builtin_altivec_vcmpeqfp">, | |||
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], | Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], | |||
[IntrNoMem]>; | [IntrNoMem]>; | |||
def int_ppc_altivec_vcmpgefp : GCCBuiltin<"__builtin_altivec_vcmpgefp">, | def int_ppc_altivec_vcmpgefp : GCCBuiltin<"__builtin_altivec_vcmpgefp">, | |||
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], | Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], | |||
End of changes. 11 change blocks. | ||||
11 lines changed or deleted | 17 lines changed or added | |||
IntrinsicsX86.td | IntrinsicsX86.td | |||
---|---|---|---|---|
skipping to change at line 2552 | skipping to change at line 2552 | |||
Intrinsic<[llvm_v8f32_ty], [llvm_v8i16_ty], [IntrNoMem]>; | Intrinsic<[llvm_v8f32_ty], [llvm_v8i16_ty], [IntrNoMem]>; | |||
def int_x86_vcvtps2ph_128 : GCCBuiltin<"__builtin_ia32_vcvtps2ph">, | def int_x86_vcvtps2ph_128 : GCCBuiltin<"__builtin_ia32_vcvtps2ph">, | |||
Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_i32_ty], | Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_i32_ty], | |||
[IntrNoMem]>; | [IntrNoMem]>; | |||
def int_x86_vcvtps2ph_256 : GCCBuiltin<"__builtin_ia32_vcvtps2ph256">, | def int_x86_vcvtps2ph_256 : GCCBuiltin<"__builtin_ia32_vcvtps2ph256">, | |||
Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty, llvm_i32_ty], | Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty, llvm_i32_ty], | |||
[IntrNoMem]>; | [IntrNoMem]>; | |||
} | } | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// RDRAND intrinsics. Return a random value and whether it is valid. | // RDRAND intrinsics - Return a random value and whether it is valid. | |||
// RDSEED intrinsics - Return a NIST SP800-90B & C compliant random value a | ||||
nd | ||||
// whether it is valid. | ||||
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". | let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". | |||
// These are declared side-effecting so they don't get eliminated by CSE or | // These are declared side-effecting so they don't get eliminated by CSE or | |||
// LICM. | // LICM. | |||
def int_x86_rdrand_16 : Intrinsic<[llvm_i16_ty, llvm_i32_ty], [], []>; | def int_x86_rdrand_16 : Intrinsic<[llvm_i16_ty, llvm_i32_ty], [], []>; | |||
def int_x86_rdrand_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>; | def int_x86_rdrand_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>; | |||
def int_x86_rdrand_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>; | def int_x86_rdrand_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>; | |||
def int_x86_rdseed_16 : Intrinsic<[llvm_i16_ty, llvm_i32_ty], [], []>; | ||||
def int_x86_rdseed_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>; | ||||
def int_x86_rdseed_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>; | ||||
} | } | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// RTM intrinsics. Transactional Memory support. | // RTM intrinsics. Transactional Memory support. | |||
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". | let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". | |||
def int_x86_xbegin : GCCBuiltin<"__builtin_ia32_xbegin">, | def int_x86_xbegin : GCCBuiltin<"__builtin_ia32_xbegin">, | |||
Intrinsic<[llvm_i32_ty], [], []>; | Intrinsic<[llvm_i32_ty], [], []>; | |||
def int_x86_xend : GCCBuiltin<"__builtin_ia32_xend">, | def int_x86_xend : GCCBuiltin<"__builtin_ia32_xend">, | |||
Intrinsic<[], [], []>; | Intrinsic<[], [], []>; | |||
def int_x86_xabort : GCCBuiltin<"__builtin_ia32_xabort">, | def int_x86_xabort : GCCBuiltin<"__builtin_ia32_xabort">, | |||
Intrinsic<[], [llvm_i8_ty], [IntrNoReturn]>; | Intrinsic<[], [llvm_i8_ty], [IntrNoReturn]>; | |||
def int_x86_xtest : GCCBuiltin<"__builtin_ia32_xtest">, | ||||
Intrinsic<[llvm_i32_ty], [], []>; | ||||
} | } | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 9 lines changed or added | |||
IntrusiveRefCntPtr.h | IntrusiveRefCntPtr.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// implements a "smart" pointer for objects that maintain their own | // implements a "smart" pointer for objects that maintain their own | |||
// internal reference count, and RefCountedBase/RefCountedBaseVPTR, two | // internal reference count, and RefCountedBase/RefCountedBaseVPTR, two | |||
// generic base classes for objects that wish to have their lifetimes | // generic base classes for objects that wish to have their lifetimes | |||
// managed using reference counting. | // managed using reference counting. | |||
// | // | |||
// IntrusiveRefCntPtr is similar to Boost's intrusive_ptr with added | // IntrusiveRefCntPtr is similar to Boost's intrusive_ptr with added | |||
// LLVM-style casting. | // LLVM-style casting. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR | #ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H | |||
#define LLVM_ADT_INTRUSIVE_REF_CNT_PTR | #define LLVM_ADT_INTRUSIVEREFCNTPTR_H | |||
#include "llvm/Support/Casting.h" | #include "llvm/Support/Casting.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include <memory> | #include <memory> | |||
namespace llvm { | namespace llvm { | |||
template <class T> | template <class T> | |||
class IntrusiveRefCntPtr; | class IntrusiveRefCntPtr; | |||
skipping to change at line 125 | skipping to change at line 125 | |||
explicit IntrusiveRefCntPtr() : Obj(0) {} | explicit IntrusiveRefCntPtr() : Obj(0) {} | |||
IntrusiveRefCntPtr(T* obj) : Obj(obj) { | IntrusiveRefCntPtr(T* obj) : Obj(obj) { | |||
retain(); | retain(); | |||
} | } | |||
IntrusiveRefCntPtr(const IntrusiveRefCntPtr& S) : Obj(S.Obj) { | IntrusiveRefCntPtr(const IntrusiveRefCntPtr& S) : Obj(S.Obj) { | |||
retain(); | retain(); | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) { | IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) { | |||
S.Obj = 0; | S.Obj = 0; | |||
} | } | |||
template <class X> | template <class X> | |||
IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.getPtr()) { | IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.getPtr()) { | |||
S.Obj = 0; | S.Obj = 0; | |||
} | } | |||
#endif | #endif | |||
skipping to change at line 228 | skipping to change at line 228 | |||
{ | { | |||
return A != B.getPtr(); | return A != B.getPtr(); | |||
} | } | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// LLVM-style downcasting support for IntrusiveRefCntPtr objects | // LLVM-style downcasting support for IntrusiveRefCntPtr objects | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > { | template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > { | |||
typedef T* SimpleType; | typedef T* SimpleType; | |||
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) { | static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) { | |||
return Val.getPtr(); | return Val.getPtr(); | |||
} | } | |||
}; | }; | |||
template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > { | template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > { | |||
typedef T* SimpleType; | typedef /*const*/ T* SimpleType; | |||
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) { | static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) { | |||
return Val.getPtr(); | return Val.getPtr(); | |||
} | } | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR | #endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H | |||
End of changes. 5 change blocks. | ||||
5 lines changed or deleted | 5 lines changed or added | |||
JIT.h | JIT.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file forces the JIT to link in on certain operating systems. | // This file forces the JIT to link in on certain operating systems. | |||
// (Windows). | // (Windows). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_EXECUTION_ENGINE_JIT_H | #ifndef LLVM_EXECUTIONENGINE_JIT_H | |||
#define LLVM_EXECUTION_ENGINE_JIT_H | #define LLVM_EXECUTIONENGINE_JIT_H | |||
#include "llvm/ExecutionEngine/ExecutionEngine.h" | #include "llvm/ExecutionEngine/ExecutionEngine.h" | |||
#include <cstdlib> | #include <cstdlib> | |||
extern "C" void LLVMLinkInJIT(); | extern "C" void LLVMLinkInJIT(); | |||
namespace { | namespace { | |||
struct ForceJITLinking { | struct ForceJITLinking { | |||
ForceJITLinking() { | ForceJITLinking() { | |||
// We must reference JIT in such a way that compilers will not | // We must reference JIT in such a way that compilers will not | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
JITCodeEmitter.h | JITCodeEmitter.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file defines an abstract interface that is used by the machine code | // This file defines an abstract interface that is used by the machine code | |||
// emission framework to output the code. This allows machine code emissio n to | // emission framework to output the code. This allows machine code emissio n to | |||
// be separated from concerns such as resolution of call targets, and where the | // be separated from concerns such as resolution of call targets, and where the | |||
// machine code will be written (memory or disk, f.e.). | // machine code will be written (memory or disk, f.e.). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_JITCODEEMITTER_H | #ifndef LLVM_CODEGEN_JITCODEEMITTER_H | |||
#define LLVM_CODEGEN_JITCODEEMITTER_H | #define LLVM_CODEGEN_JITCODEEMITTER_H | |||
#include <string> | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/CodeGen/MachineCodeEmitter.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/MathExtras.h" | #include "llvm/Support/MathExtras.h" | |||
#include "llvm/CodeGen/MachineCodeEmitter.h" | #include <string> | |||
#include "llvm/ADT/DenseMap.h" | ||||
namespace llvm { | namespace llvm { | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
class MachineConstantPool; | class MachineConstantPool; | |||
class MachineJumpTableInfo; | class MachineJumpTableInfo; | |||
class MachineFunction; | class MachineFunction; | |||
class MachineModuleInfo; | class MachineModuleInfo; | |||
class MachineRelocation; | class MachineRelocation; | |||
class Value; | class Value; | |||
skipping to change at line 210 | skipping to change at line 210 | |||
Value >>= 7; | Value >>= 7; | |||
IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; | IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; | |||
if (IsMore) Byte |= 0x80; | if (IsMore) Byte |= 0x80; | |||
emitByte(Byte); | emitByte(Byte); | |||
} while (IsMore); | } while (IsMore); | |||
} | } | |||
/// emitString - This callback is invoked when a String needs to be | /// emitString - This callback is invoked when a String needs to be | |||
/// written to the output stream. | /// written to the output stream. | |||
void emitString(const std::string &String) { | void emitString(const std::string &String) { | |||
for (unsigned i = 0, N = static_cast<unsigned>(String.size()); | for (size_t i = 0, N = String.size(); i < N; ++i) { | |||
i < N; ++i) { | ||||
uint8_t C = String[i]; | uint8_t C = String[i]; | |||
emitByte(C); | emitByte(C); | |||
} | } | |||
emitByte(0); | emitByte(0); | |||
} | } | |||
/// emitInt32 - Emit a int32 directive. | /// emitInt32 - Emit a int32 directive. | |||
void emitInt32(uint32_t Value) { | void emitInt32(uint32_t Value) { | |||
if (4 <= BufferEnd-CurBufferPtr) { | if (4 <= BufferEnd-CurBufferPtr) { | |||
*((uint32_t*)CurBufferPtr) = Value; | *((uint32_t*)CurBufferPtr) = Value; | |||
End of changes. 3 change blocks. | ||||
5 lines changed or deleted | 4 lines changed or added | |||
JITEventListener.h | JITEventListener.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the JITEventListener interface, which lets users get | // This file defines the JITEventListener interface, which lets users get | |||
// callbacks when significant events happen during the JIT compilation proc ess. | // callbacks when significant events happen during the JIT compilation proc ess. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H | #ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H | |||
#define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H | #define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H | |||
#include "llvm/Config/config.h" | #include "llvm/Config/llvm-config.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/DebugLoc.h" | #include "llvm/Support/DebugLoc.h" | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class Function; | class Function; | |||
class MachineFunction; | class MachineFunction; | |||
class OProfileWrapper; | class OProfileWrapper; | |||
class IntelJITEventsWrapper; | class IntelJITEventsWrapper; | |||
class ObjectImage; | class ObjectImage; | |||
/// JITEvent_EmittedFunctionDetails - Helper struct for containing informat ion | /// JITEvent_EmittedFunctionDetails - Helper struct for containing informat ion | |||
skipping to change at line 131 | skipping to change at line 130 | |||
static JITEventListener *createOProfileJITEventListener( | static JITEventListener *createOProfileJITEventListener( | |||
OProfileWrapper* AlternativeImpl) { | OProfileWrapper* AlternativeImpl) { | |||
return 0; | return 0; | |||
} | } | |||
#endif // USE_OPROFILE | #endif // USE_OPROFILE | |||
}; | }; | |||
} // end namespace llvm. | } // end namespace llvm. | |||
#endif // defined LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H | #endif // defined LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H | |||
End of changes. 4 change blocks. | ||||
4 lines changed or deleted | 3 lines changed or added | |||
JITMemoryManager.h | JITMemoryManager.h | |||
---|---|---|---|---|
//===-- JITMemoryManager.h - Interface JIT uses to Allocate Mem -*- C++ -*- ===// | //===-- JITMemoryManager.h - Interface JIT uses to Allocate Mem -*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H | #ifndef LLVM_EXECUTIONENGINE_JITMEMORYMANAGER_H | |||
#define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H | #define LLVM_EXECUTIONENGINE_JITMEMORYMANAGER_H | |||
#include "llvm/ExecutionEngine/RuntimeDyld.h" | #include "llvm/ExecutionEngine/RuntimeDyld.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class Function; | class Function; | |||
class GlobalValue; | class GlobalValue; | |||
/// JITMemoryManager - This interface is used by the JIT to allocate and ma nage | /// JITMemoryManager - This interface is used by the JIT to allocate and ma nage | |||
/// memory for the code generated by the JIT. This can be reimplemented by | /// memory for the code generated by the JIT. This can be reimplemented by | |||
/// clients that have a strong desire to control how the layout of JIT'd me mory | /// clients that have a strong desire to control how the layout of JIT'd me mory | |||
End of changes. 2 change blocks. | ||||
3 lines changed or deleted | 2 lines changed or added | |||
LEB128.h | LEB128.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares some utility functions for encoding SLEB128 and | // This file declares some utility functions for encoding SLEB128 and | |||
// ULEB128 values. | // ULEB128 values. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_LEB128_H | #ifndef LLVM_SUPPORT_LEB128_H | |||
#define LLVM_SYSTEM_LEB128_H | #define LLVM_SUPPORT_LEB128_H | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
namespace llvm { | namespace llvm { | |||
/// Utility function to encode a SLEB128 value to an output stream. | /// Utility function to encode a SLEB128 value to an output stream. | |||
static inline void encodeSLEB128(int64_t Value, raw_ostream &OS) { | static inline void encodeSLEB128(int64_t Value, raw_ostream &OS) { | |||
bool More; | bool More; | |||
do { | do { | |||
uint8_t Byte = Value & 0x7f; | uint8_t Byte = Value & 0x7f; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
LLVMBitCodes.h | LLVMBitCodes.h | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
namespace llvm { | namespace llvm { | |||
namespace bitc { | namespace bitc { | |||
// The only top-level block type defined is for a module. | // The only top-level block type defined is for a module. | |||
enum BlockIDs { | enum BlockIDs { | |||
// Blocks | // Blocks | |||
MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID, | MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID, | |||
// Module sub-block id's. | // Module sub-block id's. | |||
PARAMATTR_BLOCK_ID, | PARAMATTR_BLOCK_ID, | |||
PARAMATTR_GROUP_BLOCK_ID, | ||||
UNUSED_ID1, | ||||
CONSTANTS_BLOCK_ID, | CONSTANTS_BLOCK_ID, | |||
FUNCTION_BLOCK_ID, | FUNCTION_BLOCK_ID, | |||
UNUSED_ID2, | UNUSED_ID1, | |||
VALUE_SYMTAB_BLOCK_ID, | VALUE_SYMTAB_BLOCK_ID, | |||
METADATA_BLOCK_ID, | METADATA_BLOCK_ID, | |||
METADATA_ATTACHMENT_ID, | METADATA_ATTACHMENT_ID, | |||
TYPE_BLOCK_ID_NEW, | TYPE_BLOCK_ID_NEW, | |||
USELIST_BLOCK_ID | USELIST_BLOCK_ID | |||
}; | }; | |||
/// MODULE blocks have a number of optional fields and subblocks. | /// MODULE blocks have a number of optional fields and subblocks. | |||
enum ModuleCodes { | enum ModuleCodes { | |||
MODULE_CODE_VERSION = 1, // VERSION: [version#] | MODULE_CODE_VERSION = 1, // VERSION: [version#] | |||
MODULE_CODE_TRIPLE = 2, // TRIPLE: [strchr x N] | MODULE_CODE_TRIPLE = 2, // TRIPLE: [strchr x N] | |||
MODULE_CODE_DATALAYOUT = 3, // DATALAYOUT: [strchr x N] | MODULE_CODE_DATALAYOUT = 3, // DATALAYOUT: [strchr x N] | |||
MODULE_CODE_ASM = 4, // ASM: [strchr x N] | MODULE_CODE_ASM = 4, // ASM: [strchr x N] | |||
MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N] | MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N] | |||
// FIXME: Remove DEPLIB in 4.0. | ||||
MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N] | MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N] | |||
// GLOBALVAR: [pointer type, isconst, initid, | // GLOBALVAR: [pointer type, isconst, initid, | |||
// linkage, alignment, section, visibility, threadlocal] | // linkage, alignment, section, visibility, threadlocal] | |||
MODULE_CODE_GLOBALVAR = 7, | MODULE_CODE_GLOBALVAR = 7, | |||
// FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignme nt, | // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignme nt, | |||
// section, visibility, gc, unnamed_addr] | // section, visibility, gc, unnamed_addr] | |||
MODULE_CODE_FUNCTION = 8, | MODULE_CODE_FUNCTION = 8, | |||
// ALIAS: [alias type, aliasee val#, linkage, visibility] | // ALIAS: [alias type, aliasee val#, linkage, visibility] | |||
MODULE_CODE_ALIAS = 9, | MODULE_CODE_ALIAS = 9, | |||
/// MODULE_CODE_PURGEVALS: [numvals] | // MODULE_CODE_PURGEVALS: [numvals] | |||
MODULE_CODE_PURGEVALS = 10, | MODULE_CODE_PURGEVALS = 10, | |||
MODULE_CODE_GCNAME = 11 // GCNAME: [strchr x N] | MODULE_CODE_GCNAME = 11 // GCNAME: [strchr x N] | |||
}; | }; | |||
/// PARAMATTR blocks have code for defining a parameter attribute set. | /// PARAMATTR blocks have code for defining a parameter attribute set. | |||
enum AttributeCodes { | enum AttributeCodes { | |||
PARAMATTR_CODE_ENTRY = 1 // ENTRY: [paramidx0, attr0, paramidx1, attr | // FIXME: Remove `PARAMATTR_CODE_ENTRY_OLD' in 4.0 | |||
1...] | PARAMATTR_CODE_ENTRY_OLD = 1, // ENTRY: [paramidx0, attr0, | |||
// paramidx1, attr1...] | ||||
PARAMATTR_CODE_ENTRY = 2, // ENTRY: [paramidx0, attrgrp0, | ||||
// paramidx1, attrgrp1, ...] | ||||
PARAMATTR_GRP_CODE_ENTRY = 3 // ENTRY: [id, attr0, att1, ...] | ||||
}; | }; | |||
/// TYPE blocks have codes for each type primitive they use. | /// TYPE blocks have codes for each type primitive they use. | |||
enum TypeCodes { | enum TypeCodes { | |||
TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries] | TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries] | |||
// Type Codes | // Type Codes | |||
TYPE_CODE_VOID = 2, // VOID | TYPE_CODE_VOID = 2, // VOID | |||
TYPE_CODE_FLOAT = 3, // FLOAT | TYPE_CODE_FLOAT = 3, // FLOAT | |||
TYPE_CODE_DOUBLE = 4, // DOUBLE | TYPE_CODE_DOUBLE = 4, // DOUBLE | |||
skipping to change at line 143 | skipping to change at line 149 | |||
// 3 is unused. | // 3 is unused. | |||
METADATA_NAME = 4, // STRING: [values] | METADATA_NAME = 4, // STRING: [values] | |||
// 5 is unused. | // 5 is unused. | |||
METADATA_KIND = 6, // [n x [id, name]] | METADATA_KIND = 6, // [n x [id, name]] | |||
// 7 is unused. | // 7 is unused. | |||
METADATA_NODE = 8, // NODE: [n x (type num, value n um)] | METADATA_NODE = 8, // NODE: [n x (type num, value n um)] | |||
METADATA_FN_NODE = 9, // FN_NODE: [n x (type num, value n um)] | METADATA_FN_NODE = 9, // FN_NODE: [n x (type num, value n um)] | |||
METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes] | METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes] | |||
METADATA_ATTACHMENT = 11 // [m x [value, [n x [id, mdnode]]] | METADATA_ATTACHMENT = 11 // [m x [value, [n x [id, mdnode]]] | |||
}; | }; | |||
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each | // The constants block (CONSTANTS_BLOCK_ID) describes emission for each | |||
// constant and maintains an implicit current type value. | // constant and maintains an implicit current type value. | |||
enum ConstantsCodes { | enum ConstantsCodes { | |||
CST_CODE_SETTYPE = 1, // SETTYPE: [typeid] | CST_CODE_SETTYPE = 1, // SETTYPE: [typeid] | |||
CST_CODE_NULL = 2, // NULL | CST_CODE_NULL = 2, // NULL | |||
CST_CODE_UNDEF = 3, // UNDEF | CST_CODE_UNDEF = 3, // UNDEF | |||
CST_CODE_INTEGER = 4, // INTEGER: [intval] | CST_CODE_INTEGER = 4, // INTEGER: [intval] | |||
CST_CODE_WIDE_INTEGER = 5, // WIDE_INTEGER: [n x intval] | CST_CODE_WIDE_INTEGER = 5, // WIDE_INTEGER: [n x intval] | |||
CST_CODE_FLOAT = 6, // FLOAT: [fpval] | CST_CODE_FLOAT = 6, // FLOAT: [fpval] | |||
CST_CODE_AGGREGATE = 7, // AGGREGATE: [n x value number] | CST_CODE_AGGREGATE = 7, // AGGREGATE: [n x value number] | |||
End of changes. 6 change blocks. | ||||
6 lines changed or deleted | 12 lines changed or added | |||
LLVMContext.h | LLVMContext.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares LLVMContext, a container of "global" state in LLVM, s uch | // This file declares LLVMContext, a container of "global" state in LLVM, s uch | |||
// as the global type and constant uniquing tables. | // as the global type and constant uniquing tables. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_LLVMCONTEXT_H | #ifndef LLVM_IR_LLVMCONTEXT_H | |||
#define LLVM_LLVMCONTEXT_H | #define LLVM_IR_LLVMCONTEXT_H | |||
#include "llvm/Support/CBindingWrapping.h" | ||||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm-c/Core.h" | ||||
namespace llvm { | namespace llvm { | |||
class LLVMContextImpl; | class LLVMContextImpl; | |||
class StringRef; | class StringRef; | |||
class Twine; | class Twine; | |||
class Instruction; | class Instruction; | |||
class Module; | class Module; | |||
class SMDiagnostic; | class SMDiagnostic; | |||
template <typename T> class SmallVectorImpl; | template <typename T> class SmallVectorImpl; | |||
skipping to change at line 49 | skipping to change at line 51 | |||
~LLVMContext(); | ~LLVMContext(); | |||
// Pinned metadata names, which always have the same value. This is a | // Pinned metadata names, which always have the same value. This is a | |||
// compile-time performance optimization, not a correctness optimization. | // compile-time performance optimization, not a correctness optimization. | |||
enum { | enum { | |||
MD_dbg = 0, // "dbg" | MD_dbg = 0, // "dbg" | |||
MD_tbaa = 1, // "tbaa" | MD_tbaa = 1, // "tbaa" | |||
MD_prof = 2, // "prof" | MD_prof = 2, // "prof" | |||
MD_fpmath = 3, // "fpmath" | MD_fpmath = 3, // "fpmath" | |||
MD_range = 4, // "range" | MD_range = 4, // "range" | |||
MD_tbaa_struct = 5 // "tbaa.struct" | MD_tbaa_struct = 5, // "tbaa.struct" | |||
MD_invariant_load = 6 // "invariant.load" | ||||
}; | }; | |||
/// getMDKindID - Return a unique non-zero ID for the specified metadata kind. | /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. | |||
/// This ID is uniqued across modules in the current LLVMContext. | /// This ID is uniqued across modules in the current LLVMContext. | |||
unsigned getMDKindID(StringRef Name) const; | unsigned getMDKindID(StringRef Name) const; | |||
/// getMDKindNames - Populate client supplied SmallVector with the name f or | /// getMDKindNames - Populate client supplied SmallVector with the name f or | |||
/// custom metadata IDs registered in this LLVMContext. | /// custom metadata IDs registered in this LLVMContext. | |||
void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; | void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; | |||
skipping to change at line 109 | skipping to change at line 112 | |||
void removeModule(Module*); | void removeModule(Module*); | |||
// Module needs access to the add/removeModule methods. | // Module needs access to the add/removeModule methods. | |||
friend class Module; | friend class Module; | |||
}; | }; | |||
/// getGlobalContext - Returns a global context. This is for LLVM clients that | /// getGlobalContext - Returns a global context. This is for LLVM clients that | |||
/// only care about operating on a single thread. | /// only care about operating on a single thread. | |||
extern LLVMContext &getGlobalContext(); | extern LLVMContext &getGlobalContext(); | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef) | ||||
/* Specialized opaque context conversions. | ||||
*/ | ||||
inline LLVMContext **unwrap(LLVMContextRef* Tys) { | ||||
return reinterpret_cast<LLVMContext**>(Tys); | ||||
} | ||||
inline LLVMContextRef *wrap(const LLVMContext **Tys) { | ||||
return reinterpret_cast<LLVMContextRef*>(const_cast<LLVMContext**>(Tys)); | ||||
} | ||||
} | } | |||
#endif | #endif | |||
End of changes. 5 change blocks. | ||||
3 lines changed or deleted | 19 lines changed or added | |||
LatencyPriorityQueue.h | LatencyPriorityQueue.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the LatencyPriorityQueue class, which is a | // This file declares the LatencyPriorityQueue class, which is a | |||
// SchedulingPriorityQueue that schedules using latency information to | // SchedulingPriorityQueue that schedules using latency information to | |||
// reduce the length of the critical path through the basic block. | // reduce the length of the critical path through the basic block. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LATENCY_PRIORITY_QUEUE_H | #ifndef LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H | |||
#define LATENCY_PRIORITY_QUEUE_H | #define LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H | |||
#include "llvm/CodeGen/ScheduleDAG.h" | #include "llvm/CodeGen/ScheduleDAG.h" | |||
namespace llvm { | namespace llvm { | |||
class LatencyPriorityQueue; | class LatencyPriorityQueue; | |||
/// Sorting functions for the Available queue. | /// Sorting functions for the Available queue. | |||
struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> { | struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> { | |||
LatencyPriorityQueue *PQ; | LatencyPriorityQueue *PQ; | |||
explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {} | explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {} | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
LexicalScopes.h | LexicalScopes.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file implements LexicalScopes analysis. | // This file implements LexicalScopes analysis. | |||
// | // | |||
// This pass collects lexical scope information and maps machine instructio ns | // This pass collects lexical scope information and maps machine instructio ns | |||
// to respective lexical scopes. | // to respective lexical scopes. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_LEXICALSCOPES_H | #ifndef LLVM_CODEGEN_LEXICALSCOPES_H | |||
#define LLVM_CODEGEN_LEXICALSCOPES_H | #define LLVM_CODEGEN_LEXICALSCOPES_H | |||
#include "llvm/Metadata.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/IR/Metadata.h" | ||||
#include "llvm/Support/DebugLoc.h" | #include "llvm/Support/DebugLoc.h" | |||
#include "llvm/Support/ValueHandle.h" | #include "llvm/Support/ValueHandle.h" | |||
#include <utility> | #include <utility> | |||
namespace llvm { | namespace llvm { | |||
class MachineInstr; | class MachineInstr; | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
class MachineFunction; | class MachineFunction; | |||
class LexicalScope; | class LexicalScope; | |||
skipping to change at line 162 | skipping to change at line 162 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// LexicalScope - This class is used to track scope information. | /// LexicalScope - This class is used to track scope information. | |||
/// | /// | |||
class LexicalScope { | class LexicalScope { | |||
virtual void anchor(); | virtual void anchor(); | |||
public: | public: | |||
LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A) | LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A) | |||
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A), | : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A), | |||
LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0) { | LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0) { | |||
#ifndef NDEBUG | ||||
IndentLevel = 0; | ||||
#endif | ||||
if (Parent) | if (Parent) | |||
Parent->addChild(this); | Parent->addChild(this); | |||
} | } | |||
virtual ~LexicalScope() {} | virtual ~LexicalScope() {} | |||
// Accessors. | // Accessors. | |||
LexicalScope *getParent() const { return Parent; } | LexicalScope *getParent() const { return Parent; } | |||
const MDNode *getDesc() const { return Desc; } | const MDNode *getDesc() const { return Desc; } | |||
const MDNode *getInlinedAt() const { return InlinedAtLocation; } | const MDNode *getInlinedAt() const { return InlinedAtLocation; } | |||
skipping to change at line 231 | skipping to change at line 228 | |||
return false; | return false; | |||
} | } | |||
// Depth First Search support to walk and manipulate LexicalScope hierarc hy. | // Depth First Search support to walk and manipulate LexicalScope hierarc hy. | |||
unsigned getDFSOut() const { return DFSOut; } | unsigned getDFSOut() const { return DFSOut; } | |||
void setDFSOut(unsigned O) { DFSOut = O; } | void setDFSOut(unsigned O) { DFSOut = O; } | |||
unsigned getDFSIn() const { return DFSIn; } | unsigned getDFSIn() const { return DFSIn; } | |||
void setDFSIn(unsigned I) { DFSIn = I; } | void setDFSIn(unsigned I) { DFSIn = I; } | |||
/// dump - print lexical scope. | /// dump - print lexical scope. | |||
void dump() const; | void dump(unsigned Indent = 0) const; | |||
private: | private: | |||
LexicalScope *Parent; // Parent to this scope. | LexicalScope *Parent; // Parent to this scope. | |||
AssertingVH<const MDNode> Desc; // Debug info descriptor. | AssertingVH<const MDNode> Desc; // Debug info descriptor. | |||
AssertingVH<const MDNode> InlinedAtLocation; // Location at which this | AssertingVH<const MDNode> InlinedAtLocation; // Location at which this | |||
// scope is inlined. | // scope is inlined. | |||
bool AbstractScope; // Abstract Scope | bool AbstractScope; // Abstract Scope | |||
SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope . | SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope . | |||
// Contents not owned. | // Contents not owned. | |||
SmallVector<InsnRange, 4> Ranges; | SmallVector<InsnRange, 4> Ranges; | |||
const MachineInstr *LastInsn; // Last instruction of this scope. | const MachineInstr *LastInsn; // Last instruction of this scope. | |||
const MachineInstr *FirstInsn; // First instruction of this scope. | const MachineInstr *FirstInsn; // First instruction of this scope. | |||
unsigned DFSIn, DFSOut; // In & Out Depth use to determine | unsigned DFSIn, DFSOut; // In & Out Depth use to determine | |||
// scope nesting. | // scope nesting. | |||
#ifndef NDEBUG | ||||
mutable unsigned IndentLevel; // Private state for dump() | ||||
#endif | ||||
}; | }; | |||
} // end llvm namespace | } // end llvm namespace | |||
#endif | #endif | |||
End of changes. 5 change blocks. | ||||
8 lines changed or deleted | 2 lines changed or added | |||
LibCallAliasAnalysis.h | LibCallAliasAnalysis.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the LibCallAliasAnalysis class. | // This file defines the LibCallAliasAnalysis class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_LIBCALL_AA_H | #ifndef LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H | |||
#define LLVM_ANALYSIS_LIBCALL_AA_H | #define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H | |||
#include "llvm/Analysis/AliasAnalysis.h" | #include "llvm/Analysis/AliasAnalysis.h" | |||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
namespace llvm { | namespace llvm { | |||
class LibCallInfo; | class LibCallInfo; | |||
struct LibCallFunctionInfo; | struct LibCallFunctionInfo; | |||
/// LibCallAliasAnalysis - Alias analysis driven from LibCallInfo. | /// LibCallAliasAnalysis - Alias analysis driven from LibCallInfo. | |||
struct LibCallAliasAnalysis : public FunctionPass, public AliasAnalysis { | struct LibCallAliasAnalysis : public FunctionPass, public AliasAnalysis { | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
LinkAllAsmWriterComponents.h | LinkAllAsmWriterComponents.h | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
struct ForceAsmWriterLinking { | struct ForceAsmWriterLinking { | |||
ForceAsmWriterLinking() { | ForceAsmWriterLinking() { | |||
// We must reference the plug-ins in such a way that compilers will n ot | // We must reference the plug-ins in such a way that compilers will n ot | |||
// delete it all as dead code, even with whole program optimization, | // delete it all as dead code, even with whole program optimization, | |||
// yet is effectively a NO-OP. As the compiler isn't smart enough | // yet is effectively a NO-OP. As the compiler isn't smart enough | |||
// to know that getenv() never returns -1, this will do the job. | // to know that getenv() never returns -1, this will do the job. | |||
if (std::getenv("bar") != (char*) -1) | if (std::getenv("bar") != (char*) -1) | |||
return; | return; | |||
llvm::linkOcamlGCPrinter(); | llvm::linkOcamlGCPrinter(); | |||
llvm::linkErlangGCPrinter(); | ||||
} | } | |||
} ForceAsmWriterLinking; // Force link by creating a global definition. | } ForceAsmWriterLinking; // Force link by creating a global definition. | |||
} | } | |||
#endif // LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H | #endif // LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 1 lines changed or added | |||
LinkAllCodegenComponents.h | LinkAllCodegenComponents.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This header file pulls in all codegen related passes for tools like lli and | // This header file pulls in all codegen related passes for tools like lli and | |||
// llc that need this functionality. | // llc that need this functionality. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H | #ifndef LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H | |||
#define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H | #define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H | |||
#include "llvm/CodeGen/GCs.h" | ||||
#include "llvm/CodeGen/Passes.h" | #include "llvm/CodeGen/Passes.h" | |||
#include "llvm/CodeGen/SchedulerRegistry.h" | #include "llvm/CodeGen/SchedulerRegistry.h" | |||
#include "llvm/CodeGen/GCs.h" | ||||
#include "llvm/Target/TargetMachine.h" | #include "llvm/Target/TargetMachine.h" | |||
#include <cstdlib> | #include <cstdlib> | |||
namespace { | namespace { | |||
struct ForceCodegenLinking { | struct ForceCodegenLinking { | |||
ForceCodegenLinking() { | ForceCodegenLinking() { | |||
// We must reference the passes in such a way that compilers will not | // We must reference the passes in such a way that compilers will not | |||
// delete it all as dead code, even with whole program optimization, | // delete it all as dead code, even with whole program optimization, | |||
// yet is effectively a NO-OP. As the compiler isn't smart enough | // yet is effectively a NO-OP. As the compiler isn't smart enough | |||
// to know that getenv() never returns -1, this will do the job. | // to know that getenv() never returns -1, this will do the job. | |||
if (std::getenv("bar") != (char*) -1) | if (std::getenv("bar") != (char*) -1) | |||
return; | return; | |||
(void) llvm::createFastRegisterAllocator(); | (void) llvm::createFastRegisterAllocator(); | |||
(void) llvm::createBasicRegisterAllocator(); | (void) llvm::createBasicRegisterAllocator(); | |||
(void) llvm::createGreedyRegisterAllocator(); | (void) llvm::createGreedyRegisterAllocator(); | |||
(void) llvm::createDefaultPBQPRegisterAllocator(); | (void) llvm::createDefaultPBQPRegisterAllocator(); | |||
llvm::linkOcamlGC(); | llvm::linkOcamlGC(); | |||
llvm::linkErlangGC(); | ||||
llvm::linkShadowStackGC(); | llvm::linkShadowStackGC(); | |||
(void) llvm::createBURRListDAGScheduler(NULL, llvm::CodeGenOpt::Defau lt); | (void) llvm::createBURRListDAGScheduler(NULL, llvm::CodeGenOpt::Defau lt); | |||
(void) llvm::createSourceListDAGScheduler(NULL,llvm::CodeGenOpt::Defa ult); | (void) llvm::createSourceListDAGScheduler(NULL,llvm::CodeGenOpt::Defa ult); | |||
(void) llvm::createHybridListDAGScheduler(NULL,llvm::CodeGenOpt::Defa ult); | (void) llvm::createHybridListDAGScheduler(NULL,llvm::CodeGenOpt::Defa ult); | |||
(void) llvm::createFastDAGScheduler(NULL, llvm::CodeGenOpt::Default); | (void) llvm::createFastDAGScheduler(NULL, llvm::CodeGenOpt::Default); | |||
(void) llvm::createDefaultScheduler(NULL, llvm::CodeGenOpt::Default); | (void) llvm::createDefaultScheduler(NULL, llvm::CodeGenOpt::Default); | |||
(void) llvm::createVLIWDAGScheduler(NULL, llvm::CodeGenOpt::Default); | (void) llvm::createVLIWDAGScheduler(NULL, llvm::CodeGenOpt::Default); | |||
} | } | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 2 lines changed or added | |||
LinkAllPasses.h | LinkAllPasses.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This header file pulls in all transformation and analysis passes for too ls | // This header file pulls in all transformation and analysis passes for too ls | |||
// like opt and bugpoint that need this functionality. | // like opt and bugpoint that need this functionality. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_LINKALLPASSES_H | #ifndef LLVM_LINKALLPASSES_H | |||
#define LLVM_LINKALLPASSES_H | #define LLVM_LINKALLPASSES_H | |||
#include "llvm/Analysis/AliasSetTracker.h" | #include "llvm/Analysis/AliasSetTracker.h" | |||
#include "llvm/Analysis/CallPrinter.h" | ||||
#include "llvm/Analysis/DomPrinter.h" | #include "llvm/Analysis/DomPrinter.h" | |||
#include "llvm/Analysis/FindUsedTypes.h" | #include "llvm/Analysis/FindUsedTypes.h" | |||
#include "llvm/Analysis/IntervalPartition.h" | #include "llvm/Analysis/IntervalPartition.h" | |||
#include "llvm/Analysis/Lint.h" | ||||
#include "llvm/Analysis/Passes.h" | #include "llvm/Analysis/Passes.h" | |||
#include "llvm/Analysis/PostDominators.h" | #include "llvm/Analysis/PostDominators.h" | |||
#include "llvm/Analysis/RegionPass.h" | #include "llvm/Analysis/RegionPass.h" | |||
#include "llvm/Analysis/RegionPrinter.h" | #include "llvm/Analysis/RegionPrinter.h" | |||
#include "llvm/Analysis/ScalarEvolution.h" | #include "llvm/Analysis/ScalarEvolution.h" | |||
#include "llvm/Analysis/Lint.h" | ||||
#include "llvm/Assembly/PrintModulePass.h" | #include "llvm/Assembly/PrintModulePass.h" | |||
#include "llvm/CodeGen/Passes.h" | #include "llvm/CodeGen/Passes.h" | |||
#include "llvm/Function.h" | #include "llvm/IR/Function.h" | |||
#include "llvm/Transforms/Instrumentation.h" | ||||
#include "llvm/Transforms/IPO.h" | #include "llvm/Transforms/IPO.h" | |||
#include "llvm/Transforms/Instrumentation.h" | ||||
#include "llvm/Transforms/ObjCARC.h" | ||||
#include "llvm/Transforms/Scalar.h" | #include "llvm/Transforms/Scalar.h" | |||
#include "llvm/Transforms/Vectorize.h" | ||||
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" | #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" | |||
#include "llvm/Transforms/Vectorize.h" | ||||
#include <cstdlib> | #include <cstdlib> | |||
namespace { | namespace { | |||
struct ForcePassLinking { | struct ForcePassLinking { | |||
ForcePassLinking() { | ForcePassLinking() { | |||
// We must reference the passes in such a way that compilers will not | // We must reference the passes in such a way that compilers will not | |||
// delete it all as dead code, even with whole program optimization, | // delete it all as dead code, even with whole program optimization, | |||
// yet is effectively a NO-OP. As the compiler isn't smart enough | // yet is effectively a NO-OP. As the compiler isn't smart enough | |||
// to know that getenv() never returns -1, this will do the job. | // to know that getenv() never returns -1, this will do the job. | |||
if (std::getenv("bar") != (char*) -1) | if (std::getenv("bar") != (char*) -1) | |||
skipping to change at line 60 | skipping to change at line 62 | |||
(void) llvm::createAliasAnalysisCounterPass(); | (void) llvm::createAliasAnalysisCounterPass(); | |||
(void) llvm::createAliasDebugger(); | (void) llvm::createAliasDebugger(); | |||
(void) llvm::createArgumentPromotionPass(); | (void) llvm::createArgumentPromotionPass(); | |||
(void) llvm::createBasicAliasAnalysisPass(); | (void) llvm::createBasicAliasAnalysisPass(); | |||
(void) llvm::createLibCallAliasAnalysisPass(0); | (void) llvm::createLibCallAliasAnalysisPass(0); | |||
(void) llvm::createScalarEvolutionAliasAnalysisPass(); | (void) llvm::createScalarEvolutionAliasAnalysisPass(); | |||
(void) llvm::createTypeBasedAliasAnalysisPass(); | (void) llvm::createTypeBasedAliasAnalysisPass(); | |||
(void) llvm::createBlockPlacementPass(); | (void) llvm::createBlockPlacementPass(); | |||
(void) llvm::createBoundsCheckingPass(); | (void) llvm::createBoundsCheckingPass(); | |||
(void) llvm::createBreakCriticalEdgesPass(); | (void) llvm::createBreakCriticalEdgesPass(); | |||
(void) llvm::createCallGraphPrinterPass(); | ||||
(void) llvm::createCallGraphViewerPass(); | ||||
(void) llvm::createCFGSimplificationPass(); | (void) llvm::createCFGSimplificationPass(); | |||
(void) llvm::createConstantMergePass(); | (void) llvm::createConstantMergePass(); | |||
(void) llvm::createConstantPropagationPass(); | (void) llvm::createConstantPropagationPass(); | |||
(void) llvm::createCostModelAnalysisPass(); | (void) llvm::createCostModelAnalysisPass(); | |||
(void) llvm::createDeadArgEliminationPass(); | (void) llvm::createDeadArgEliminationPass(); | |||
(void) llvm::createDeadCodeEliminationPass(); | (void) llvm::createDeadCodeEliminationPass(); | |||
(void) llvm::createDeadInstEliminationPass(); | (void) llvm::createDeadInstEliminationPass(); | |||
(void) llvm::createDeadStoreEliminationPass(); | (void) llvm::createDeadStoreEliminationPass(); | |||
(void) llvm::createDependenceAnalysisPass(); | (void) llvm::createDependenceAnalysisPass(); | |||
(void) llvm::createDomOnlyPrinterPass(); | (void) llvm::createDomOnlyPrinterPass(); | |||
skipping to change at line 150 | skipping to change at line 154 | |||
(void) llvm::createGVNPass(); | (void) llvm::createGVNPass(); | |||
(void) llvm::createMemCpyOptPass(); | (void) llvm::createMemCpyOptPass(); | |||
(void) llvm::createLoopDeletionPass(); | (void) llvm::createLoopDeletionPass(); | |||
(void) llvm::createPostDomTree(); | (void) llvm::createPostDomTree(); | |||
(void) llvm::createInstructionNamerPass(); | (void) llvm::createInstructionNamerPass(); | |||
(void) llvm::createMetaRenamerPass(); | (void) llvm::createMetaRenamerPass(); | |||
(void) llvm::createFunctionAttrsPass(); | (void) llvm::createFunctionAttrsPass(); | |||
(void) llvm::createMergeFunctionsPass(); | (void) llvm::createMergeFunctionsPass(); | |||
(void) llvm::createPrintModulePass(0); | (void) llvm::createPrintModulePass(0); | |||
(void) llvm::createPrintFunctionPass("", 0); | (void) llvm::createPrintFunctionPass("", 0); | |||
(void) llvm::createDbgInfoPrinterPass(); | (void) llvm::createPrintBasicBlockPass(0); | |||
(void) llvm::createModuleDebugInfoPrinterPass(); | (void) llvm::createModuleDebugInfoPrinterPass(); | |||
(void) llvm::createPartialInliningPass(); | (void) llvm::createPartialInliningPass(); | |||
(void) llvm::createLintPass(); | (void) llvm::createLintPass(); | |||
(void) llvm::createSinkingPass(); | (void) llvm::createSinkingPass(); | |||
(void) llvm::createLowerAtomicPass(); | (void) llvm::createLowerAtomicPass(); | |||
(void) llvm::createCorrelatedValuePropagationPass(); | (void) llvm::createCorrelatedValuePropagationPass(); | |||
(void) llvm::createMemDepPrinter(); | (void) llvm::createMemDepPrinter(); | |||
(void) llvm::createInstructionSimplifierPass(); | (void) llvm::createInstructionSimplifierPass(); | |||
(void) llvm::createLoopVectorizePass(); | (void) llvm::createLoopVectorizePass(); | |||
(void) llvm::createSLPVectorizerPass(); | ||||
(void) llvm::createBBVectorizePass(); | (void) llvm::createBBVectorizePass(); | |||
(void)new llvm::IntervalPartition(); | (void)new llvm::IntervalPartition(); | |||
(void)new llvm::FindUsedTypes(); | (void)new llvm::FindUsedTypes(); | |||
(void)new llvm::ScalarEvolution(); | (void)new llvm::ScalarEvolution(); | |||
((llvm::Function*)0)->viewCFGOnly(); | ((llvm::Function*)0)->viewCFGOnly(); | |||
llvm::RGPassManager RGM; | llvm::RGPassManager RGM; | |||
((llvm::RegionPass*)0)->runOnRegion((llvm::Region*)0, RGM); | ((llvm::RegionPass*)0)->runOnRegion((llvm::Region*)0, RGM); | |||
llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)0); | llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)0); | |||
X.add((llvm::Value*)0, 0, 0); // for -print-alias-sets | X.add((llvm::Value*)0, 0, 0); // for -print-alias-sets | |||
End of changes. 10 change blocks. | ||||
5 lines changed or deleted | 10 lines changed or added | |||
LinkTimeOptimizer.h | LinkTimeOptimizer.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This header provides a C API to use the LLVM link time optimization | // This header provides a C API to use the LLVM link time optimization | |||
// library. This is intended to be used by linkers which are C-only in | // library. This is intended to be used by linkers which are C-only in | |||
// their implementation for performing LTO. | // their implementation for performing LTO. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef __LTO_CAPI_H__ | #ifndef LLVM_C_LINKTIMEOPTIMIZER_H | |||
#define __LTO_CAPI_H__ | #define LLVM_C_LINKTIMEOPTIMIZER_H | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
extern "C" { | extern "C" { | |||
#endif | #endif | |||
/** | /** | |||
* @defgroup LLVMCLinkTimeOptimizer Link Time Optimization | * @defgroup LLVMCLinkTimeOptimizer Link Time Optimization | |||
* @ingroup LLVMC | * @ingroup LLVMC | |||
* | * | |||
* @{ | * @{ | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Linker.h | Linker.h | |||
---|---|---|---|---|
//===- llvm/Linker.h - Module Linker Interface ------------------*- C++ -*- ===// | //===- llvm/Linker.h - Module Linker Interface ------------------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | ||||
// This file defines the interface to the module/file/archive linker. | ||||
// | ||||
//===---------------------------------------------------------------------- | ||||
===// | ||||
#ifndef LLVM_LINKER_H | #ifndef LLVM_LINKER_H | |||
#define LLVM_LINKER_H | #define LLVM_LINKER_H | |||
#include <memory> | #include "llvm/ADT/SmallPtrSet.h" | |||
#include <string> | #include <string> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
namespace sys { class Path; } | ||||
class Module; | class Module; | |||
class LLVMContext; | ||||
class StringRef; | class StringRef; | |||
class StructType; | ||||
/// This class provides the core functionality of linking in LLVM. It retai | /// This class provides the core functionality of linking in LLVM. It keeps | |||
ns a | a | |||
/// Module object which is the composite of the modules and libraries linke | /// pointer to the merged module so far. It doesn't take ownership of the | |||
d | /// module since it is assumed that the user of this class will want to do | |||
/// into it. The composite Module can be retrieved via the getModule() meth | /// something with it after the linking. | |||
od. | ||||
/// In this case the Linker still retains ownership of the Module. If the | ||||
/// releaseModule() method is used, the ownership of the Module is transfer | ||||
red | ||||
/// to the caller and the Linker object is only suitable for destruction. | ||||
/// The Linker can link Modules from memory, bitcode files, or bitcode | ||||
/// archives. It retains a set of search paths in which to find any librar | ||||
ies | ||||
/// presented to it. By default, the linker will generate error and warning | ||||
/// messages to stderr but this capability can be turned off with the | ||||
/// QuietWarnings and QuietErrors flags. It can also be instructed to verbo | ||||
sely | ||||
/// print out the linking actions it is taking with the Verbose flag. | ||||
/// @brief The LLVM Linker. | ||||
class Linker { | class Linker { | |||
/// @name Types | ||||
/// @{ | ||||
public: | public: | |||
/// This type is used to pass the linkage items (libraries and files) t | ||||
o | ||||
/// the LinkItems function. It is composed of string/bool pairs. The st | ||||
ring | ||||
/// provides the name of the file or library (as with the -l option). T | ||||
he | ||||
/// bool should be true for libraries and false for files, signifying | ||||
/// "isLibrary". | ||||
/// @brief A list of linkage items | ||||
typedef std::vector<std::pair<std::string,bool> > ItemList; | ||||
/// This enumeration is used to control various optional features of th | ||||
e | ||||
/// linker. | ||||
enum ControlFlags { | ||||
Verbose = 1, ///< Print to stderr what steps the linker is taki | ||||
ng | ||||
QuietWarnings = 2, ///< Don't print warnings to stderr. | ||||
QuietErrors = 4 ///< Don't print errors to stderr. | ||||
}; | ||||
enum LinkerMode { | enum LinkerMode { | |||
DestroySource = 0, // Allow source module to be destroyed. | DestroySource = 0, // Allow source module to be destroyed. | |||
PreserveSource = 1 // Preserve the source module. | PreserveSource = 1 // Preserve the source module. | |||
}; | }; | |||
/// @} | Linker(Module *M); | |||
/// @name Constructors | ||||
/// @{ | ||||
public: | ||||
/// Construct the Linker with an empty module which will be given the | ||||
/// name \p progname. \p progname will also be used for error messages. | ||||
/// @brief Construct with empty module | ||||
Linker(StringRef progname, ///< name of tool running linker | ||||
StringRef modulename, ///< name of linker's end-result module | ||||
LLVMContext &C, ///< Context for global info | ||||
unsigned Flags = 0 ///< ControlFlags (one or more |'d together) | ||||
); | ||||
/// Construct the Linker with a previously defined module, \p aModule. | ||||
Use | ||||
/// \p progname for the name of the program in error messages. | ||||
/// @brief Construct with existing module | ||||
Linker(StringRef progname, Module* aModule, unsigned Flags = 0); | ||||
/// Destruct the Linker. | ||||
/// @brief Destructor | ||||
~Linker(); | ~Linker(); | |||
Module *getModule() const { return Composite; } | ||||
/// @} | /// \brief Link \p Src into the composite. The source is destroyed if | |||
/// @name Accessors | /// \p Mode is DestroySource and preserved if it is PreserveSource. | |||
/// @{ | /// If \p ErrorMsg is not null, information about any error is written | |||
public: | /// to it. | |||
/// This method gets the composite module into which linking is being | /// Returns true on error. | |||
/// done. The Composite module starts out empty and accumulates modules | bool linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg); | |||
/// linked into it via the various LinkIn* methods. This method does no | bool linkInModule(Module *Src, std::string *ErrorMsg) { | |||
t | return linkInModule(Src, Linker::DestroySource, ErrorMsg); | |||
/// release the Module to the caller. The Linker retains ownership and | ||||
will | ||||
/// destruct the Module when the Linker is destructed. | ||||
/// @see releaseModule | ||||
/// @brief Get the linked/composite module. | ||||
Module* getModule() const { return Composite; } | ||||
/// This method releases the composite Module into which linking is bei | ||||
ng | ||||
/// done. Ownership of the composite Module is transferred to the calle | ||||
r who | ||||
/// must arrange for its destruct. After this method is called, the Lin | ||||
ker | ||||
/// terminates the linking session for the returned Module. It will no | ||||
/// longer utilize the returned Module but instead resets itself for | ||||
/// subsequent linking as if the constructor had been called. The Linke | ||||
r's | ||||
/// LibPaths and flags to be reset, and memory will be released. | ||||
/// @brief Release the linked/composite module. | ||||
Module* releaseModule(); | ||||
/// This method gets the list of libraries that form the path that the | ||||
/// Linker will search when it is presented with a library name. | ||||
/// @brief Get the Linkers library path | ||||
const std::vector<sys::Path>& getLibPaths() const { return LibPaths; } | ||||
/// This method returns an error string suitable for printing to the us | ||||
er. | ||||
/// The return value will be empty unless an error occurred in one of t | ||||
he | ||||
/// LinkIn* methods. In those cases, the LinkIn* methods will have retu | ||||
rned | ||||
/// true, indicating an error occurred. At most one error is retained s | ||||
o | ||||
/// this function always returns the last error that occurred. Note tha | ||||
t if | ||||
/// the Quiet control flag is not set, the error string will have alrea | ||||
dy | ||||
/// been printed to stderr. | ||||
/// @brief Get the text of the last error that occurred. | ||||
const std::string &getLastError() const { return Error; } | ||||
/// @} | ||||
/// @name Mutators | ||||
/// @{ | ||||
public: | ||||
/// Add a path to the list of paths that the Linker will search. The Li | ||||
nker | ||||
/// accumulates the set of libraries added | ||||
/// library paths for the target platform. The standard libraries will | ||||
/// always be searched last. The added libraries will be searched in th | ||||
e | ||||
/// order added. | ||||
/// @brief Add a path. | ||||
void addPath(const sys::Path& path); | ||||
/// Add a set of paths to the list of paths that the linker will search | ||||
. The | ||||
/// Linker accumulates the set of libraries added. The \p paths will be | ||||
/// added to the end of the Linker's list. Order will be retained. | ||||
/// @brief Add a set of paths. | ||||
void addPaths(const std::vector<std::string>& paths); | ||||
/// This method augments the Linker's list of library paths with the sy | ||||
stem | ||||
/// paths of the host operating system, include LLVM_LIB_SEARCH_PATH. | ||||
/// @brief Add the system paths. | ||||
void addSystemPaths(); | ||||
/// Control optional linker behavior by setting a group of flags. The f | ||||
lags | ||||
/// are defined in the ControlFlags enumeration. | ||||
/// @see ControlFlags | ||||
/// @brief Set control flags. | ||||
void setFlags(unsigned flags) { Flags = flags; } | ||||
/// This method is the main interface to the linker. It can be used to | ||||
/// link a set of linkage items into a module. A linkage item is either | ||||
a | ||||
/// file name with fully qualified path, or a library for which the Lin | ||||
ker's | ||||
/// LibraryPath will be utilized to locate the library. The bool value | ||||
in | ||||
/// the LinkItemKind should be set to true for libraries. This functio | ||||
n | ||||
/// allows linking to preserve the order of specification associated wi | ||||
th | ||||
/// the command line, or for other purposes. Each item will be linked i | ||||
n | ||||
/// turn as it occurs in \p Items. | ||||
/// @returns true if an error occurred, false otherwise | ||||
/// @see LinkItemKind | ||||
/// @see getLastError | ||||
bool LinkInItems ( | ||||
const ItemList& Items, ///< Set of libraries/files to link in | ||||
ItemList& NativeItems ///< Output list of native files/libs | ||||
); | ||||
/// This function links the bitcode \p Files into the composite module. | ||||
/// Note that this does not do any linking of unresolved symbols. The \ | ||||
p | ||||
/// Files are all completely linked into \p HeadModule regardless of | ||||
/// unresolved symbols. This function just loads each bitcode file and | ||||
/// calls LinkInModule on them. | ||||
/// @returns true if an error occurs, false otherwise | ||||
/// @see getLastError | ||||
/// @brief Link in multiple files. | ||||
bool LinkInFiles ( | ||||
const std::vector<sys::Path> & Files ///< Files to link in | ||||
); | ||||
/// This function links a single bitcode file, \p File, into the compos | ||||
ite | ||||
/// module. Note that this does not attempt to resolve symbols. This me | ||||
thod | ||||
/// just loads the bitcode file and calls LinkInModule on it. If an err | ||||
or | ||||
/// occurs, the Linker's error string is set. | ||||
/// @returns true if an error occurs, false otherwise | ||||
/// @see getLastError | ||||
/// @brief Link in a single file. | ||||
bool LinkInFile( | ||||
const sys::Path& File, ///< File to link in. | ||||
bool &is_native ///< Indicates if the file is native object fi | ||||
le | ||||
); | ||||
/// This function provides a way to selectively link in a set of module | ||||
s, | ||||
/// found in libraries, based on the unresolved symbols in the composit | ||||
e | ||||
/// module. Each item in \p Libraries should be the base name of a libr | ||||
ary, | ||||
/// as if given with the -l option of a linker tool. The Linker's LibP | ||||
aths | ||||
/// are searched for the \p Libraries and any found will be linked in w | ||||
ith | ||||
/// LinkInArchive. If an error occurs, the Linker's error string is se | ||||
t. | ||||
/// @see LinkInArchive | ||||
/// @see getLastError | ||||
/// @returns true if an error occurs, false otherwise | ||||
/// @brief Link libraries into the module | ||||
bool LinkInLibraries ( | ||||
const std::vector<std::string> & Libraries ///< Libraries to link in | ||||
); | ||||
/// This function provides a way to selectively link in a set of module | ||||
s, | ||||
/// found in one library, based on the unresolved symbols in the compos | ||||
ite | ||||
/// module.The \p Library should be the base name of a library, as if g | ||||
iven | ||||
/// with the -l option of a linker tool. The Linker's LibPaths are sear | ||||
ched | ||||
/// for the \p Library and if found, it will be linked in with via the | ||||
/// LinkInArchive method. If an error occurs, the Linker's error string | ||||
is | ||||
/// set. | ||||
/// @see LinkInArchive | ||||
/// @see getLastError | ||||
/// @returns true if an error occurs, false otherwise | ||||
/// @brief Link one library into the module | ||||
bool LinkInLibrary ( | ||||
StringRef Library, ///< The library to link in | ||||
bool& is_native ///< Indicates if lib a native library | ||||
); | ||||
/// This function links one bitcode archive, \p Filename, into the modu | ||||
le. | ||||
/// The archive is searched to resolve outstanding symbols. Any modules | ||||
in | ||||
/// the archive that resolve outstanding symbols will be linked in. The | ||||
/// library is searched repeatedly until no more modules that resolve | ||||
/// symbols can be found. If an error occurs, the error string is set. | ||||
/// To speed up this function, ensure the archive has been processed | ||||
/// llvm-ranlib or the S option was given to llvm-ar when the archive w | ||||
as | ||||
/// created. These tools add a symbol table to the archive which makes | ||||
the | ||||
/// search for undefined symbols much faster. | ||||
/// @see getLastError | ||||
/// @returns true if an error occurs, otherwise false. | ||||
/// @brief Link in one archive. | ||||
bool LinkInArchive( | ||||
const sys::Path& Filename, ///< Filename of the archive to link | ||||
bool& is_native ///< Indicates if archive is a native arc | ||||
hive | ||||
); | ||||
/// This method links the \p Src module into the Linker's Composite mod | ||||
ule | ||||
/// by calling LinkModules. All the other LinkIn* methods eventually | ||||
/// result in calling this method to link a Module into the Linker's | ||||
/// composite. | ||||
/// @see LinkModules | ||||
/// @returns True if an error occurs, false otherwise. | ||||
/// @brief Link in a module. | ||||
bool LinkInModule( | ||||
Module* Src, ///< Module linked into \p Dest | ||||
std::string* ErrorMsg = 0 /// Error/diagnostic string | ||||
) { | ||||
return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg ); | ||||
} | } | |||
/// This is the heart of the linker. This method will take unconditiona | static bool LinkModules(Module *Dest, Module *Src, unsigned Mode, | |||
l | std::string *ErrorMsg); | |||
/// control of the \p Src module and link it into the \p Dest module. T | ||||
he | ||||
/// \p Src module will be destructed or subsumed by this method. In eit | ||||
her | ||||
/// case it is not usable by the caller after this method is invoked. O | ||||
nly | ||||
/// the \p Dest module will remain. The \p Src module is linked into th | ||||
e | ||||
/// Linker's composite module such that types, global variables, functi | ||||
ons, | ||||
/// and etc. are matched and resolved. If an error occurs, this functi | ||||
on | ||||
/// returns true and ErrorMsg is set to a descriptive message about the | ||||
/// error. | ||||
/// @returns True if an error occurs, false otherwise. | ||||
/// @brief Generically link two modules together. | ||||
static bool LinkModules(Module* Dest, Module* Src, unsigned Mode, | ||||
std::string* ErrorMsg); | ||||
/// This function looks through the Linker's LibPaths to find a library | ||||
with | ||||
/// the name \p Filename. If the library cannot be found, the returned | ||||
path | ||||
/// will be empty (i.e. sys::Path::isEmpty() will return true). | ||||
/// @returns A sys::Path to the found library | ||||
/// @brief Find a library from its short name. | ||||
sys::Path FindLib(StringRef Filename); | ||||
/// @} | ||||
/// @name Implementation | ||||
/// @{ | ||||
private: | ||||
/// Read in and parse the bitcode file named by FN and return the | ||||
/// Module it contains (wrapped in an auto_ptr), or 0 if an error occur | ||||
s. | ||||
std::auto_ptr<Module> LoadObject(const sys::Path& FN); | ||||
bool warning(StringRef message); | ||||
bool error(StringRef message); | ||||
void verbose(StringRef message); | ||||
/// @} | ||||
/// @name Data | ||||
/// @{ | ||||
private: | ||||
LLVMContext& Context; ///< The context for global information | ||||
Module* Composite; ///< The composite module linked together | ||||
std::vector<sys::Path> LibPaths; ///< The library search paths | ||||
unsigned Flags; ///< Flags to control optional behavior. | ||||
std::string Error; ///< Text of error that occurred. | ||||
std::string ProgramName; ///< Name of the program being linked | ||||
/// @} | ||||
private: | ||||
Module *Composite; | ||||
SmallPtrSet<StructType*, 32> IdentifiedStructTypes; | ||||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 14 change blocks. | ||||
338 lines changed or deleted | 22 lines changed or added | |||
LiveInterval.h | LiveInterval.h | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each | // i.e. an interval might look like [1,20), [50,65), [1000,1001). Each | |||
// individual range is represented as an instance of LiveRange, and the who le | // individual range is represented as an instance of LiveRange, and the who le | |||
// interval is represented as an instance of LiveInterval. | // interval is represented as an instance of LiveInterval. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_LIVEINTERVAL_H | #ifndef LLVM_CODEGEN_LIVEINTERVAL_H | |||
#define LLVM_CODEGEN_LIVEINTERVAL_H | #define LLVM_CODEGEN_LIVEINTERVAL_H | |||
#include "llvm/ADT/IntEqClasses.h" | #include "llvm/ADT/IntEqClasses.h" | |||
#include "llvm/Support/Allocator.h" | ||||
#include "llvm/Support/AlignOf.h" | ||||
#include "llvm/CodeGen/SlotIndexes.h" | #include "llvm/CodeGen/SlotIndexes.h" | |||
#include "llvm/Support/AlignOf.h" | ||||
#include "llvm/Support/Allocator.h" | ||||
#include <cassert> | #include <cassert> | |||
#include <climits> | #include <climits> | |||
namespace llvm { | namespace llvm { | |||
class CoalescerPair; | class CoalescerPair; | |||
class LiveIntervals; | class LiveIntervals; | |||
class MachineInstr; | class MachineInstr; | |||
class MachineRegisterInfo; | class MachineRegisterInfo; | |||
class TargetRegisterInfo; | class TargetRegisterInfo; | |||
class raw_ostream; | class raw_ostream; | |||
skipping to change at line 89 | skipping to change at line 89 | |||
}; | }; | |||
/// LiveRange structure - This represents a simple register range in the | /// LiveRange structure - This represents a simple register range in the | |||
/// program, with an inclusive start point and an exclusive end point. | /// program, with an inclusive start point and an exclusive end point. | |||
/// These ranges are rendered as [start,end). | /// These ranges are rendered as [start,end). | |||
struct LiveRange { | struct LiveRange { | |||
SlotIndex start; // Start point of the interval (inclusive) | SlotIndex start; // Start point of the interval (inclusive) | |||
SlotIndex end; // End point of the interval (exclusive) | SlotIndex end; // End point of the interval (exclusive) | |||
VNInfo *valno; // identifier for the value contained in this interval . | VNInfo *valno; // identifier for the value contained in this interval . | |||
LiveRange() : valno(0) {} | ||||
LiveRange(SlotIndex S, SlotIndex E, VNInfo *V) | LiveRange(SlotIndex S, SlotIndex E, VNInfo *V) | |||
: start(S), end(E), valno(V) { | : start(S), end(E), valno(V) { | |||
assert(S < E && "Cannot create empty or backwards range"); | assert(S < E && "Cannot create empty or backwards range"); | |||
} | } | |||
/// contains - Return true if the index is covered by this range. | /// contains - Return true if the index is covered by this range. | |||
/// | /// | |||
bool contains(SlotIndex I) const { | bool contains(SlotIndex I) const { | |||
return start <= I && I < end; | return start <= I && I < end; | |||
} | } | |||
/// containsRange - Return true if the given range, [S, E), is covered by | /// containsRange - Return true if the given range, [S, E), is covered by | |||
skipping to change at line 375 | skipping to change at line 376 | |||
bool overlaps(SlotIndex Start, SlotIndex End) const; | bool overlaps(SlotIndex Start, SlotIndex End) const; | |||
/// overlapsFrom - Return true if the intersection of the two live inte rvals | /// overlapsFrom - Return true if the intersection of the two live inte rvals | |||
/// is not empty. The specified iterator is a hint that we can begin | /// is not empty. The specified iterator is a hint that we can begin | |||
/// scanning the Other interval starting at I. | /// scanning the Other interval starting at I. | |||
bool overlapsFrom(const LiveInterval& other, const_iterator I) const; | bool overlapsFrom(const LiveInterval& other, const_iterator I) const; | |||
/// addRange - Add the specified LiveRange to this interval, merging | /// addRange - Add the specified LiveRange to this interval, merging | |||
/// intervals as appropriate. This returns an iterator to the inserted live | /// intervals as appropriate. This returns an iterator to the inserted live | |||
/// range (which may have grown since it was inserted. | /// range (which may have grown since it was inserted. | |||
void addRange(LiveRange LR) { | iterator addRange(LiveRange LR) { | |||
addRangeFrom(LR, ranges.begin()); | return addRangeFrom(LR, ranges.begin()); | |||
} | } | |||
/// extendInBlock - If this interval is live before Kill in the basic b lock | /// extendInBlock - If this interval is live before Kill in the basic b lock | |||
/// that starts at StartIdx, extend it to be live up to Kill, and retur n | /// that starts at StartIdx, extend it to be live up to Kill, and retur n | |||
/// the value. If there is no live range before Kill, return NULL. | /// the value. If there is no live range before Kill, return NULL. | |||
VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Kill); | VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Kill); | |||
/// join - Join two live intervals (this, and other) together. This ap plies | /// join - Join two live intervals (this, and other) together. This ap plies | |||
/// mappings to the value numbers in the LHS/RHS intervals as specified . If | /// mappings to the value numbers in the LHS/RHS intervals as specified . If | |||
/// the intervals are not joinable, this aborts. | /// the intervals are not joinable, this aborts. | |||
skipping to change at line 400 | skipping to change at line 401 | |||
SmallVector<VNInfo*, 16> &NewVNInfo, | SmallVector<VNInfo*, 16> &NewVNInfo, | |||
MachineRegisterInfo *MRI); | MachineRegisterInfo *MRI); | |||
/// isInOneLiveRange - Return true if the range specified is entirely i n the | /// isInOneLiveRange - Return true if the range specified is entirely i n the | |||
/// a single LiveRange of the live interval. | /// a single LiveRange of the live interval. | |||
bool isInOneLiveRange(SlotIndex Start, SlotIndex End) const { | bool isInOneLiveRange(SlotIndex Start, SlotIndex End) const { | |||
const_iterator r = find(Start); | const_iterator r = find(Start); | |||
return r != end() && r->containsRange(Start, End); | return r != end() && r->containsRange(Start, End); | |||
} | } | |||
/// True iff this live range is a single segment that lies between the | ||||
/// specified boundaries, exclusively. Vregs live across a backedge are | ||||
not | ||||
/// considered local. The boundaries are expected to lie within an exte | ||||
nded | ||||
/// basic block, so vregs that are not live out should contain no holes | ||||
. | ||||
bool isLocal(SlotIndex Start, SlotIndex End) const { | ||||
return beginIndex() > Start.getBaseIndex() && | ||||
endIndex() < End.getBoundaryIndex(); | ||||
} | ||||
/// removeRange - Remove the specified range from this interval. Note that | /// removeRange - Remove the specified range from this interval. Note that | |||
/// the range must be a single LiveRange in its entirety. | /// the range must be a single LiveRange in its entirety. | |||
void removeRange(SlotIndex Start, SlotIndex End, | void removeRange(SlotIndex Start, SlotIndex End, | |||
bool RemoveDeadValNo = false); | bool RemoveDeadValNo = false); | |||
void removeRange(LiveRange LR, bool RemoveDeadValNo = false) { | void removeRange(LiveRange LR, bool RemoveDeadValNo = false) { | |||
removeRange(LR.start, LR.end, RemoveDeadValNo); | removeRange(LR.start, LR.end, RemoveDeadValNo); | |||
} | } | |||
/// removeValNo - Remove all the ranges defined by the specified value# . | /// removeValNo - Remove all the ranges defined by the specified value# . | |||
skipping to change at line 462 | skipping to change at line 472 | |||
#else | #else | |||
void verify() const; | void verify() const; | |||
#endif | #endif | |||
private: | private: | |||
Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From); | Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From); | |||
void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd); | void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd); | |||
Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex Ne wStr); | Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex Ne wStr); | |||
void markValNoForDeletion(VNInfo *V); | void markValNoForDeletion(VNInfo *V); | |||
void mergeIntervalRanges(const LiveInterval &RHS, | ||||
VNInfo *LHSValNo = 0, | ||||
const VNInfo *RHSValNo = 0); | ||||
LiveInterval& operator=(const LiveInterval& rhs) LLVM_DELETED_FUNCTION; | LiveInterval& operator=(const LiveInterval& rhs) LLVM_DELETED_FUNCTION; | |||
}; | }; | |||
inline raw_ostream &operator<<(raw_ostream &OS, const LiveInterval &LI) { | inline raw_ostream &operator<<(raw_ostream &OS, const LiveInterval &LI) { | |||
LI.print(OS); | LI.print(OS); | |||
return OS; | return OS; | |||
} | } | |||
/// Helper class for performant LiveInterval bulk updates. | ||||
/// | ||||
/// Calling LiveInterval::addRange() repeatedly can be expensive on large | ||||
/// live ranges because segments after the insertion point may need to be | ||||
/// shifted. The LiveRangeUpdater class can defer the shifting when addin | ||||
g | ||||
/// many segments in order. | ||||
/// | ||||
/// The LiveInterval will be in an invalid state until flush() is called. | ||||
class LiveRangeUpdater { | ||||
LiveInterval *LI; | ||||
SlotIndex LastStart; | ||||
LiveInterval::iterator WriteI; | ||||
LiveInterval::iterator ReadI; | ||||
SmallVector<LiveRange, 16> Spills; | ||||
void mergeSpills(); | ||||
public: | ||||
/// Create a LiveRangeUpdater for adding segments to LI. | ||||
/// LI will temporarily be in an invalid state until flush() is called. | ||||
LiveRangeUpdater(LiveInterval *li = 0) : LI(li) {} | ||||
~LiveRangeUpdater() { flush(); } | ||||
/// Add a segment to LI and coalesce when possible, just like LI.addRan | ||||
ge(). | ||||
/// Segments should be added in increasing start order for best perform | ||||
ance. | ||||
void add(LiveRange); | ||||
void add(SlotIndex Start, SlotIndex End, VNInfo *VNI) { | ||||
add(LiveRange(Start, End, VNI)); | ||||
} | ||||
/// Return true if the LI is currently in an invalid state, and flush() | ||||
/// needs to be called. | ||||
bool isDirty() const { return LastStart.isValid(); } | ||||
/// Flush the updater state to LI so it is valid and contains all added | ||||
/// segments. | ||||
void flush(); | ||||
/// Select a different destination live range. | ||||
void setDest(LiveInterval *li) { | ||||
if (LI != li && isDirty()) | ||||
flush(); | ||||
LI = li; | ||||
} | ||||
/// Get the current destination live range. | ||||
LiveInterval *getDest() const { return LI; } | ||||
void dump() const; | ||||
void print(raw_ostream&) const; | ||||
}; | ||||
inline raw_ostream &operator<<(raw_ostream &OS, const LiveRangeUpdater &X | ||||
) { | ||||
X.print(OS); | ||||
return OS; | ||||
} | ||||
/// LiveRangeQuery - Query information about a live range around a given | /// LiveRangeQuery - Query information about a live range around a given | |||
/// instruction. This class hides the implementation details of live rang es, | /// instruction. This class hides the implementation details of live rang es, | |||
/// and it should be used as the primary interface for examining live ran ges | /// and it should be used as the primary interface for examining live ran ges | |||
/// around instructions. | /// around instructions. | |||
/// | /// | |||
class LiveRangeQuery { | class LiveRangeQuery { | |||
VNInfo *EarlyVal; | VNInfo *EarlyVal; | |||
VNInfo *LateVal; | VNInfo *LateVal; | |||
SlotIndex EndPoint; | SlotIndex EndPoint; | |||
bool Kill; | bool Kill; | |||
End of changes. 8 change blocks. | ||||
8 lines changed or deleted | 80 lines changed or added | |||
LiveIntervalAnalysis.h | LiveIntervalAnalysis.h | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// instruction with number j' > j such that v is live at j' and there is no | // instruction with number j' > j such that v is live at j' and there is no | |||
// instruction with number i' < i such that v is live at i'. In this | // instruction with number i' < i such that v is live at i'. In this | |||
// implementation intervals can have holes, i.e. an interval might look lik e | // implementation intervals can have holes, i.e. an interval might look lik e | |||
// [1,20), [50,65), [1000,1001). | // [1,20), [50,65), [1000,1001). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H | #ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H | |||
#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H | #define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H | |||
#include "llvm/Target/TargetRegisterInfo.h" | #include "llvm/ADT/IndexedMap.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/CodeGen/LiveInterval.h" | ||||
#include "llvm/CodeGen/MachineBasicBlock.h" | #include "llvm/CodeGen/MachineBasicBlock.h" | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | #include "llvm/CodeGen/MachineFunctionPass.h" | |||
#include "llvm/CodeGen/LiveInterval.h" | ||||
#include "llvm/CodeGen/SlotIndexes.h" | #include "llvm/CodeGen/SlotIndexes.h" | |||
#include "llvm/ADT/BitVector.h" | ||||
#include "llvm/ADT/IndexedMap.h" | ||||
#include "llvm/ADT/SmallPtrSet.h" | ||||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/Support/Allocator.h" | #include "llvm/Support/Allocator.h" | |||
#include "llvm/Target/TargetRegisterInfo.h" | ||||
#include <cmath> | #include <cmath> | |||
#include <iterator> | #include <iterator> | |||
namespace llvm { | namespace llvm { | |||
class AliasAnalysis; | class AliasAnalysis; | |||
class BitVector; | ||||
class LiveRangeCalc; | class LiveRangeCalc; | |||
class LiveVariables; | class LiveVariables; | |||
class MachineDominatorTree; | class MachineDominatorTree; | |||
class MachineLoopInfo; | class MachineLoopInfo; | |||
class TargetRegisterInfo; | class TargetRegisterInfo; | |||
class MachineRegisterInfo; | class MachineRegisterInfo; | |||
class TargetInstrInfo; | class TargetInstrInfo; | |||
class TargetRegisterClass; | class TargetRegisterClass; | |||
class VirtRegMap; | class VirtRegMap; | |||
class LiveIntervals : public MachineFunctionPass { | class LiveIntervals : public MachineFunctionPass { | |||
MachineFunction* MF; | MachineFunction* MF; | |||
MachineRegisterInfo* MRI; | MachineRegisterInfo* MRI; | |||
const TargetMachine* TM; | const TargetMachine* TM; | |||
const TargetRegisterInfo* TRI; | const TargetRegisterInfo* TRI; | |||
const TargetInstrInfo* TII; | const TargetInstrInfo* TII; | |||
AliasAnalysis *AA; | AliasAnalysis *AA; | |||
LiveVariables* LV; | ||||
SlotIndexes* Indexes; | SlotIndexes* Indexes; | |||
MachineDominatorTree *DomTree; | MachineDominatorTree *DomTree; | |||
LiveRangeCalc *LRCalc; | LiveRangeCalc *LRCalc; | |||
/// Special pool allocator for VNInfo's (LiveInterval val#). | /// Special pool allocator for VNInfo's (LiveInterval val#). | |||
/// | /// | |||
VNInfo::Allocator VNInfoAllocator; | VNInfo::Allocator VNInfoAllocator; | |||
/// Live interval pointers for all the virtual registers. | /// Live interval pointers for all the virtual registers. | |||
IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals; | IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals; | |||
skipping to change at line 218 | skipping to change at line 216 | |||
bool isLiveOutOfMBB(const LiveInterval &li, | bool isLiveOutOfMBB(const LiveInterval &li, | |||
const MachineBasicBlock *mbb) const { | const MachineBasicBlock *mbb) const { | |||
return li.liveAt(getMBBEndIdx(mbb).getPrevSlot()); | return li.liveAt(getMBBEndIdx(mbb).getPrevSlot()); | |||
} | } | |||
MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { | MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { | |||
return Indexes->getMBBFromIndex(index); | return Indexes->getMBBFromIndex(index); | |||
} | } | |||
void insertMBBInMaps(MachineBasicBlock *MBB) { | ||||
Indexes->insertMBBInMaps(MBB); | ||||
assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() && | ||||
"Blocks must be added in order."); | ||||
RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0)); | ||||
} | ||||
SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) { | SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) { | |||
return Indexes->insertMachineInstrInMaps(MI); | return Indexes->insertMachineInstrInMaps(MI); | |||
} | } | |||
void RemoveMachineInstrFromMaps(MachineInstr *MI) { | void RemoveMachineInstrFromMaps(MachineInstr *MI) { | |||
Indexes->removeMachineInstrFromMaps(MI); | Indexes->removeMachineInstrFromMaps(MI); | |||
} | } | |||
void ReplaceMachineInstrInMaps(MachineInstr *MI, MachineInstr *NewMI) { | void ReplaceMachineInstrInMaps(MachineInstr *MI, MachineInstr *NewMI) { | |||
Indexes->replaceMachineInstrInMaps(MI, NewMI); | Indexes->replaceMachineInstrInMaps(MI, NewMI); | |||
skipping to change at line 278 | skipping to change at line 283 | |||
/// begin/end on the SlotIndex for BundleStart. | /// begin/end on the SlotIndex for BundleStart. | |||
/// | /// | |||
/// \param UpdateFlags Update live intervals for nonallocatable physreg s. | /// \param UpdateFlags Update live intervals for nonallocatable physreg s. | |||
/// | /// | |||
/// Requires MI and BundleStart to have SlotIndexes, and assumes | /// Requires MI and BundleStart to have SlotIndexes, and assumes | |||
/// existing liveness is accurate. BundleStart should be the first | /// existing liveness is accurate. BundleStart should be the first | |||
/// instruction in the Bundle. | /// instruction in the Bundle. | |||
void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart, | void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart, | |||
bool UpdateFlags = false); | bool UpdateFlags = false); | |||
/// repairIntervalsInRange - Update live intervals for instructions in | ||||
a | ||||
/// range of iterators. It is intended for use after target hooks that | ||||
may | ||||
/// insert or remove instructions, and is only efficient for a small nu | ||||
mber | ||||
/// of instructions. | ||||
/// | ||||
/// OrigRegs is a vector of registers that were originally used by the | ||||
/// instructions in the range between the two iterators. | ||||
/// | ||||
/// Currently, the only only changes that are supported are simple remo | ||||
val | ||||
/// and addition of uses. | ||||
void repairIntervalsInRange(MachineBasicBlock *MBB, | ||||
MachineBasicBlock::iterator Begin, | ||||
MachineBasicBlock::iterator End, | ||||
ArrayRef<unsigned> OrigRegs); | ||||
// Register mask functions. | // Register mask functions. | |||
// | // | |||
// Machine instructions may use a register mask operand to indicate tha t a | // Machine instructions may use a register mask operand to indicate tha t a | |||
// large number of registers are clobbered by the instruction. This is | // large number of registers are clobbered by the instruction. This is | |||
// typically used for calls. | // typically used for calls. | |||
// | // | |||
// For compile time performance reasons, these clobbers are not recorde d in | // For compile time performance reasons, these clobbers are not recorde d in | |||
// the live intervals for individual physical registers. Instead, | // the live intervals for individual physical registers. Instead, | |||
// LiveIntervalAnalysis maintains a sorted list of instructions with | // LiveIntervalAnalysis maintains a sorted list of instructions with | |||
// register mask operands. | // register mask operands. | |||
skipping to change at line 350 | skipping to change at line 370 | |||
} | } | |||
return *LI; | return *LI; | |||
} | } | |||
/// getCachedRegUnit - Return the live range for Unit if it has already | /// getCachedRegUnit - Return the live range for Unit if it has already | |||
/// been computed, or NULL if it hasn't been computed yet. | /// been computed, or NULL if it hasn't been computed yet. | |||
LiveInterval *getCachedRegUnit(unsigned Unit) { | LiveInterval *getCachedRegUnit(unsigned Unit) { | |||
return RegUnitIntervals[Unit]; | return RegUnitIntervals[Unit]; | |||
} | } | |||
private: | const LiveInterval *getCachedRegUnit(unsigned Unit) const { | |||
/// computeIntervals - Compute live intervals. | return RegUnitIntervals[Unit]; | |||
void computeIntervals(); | } | |||
private: | ||||
/// Compute live intervals for all virtual registers. | /// Compute live intervals for all virtual registers. | |||
void computeVirtRegs(); | void computeVirtRegs(); | |||
/// Compute RegMaskSlots and RegMaskBits. | /// Compute RegMaskSlots and RegMaskBits. | |||
void computeRegMasks(); | void computeRegMasks(); | |||
/// handleRegisterDef - update intervals for a register def | ||||
/// (calls handleVirtualRegisterDef) | ||||
void handleRegisterDef(MachineBasicBlock *MBB, | ||||
MachineBasicBlock::iterator MI, | ||||
SlotIndex MIIdx, | ||||
MachineOperand& MO, unsigned MOIdx); | ||||
/// isPartialRedef - Return true if the specified def at the specific i | ||||
ndex | ||||
/// is partially re-defining the specified live interval. A common case | ||||
of | ||||
/// this is a definition of the sub-register. | ||||
bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO, | ||||
LiveInterval &interval); | ||||
/// handleVirtualRegisterDef - update intervals for a virtual | ||||
/// register def | ||||
void handleVirtualRegisterDef(MachineBasicBlock *MBB, | ||||
MachineBasicBlock::iterator MI, | ||||
SlotIndex MIIdx, MachineOperand& MO, | ||||
unsigned MOIdx, | ||||
LiveInterval& interval); | ||||
static LiveInterval* createInterval(unsigned Reg); | static LiveInterval* createInterval(unsigned Reg); | |||
void printInstrs(raw_ostream &O) const; | void printInstrs(raw_ostream &O) const; | |||
void dumpInstrs() const; | void dumpInstrs() const; | |||
void computeLiveInRegUnits(); | void computeLiveInRegUnits(); | |||
void computeRegUnitInterval(LiveInterval*); | void computeRegUnitInterval(LiveInterval*); | |||
void computeVirtRegInterval(LiveInterval*); | void computeVirtRegInterval(LiveInterval*); | |||
class HMEditor; | class HMEditor; | |||
End of changes. 11 change blocks. | ||||
33 lines changed or deleted | 35 lines changed or added | |||
LiveRangeEdit.h | LiveRangeEdit.h | |||
---|---|---|---|---|
skipping to change at line 86 | skipping to change at line 86 | |||
/// Rematted - Values that were actually rematted, and so need to have th eir | /// Rematted - Values that were actually rematted, and so need to have th eir | |||
/// live range trimmed or entirely removed. | /// live range trimmed or entirely removed. | |||
SmallPtrSet<const VNInfo*,4> Rematted; | SmallPtrSet<const VNInfo*,4> Rematted; | |||
/// scanRemattable - Identify the Parent values that may rematerialize. | /// scanRemattable - Identify the Parent values that may rematerialize. | |||
void scanRemattable(AliasAnalysis *aa); | void scanRemattable(AliasAnalysis *aa); | |||
/// allUsesAvailableAt - Return true if all registers used by OrigMI at | /// allUsesAvailableAt - Return true if all registers used by OrigMI at | |||
/// OrigIdx are also available with the same value at UseIdx. | /// OrigIdx are also available with the same value at UseIdx. | |||
bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, | bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, | |||
SlotIndex UseIdx); | SlotIndex UseIdx) const; | |||
/// foldAsLoad - If LI has a single use and a single def that can be fold ed as | /// foldAsLoad - If LI has a single use and a single def that can be fold ed as | |||
/// a load, eliminate the register by folding the def into the use. | /// a load, eliminate the register by folding the def into the use. | |||
bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead); | bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead); | |||
public: | public: | |||
/// Create a LiveRangeEdit for breaking down parent into smaller pieces. | /// Create a LiveRangeEdit for breaking down parent into smaller pieces. | |||
/// @param parent The register being spilled or split. | /// @param parent The register being spilled or split. | |||
/// @param newRegs List to receive any new registers created. This needn' t be | /// @param newRegs List to receive any new registers created. This needn' t be | |||
/// empty initially, any existing registers are ignored. | /// empty initially, any existing registers are ignored. | |||
skipping to change at line 199 | skipping to change at line 199 | |||
/// to erase it from LIS. | /// to erase it from LIS. | |||
void eraseVirtReg(unsigned Reg); | void eraseVirtReg(unsigned Reg); | |||
/// eliminateDeadDefs - Try to delete machine instructions that are now d ead | /// eliminateDeadDefs - Try to delete machine instructions that are now d ead | |||
/// (allDefsAreDead returns true). This may cause live intervals to be tr immed | /// (allDefsAreDead returns true). This may cause live intervals to be tr immed | |||
/// and further dead efs to be eliminated. | /// and further dead efs to be eliminated. | |||
/// RegsBeingSpilled lists registers currently being spilled by the regis ter | /// RegsBeingSpilled lists registers currently being spilled by the regis ter | |||
/// allocator. These registers should not be split into new intervals | /// allocator. These registers should not be split into new intervals | |||
/// as currently those new intervals are not guaranteed to spill. | /// as currently those new intervals are not guaranteed to spill. | |||
void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead, | void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead, | |||
ArrayRef<unsigned> RegsBeingSpilled | ArrayRef<unsigned> RegsBeingSpilled = None); | |||
= ArrayRef<unsigned>()); | ||||
/// calculateRegClassAndHint - Recompute register class and hint for each new | /// calculateRegClassAndHint - Recompute register class and hint for each new | |||
/// register. | /// register. | |||
void calculateRegClassAndHint(MachineFunction&, | void calculateRegClassAndHint(MachineFunction&, | |||
const MachineLoopInfo&); | const MachineLoopInfo&); | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
3 lines changed or deleted | 2 lines changed or added | |||
LiveStackAnalysis.h | LiveStackAnalysis.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements the live stack slot analysis pass. It is analogous to | // This file implements the live stack slot analysis pass. It is analogous to | |||
// live interval analysis except it's analyzing liveness of stack slots rat her | // live interval analysis except it's analyzing liveness of stack slots rat her | |||
// than registers. | // than registers. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_LIVESTACK_ANALYSIS_H | #ifndef LLVM_CODEGEN_LIVESTACKANALYSIS_H | |||
#define LLVM_CODEGEN_LIVESTACK_ANALYSIS_H | #define LLVM_CODEGEN_LIVESTACKANALYSIS_H | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | ||||
#include "llvm/CodeGen/LiveInterval.h" | #include "llvm/CodeGen/LiveInterval.h" | |||
#include "llvm/Target/TargetRegisterInfo.h" | #include "llvm/CodeGen/MachineFunctionPass.h" | |||
#include "llvm/Support/Allocator.h" | #include "llvm/Support/Allocator.h" | |||
#include "llvm/Target/TargetRegisterInfo.h" | ||||
#include <map> | #include <map> | |||
namespace llvm { | namespace llvm { | |||
class LiveStacks : public MachineFunctionPass { | class LiveStacks : public MachineFunctionPass { | |||
const TargetRegisterInfo *TRI; | const TargetRegisterInfo *TRI; | |||
/// Special pool allocator for VNInfo's (LiveInterval val#). | /// Special pool allocator for VNInfo's (LiveInterval val#). | |||
/// | /// | |||
VNInfo::Allocator VNInfoAllocator; | VNInfo::Allocator VNInfoAllocator; | |||
End of changes. 4 change blocks. | ||||
4 lines changed or deleted | 4 lines changed or added | |||
LiveVariables.h | LiveVariables.h | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
// live within a single basic block (allowing it to do a single local analy sis | // live within a single basic block (allowing it to do a single local analy sis | |||
// to resolve physical register lifetimes in each basic block). If a physi cal | // to resolve physical register lifetimes in each basic block). If a physi cal | |||
// register is not register allocatable, it is not tracked. This is useful for | // register is not register allocatable, it is not tracked. This is useful for | |||
// things like the stack pointer and condition codes. | // things like the stack pointer and condition codes. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_LIVEVARIABLES_H | #ifndef LLVM_CODEGEN_LIVEVARIABLES_H | |||
#define LLVM_CODEGEN_LIVEVARIABLES_H | #define LLVM_CODEGEN_LIVEVARIABLES_H | |||
#include "llvm/CodeGen/MachineBasicBlock.h" | ||||
#include "llvm/CodeGen/MachineFunctionPass.h" | ||||
#include "llvm/CodeGen/MachineInstr.h" | ||||
#include "llvm/Target/TargetRegisterInfo.h" | ||||
#include "llvm/ADT/BitVector.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/IndexedMap.h" | #include "llvm/ADT/IndexedMap.h" | |||
#include "llvm/ADT/SmallSet.h" | #include "llvm/ADT/SmallSet.h" | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/SparseBitVector.h" | #include "llvm/ADT/SparseBitVector.h" | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | ||||
#include "llvm/CodeGen/MachineInstr.h" | ||||
#include "llvm/Target/TargetRegisterInfo.h" | ||||
namespace llvm { | namespace llvm { | |||
class MachineBasicBlock; | ||||
class MachineRegisterInfo; | class MachineRegisterInfo; | |||
class TargetRegisterInfo; | ||||
class LiveVariables : public MachineFunctionPass { | class LiveVariables : public MachineFunctionPass { | |||
public: | public: | |||
static char ID; // Pass identification, replacement for typeid | static char ID; // Pass identification, replacement for typeid | |||
LiveVariables() : MachineFunctionPass(ID) { | LiveVariables() : MachineFunctionPass(ID) { | |||
initializeLiveVariablesPass(*PassRegistry::getPassRegistry()); | initializeLiveVariablesPass(*PassRegistry::getPassRegistry()); | |||
} | } | |||
/// VarInfo - This represents the regions where a virtual register is liv e in | /// VarInfo - This represents the regions where a virtual register is liv e in | |||
/// the program. We represent this with three different pieces of | /// the program. We represent this with three different pieces of | |||
End of changes. 4 change blocks. | ||||
6 lines changed or deleted | 4 lines changed or added | |||
Loads.h | Loads.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares simple local analyses for load instructions. | // This file declares simple local analyses for load instructions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_LOADS_H | #ifndef LLVM_ANALYSIS_LOADS_H | |||
#define LLVM_ANALYSIS_LOADS_H | #define LLVM_ANALYSIS_LOADS_H | |||
#include "llvm/BasicBlock.h" | #include "llvm/IR/BasicBlock.h" | |||
namespace llvm { | namespace llvm { | |||
class AliasAnalysis; | class AliasAnalysis; | |||
class DataLayout; | class DataLayout; | |||
class MDNode; | class MDNode; | |||
/// isSafeToLoadUnconditionally - Return true if we know that executing a l oad | /// isSafeToLoadUnconditionally - Return true if we know that executing a l oad | |||
/// from this value cannot trap. If it is not obviously safe to load from the | /// from this value cannot trap. If it is not obviously safe to load from the | |||
/// specified pointer, we do a quick local scan of the basic block containi ng | /// specified pointer, we do a quick local scan of the basic block containi ng | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Local.h | Local.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This family of functions perform various local transformations to the | // This family of functions perform various local transformations to the | |||
// program. | // program. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H | #ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H | |||
#define LLVM_TRANSFORMS_UTILS_LOCAL_H | #define LLVM_TRANSFORMS_UTILS_LOCAL_H | |||
#include "llvm/IRBuilder.h" | #include "llvm/IR/DataLayout.h" | |||
#include "llvm/Operator.h" | #include "llvm/IR/IRBuilder.h" | |||
#include "llvm/IR/Operator.h" | ||||
#include "llvm/Support/GetElementPtrTypeIterator.h" | #include "llvm/Support/GetElementPtrTypeIterator.h" | |||
#include "llvm/DataLayout.h" | ||||
namespace llvm { | namespace llvm { | |||
class User; | class User; | |||
class BasicBlock; | class BasicBlock; | |||
class Function; | class Function; | |||
class BranchInst; | class BranchInst; | |||
class Instruction; | class Instruction; | |||
class DbgDeclareInst; | class DbgDeclareInst; | |||
class StoreInst; | class StoreInst; | |||
skipping to change at line 135 | skipping to change at line 135 | |||
/// orders them so it usually won't matter. | /// orders them so it usually won't matter. | |||
/// | /// | |||
bool EliminateDuplicatePHINodes(BasicBlock *BB); | bool EliminateDuplicatePHINodes(BasicBlock *BB); | |||
/// SimplifyCFG - This function is used to do simplification of a CFG. For | /// SimplifyCFG - This function is used to do simplification of a CFG. For | |||
/// example, it adjusts branches to branches to eliminate the extra hop, it | /// example, it adjusts branches to branches to eliminate the extra hop, it | |||
/// eliminates unreachable basic blocks, and does other "peephole" optimiza tion | /// eliminates unreachable basic blocks, and does other "peephole" optimiza tion | |||
/// of the CFG. It returns true if a modification was made, possibly delet ing | /// of the CFG. It returns true if a modification was made, possibly delet ing | |||
/// the basic block that was pointed to. | /// the basic block that was pointed to. | |||
/// | /// | |||
bool SimplifyCFG(BasicBlock *BB, const DataLayout *TD = 0, | bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI, | |||
const TargetTransformInfo *TTI = 0); | const DataLayout *TD = 0); | |||
/// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a bran ch, | /// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a bran ch, | |||
/// and if a predecessor branches to us and one of our successors, fold the | /// 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 | /// setcc into the predecessor and use logical operations to pick the right | |||
/// destination. | /// destination. | |||
bool FoldBranchToCommonDest(BranchInst *BI); | bool FoldBranchToCommonDest(BranchInst *BI); | |||
/// DemoteRegToStack - This function takes a virtual register computed by a n | /// DemoteRegToStack - This function takes a virtual register computed by a n | |||
/// Instruction and replaces it with a slot in the stack frame, allocated v ia | /// Instruction and replaces it with a slot in the stack frame, allocated v ia | |||
/// alloca. This allows the CFG to be changed around without fear of | /// alloca. This allows the CFG to be changed around without fear of | |||
skipping to change at line 234 | skipping to change at line 234 | |||
// Emit an add instruction. | // Emit an add instruction. | |||
Result = Builder->CreateAdd(Op, Result, GEP->getName()+".offs"); | Result = Builder->CreateAdd(Op, Result, GEP->getName()+".offs"); | |||
} | } | |||
return Result; | return Result; | |||
} | } | |||
///===--------------------------------------------------------------------- ===// | ///===--------------------------------------------------------------------- ===// | |||
/// Dbg Intrinsic utilities | /// Dbg Intrinsic utilities | |||
/// | /// | |||
/// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd va lue | /// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value | |||
/// that has an associated llvm.dbg.decl intrinsic. | /// that has an associated llvm.dbg.decl intrinsic. | |||
bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, | bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, | |||
StoreInst *SI, DIBuilder &Builder); | StoreInst *SI, DIBuilder &Builder); | |||
/// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd va lue | /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value | |||
/// that has an associated llvm.dbg.decl intrinsic. | /// that has an associated llvm.dbg.decl intrinsic. | |||
bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, | bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, | |||
LoadInst *LI, DIBuilder &Builder); | LoadInst *LI, DIBuilder &Builder); | |||
/// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate s et | /// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate s et | |||
/// of llvm.dbg.value intrinsics. | /// of llvm.dbg.value intrinsics. | |||
bool LowerDbgDeclare(Function &F); | bool LowerDbgDeclare(Function &F); | |||
/// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic correspondi ng to | /// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic correspondi ng to | |||
/// an alloca, if any. | /// an alloca, if any. | |||
DbgDeclareInst *FindAllocaDbgDeclare(Value *V); | DbgDeclareInst *FindAllocaDbgDeclare(Value *V); | |||
/// replaceDbgDeclareForAlloca - Replaces llvm.dbg.declare instruction when | ||||
/// alloca is replaced with a new value. | ||||
bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, | ||||
DIBuilder &Builder); | ||||
/// \brief Remove all blocks that can not be reached from the function's en | ||||
try. | ||||
/// | ||||
/// Returns true if any basic block was removed. | ||||
bool removeUnreachableBlocks(Function &F); | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 6 change blocks. | ||||
7 lines changed or deleted | 18 lines changed or added | |||
Locale.h | Locale.h | |||
---|---|---|---|---|
#ifndef LLVM_SUPPORT_LOCALE | #ifndef LLVM_SUPPORT_LOCALE_H | |||
#define LLVM_SUPPORT_LOCALE | #define LLVM_SUPPORT_LOCALE_H | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
namespace locale { | namespace locale { | |||
int columnWidth(StringRef s); | int columnWidth(StringRef s); | |||
bool isPrint(int c); | bool isPrint(int c); | |||
} | } | |||
} | } | |||
} | } | |||
#endif // LLVM_SUPPORT_LOCALE | #endif // LLVM_SUPPORT_LOCALE_H | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
LockFileManager.h | LockFileManager.h | |||
---|---|---|---|---|
skipping to change at line 44 | skipping to change at line 44 | |||
LFS_Owned, | LFS_Owned, | |||
/// \brief The lock file already exists and is owned by some other | /// \brief The lock file already exists and is owned by some other | |||
/// instance. | /// instance. | |||
LFS_Shared, | LFS_Shared, | |||
/// \brief An error occurred while trying to create or find the lock | /// \brief An error occurred while trying to create or find the lock | |||
/// file. | /// file. | |||
LFS_Error | LFS_Error | |||
}; | }; | |||
private: | private: | |||
SmallString<128> FileName; | ||||
SmallString<128> LockFileName; | SmallString<128> LockFileName; | |||
SmallString<128> UniqueLockFileName; | SmallString<128> UniqueLockFileName; | |||
Optional<std::pair<std::string, int> > Owner; | Optional<std::pair<std::string, int> > Owner; | |||
Optional<error_code> Error; | Optional<error_code> Error; | |||
LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION; | LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION; | |||
LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION ; | LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION ; | |||
static Optional<std::pair<std::string, int> > | static Optional<std::pair<std::string, int> > | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 1 lines changed or added | |||
LoopInfo.h | LoopInfo.h | |||
---|---|---|---|---|
skipping to change at line 30 | skipping to change at line 30 | |||
// | // | |||
// * whether there is a preheader for the loop | // * whether there is a preheader for the loop | |||
// * the number of back edges to the header | // * the number of back edges to the header | |||
// * whether or not a particular block branches out of the loop | // * whether or not a particular block branches out of the loop | |||
// * the successor blocks of the loop | // * the successor blocks of the loop | |||
// * the loop depth | // * the loop depth | |||
// * etc... | // * etc... | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_LOOP_INFO_H | #ifndef LLVM_ANALYSIS_LOOPINFO_H | |||
#define LLVM_ANALYSIS_LOOP_INFO_H | #define LLVM_ANALYSIS_LOOPINFO_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/DenseSet.h" | #include "llvm/ADT/DenseSet.h" | |||
#include "llvm/ADT/DepthFirstIterator.h" | ||||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/STLExtras.h" | ||||
#include "llvm/Analysis/Dominators.h" | #include "llvm/Analysis/Dominators.h" | |||
#include "llvm/Support/CFG.h" | #include "llvm/Pass.h" | |||
#include "llvm/Support/raw_ostream.h" | ||||
#include <algorithm> | #include <algorithm> | |||
#include <map> | ||||
namespace llvm { | namespace llvm { | |||
template<typename T> | template<typename T> | |||
inline void RemoveFromVector(std::vector<T*> &V, T *N) { | inline void RemoveFromVector(std::vector<T*> &V, T *N) { | |||
typename std::vector<T*>::iterator I = std::find(V.begin(), V.end(), N); | typename std::vector<T*>::iterator I = std::find(V.begin(), V.end(), N); | |||
assert(I != V.end() && "N is not in this list!"); | assert(I != V.end() && "N is not in this list!"); | |||
V.erase(I); | V.erase(I); | |||
} | } | |||
class DominatorTree; | class DominatorTree; | |||
class LoopInfo; | class LoopInfo; | |||
class Loop; | class Loop; | |||
class PHINode; | class PHINode; | |||
class raw_ostream; | ||||
template<class N, class M> class LoopInfoBase; | template<class N, class M> class LoopInfoBase; | |||
template<class N, class M> class LoopBase; | template<class N, class M> class LoopBase; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// LoopBase class - Instances of this class are used to represent loops th at | /// LoopBase class - Instances of this class are used to represent loops th at | |||
/// are detected in the flow graph | /// are detected in the flow graph | |||
/// | /// | |||
template<class BlockT, class LoopT> | template<class BlockT, class LoopT> | |||
class LoopBase { | class LoopBase { | |||
LoopT *ParentLoop; | LoopT *ParentLoop; | |||
skipping to change at line 154 | skipping to change at line 150 | |||
/// getNumBlocks - Get the number of blocks in this loop in constant time . | /// getNumBlocks - Get the number of blocks in this loop in constant time . | |||
unsigned getNumBlocks() const { | unsigned getNumBlocks() const { | |||
return Blocks.size(); | return Blocks.size(); | |||
} | } | |||
/// isLoopExiting - True if terminator in the block can branch to another | /// isLoopExiting - True if terminator in the block can branch to another | |||
/// block that is outside of the current loop. | /// block that is outside of the current loop. | |||
/// | /// | |||
bool isLoopExiting(const BlockT *BB) const { | bool isLoopExiting(const BlockT *BB) const { | |||
typedef GraphTraits<BlockT*> BlockTraits; | typedef GraphTraits<const BlockT*> BlockTraits; | |||
for (typename BlockTraits::ChildIteratorType SI = | for (typename BlockTraits::ChildIteratorType SI = | |||
BlockTraits::child_begin(const_cast<BlockT*>(BB)), | BlockTraits::child_begin(BB), | |||
SE = BlockTraits::child_end(const_cast<BlockT*>(BB)); SI != SE; ++ | SE = BlockTraits::child_end(BB); SI != SE; ++SI) { | |||
SI) { | ||||
if (!contains(*SI)) | if (!contains(*SI)) | |||
return true; | return true; | |||
} | } | |||
return false; | return false; | |||
} | } | |||
/// getNumBackEdges - Calculate the number of back edges to the loop head er | /// getNumBackEdges - Calculate the number of back edges to the loop head er | |||
/// | /// | |||
unsigned getNumBackEdges() const { | unsigned getNumBackEdges() const { | |||
unsigned NumBackEdges = 0; | unsigned NumBackEdges = 0; | |||
BlockT *H = getHeader(); | BlockT *H = getHeader(); | |||
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; | typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; | |||
for (typename InvBlockTraits::ChildIteratorType I = | for (typename InvBlockTraits::ChildIteratorType I = | |||
InvBlockTraits::child_begin(const_cast<BlockT*>(H)), | InvBlockTraits::child_begin(H), | |||
E = InvBlockTraits::child_end(const_cast<BlockT*>(H)); I != E; ++I | E = InvBlockTraits::child_end(H); I != E; ++I) | |||
) | ||||
if (contains(*I)) | if (contains(*I)) | |||
++NumBackEdges; | ++NumBackEdges; | |||
return NumBackEdges; | return NumBackEdges; | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// APIs for simple analysis of the loop. | // APIs for simple analysis of the loop. | |||
// | // | |||
// Note that all of these methods can fail on general loops (ie, there ma y not | // Note that all of these methods can fail on general loops (ie, there ma y not | |||
skipping to change at line 384 | skipping to change at line 380 | |||
bool isLCSSAForm(DominatorTree &DT) const; | bool isLCSSAForm(DominatorTree &DT) const; | |||
/// isLoopSimplifyForm - Return true if the Loop is in the form that | /// isLoopSimplifyForm - Return true if the Loop is in the form that | |||
/// the LoopSimplify form transforms loops to, which is sometimes called | /// the LoopSimplify form transforms loops to, which is sometimes called | |||
/// normal form. | /// normal form. | |||
bool isLoopSimplifyForm() const; | bool isLoopSimplifyForm() const; | |||
/// isSafeToClone - Return true if the loop body is safe to clone in prac tice. | /// isSafeToClone - Return true if the loop body is safe to clone in prac tice. | |||
bool isSafeToClone() const; | bool isSafeToClone() const; | |||
/// Returns true if the loop is annotated parallel. | ||||
/// | ||||
/// A parallel loop can be assumed to not contain any dependencies betwee | ||||
n | ||||
/// iterations by the compiler. That is, any loop-carried dependency chec | ||||
king | ||||
/// can be skipped completely when parallelizing the loop on the target | ||||
/// machine. Thus, if the parallel loop information originates from the | ||||
/// programmer, e.g. via the OpenMP parallel for pragma, it is the | ||||
/// programmer's responsibility to ensure there are no loop-carried | ||||
/// dependencies. The final execution order of the instructions across | ||||
/// iterations is not guaranteed, thus, the end result might or might not | ||||
/// implement actual concurrent execution of instructions across multiple | ||||
/// iterations. | ||||
bool isAnnotatedParallel() const; | ||||
/// hasDedicatedExits - Return true if no exit block for the loop | /// hasDedicatedExits - Return true if no exit block for the loop | |||
/// has a predecessor that is outside the loop. | /// has a predecessor that is outside the loop. | |||
bool hasDedicatedExits() const; | bool hasDedicatedExits() const; | |||
/// getUniqueExitBlocks - Return all unique successor blocks of this loop . | /// getUniqueExitBlocks - Return all unique successor blocks of this loop . | |||
/// These are the blocks _outside of the current loop_ which are branched to. | /// These are the blocks _outside of the current loop_ which are branched to. | |||
/// This assumes that loop exits are in canonical form. | /// This assumes that loop exits are in canonical form. | |||
/// | /// | |||
void getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const ; | void getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const ; | |||
End of changes. 11 change blocks. | ||||
15 lines changed or deleted | 25 lines changed or added | |||
LoopInfoImpl.h | LoopInfoImpl.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This is the generic implementation of LoopInfo used for both Loops and | // This is the generic implementation of LoopInfo used for both Loops and | |||
// MachineLoops. | // MachineLoops. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_LOOP_INFO_IMPL_H | #ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H | |||
#define LLVM_ANALYSIS_LOOP_INFO_IMPL_H | #define LLVM_ANALYSIS_LOOPINFOIMPL_H | |||
#include "llvm/Analysis/LoopInfo.h" | ||||
#include "llvm/ADT/PostOrderIterator.h" | #include "llvm/ADT/PostOrderIterator.h" | |||
#include "llvm/ADT/STLExtras.h" | ||||
#include "llvm/Analysis/LoopInfo.h" | ||||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// APIs for simple analysis of the loop. See header notes. | // APIs for simple analysis of the loop. See header notes. | |||
/// getExitingBlocks - Return all blocks inside the loop that have successo rs | /// getExitingBlocks - Return all blocks inside the loop that have successo rs | |||
/// outside of the loop. These are the blocks _inside of the current loop_ | /// outside of the loop. These are the blocks _inside of the current loop_ | |||
/// which branch out. The returned list is always unique. | /// which branch out. The returned list is always unique. | |||
/// | /// | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 4 lines changed or added | |||
LoopIterator.h | LoopIterator.h | |||
---|---|---|---|---|
skipping to change at line 24 | skipping to change at line 24 | |||
// | // | |||
// If you want to visit all blocks in a loop and don't need an ordered trav eral, | // If you want to visit all blocks in a loop and don't need an ordered trav eral, | |||
// use Loop::block_begin() instead. | // use Loop::block_begin() instead. | |||
// | // | |||
// This is intentionally designed to work with ill-formed loops in which th e | // This is intentionally designed to work with ill-formed loops in which th e | |||
// backedge has been deleted. The only prerequisite is that all blocks | // backedge has been deleted. The only prerequisite is that all blocks | |||
// contained within the loop according to the most recent LoopInfo analysis are | // contained within the loop according to the most recent LoopInfo analysis are | |||
// reachable from the loop header. | // reachable from the loop header. | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_LOOP_ITERATOR_H | #ifndef LLVM_ANALYSIS_LOOPITERATOR_H | |||
#define LLVM_ANALYSIS_LOOP_ITERATOR_H | #define LLVM_ANALYSIS_LOOPITERATOR_H | |||
#include "llvm/ADT/DepthFirstIterator.h" | ||||
#include "llvm/ADT/PostOrderIterator.h" | #include "llvm/ADT/PostOrderIterator.h" | |||
#include "llvm/Analysis/LoopInfo.h" | #include "llvm/Analysis/LoopInfo.h" | |||
namespace llvm { | namespace llvm { | |||
class LoopBlocksTraversal; | class LoopBlocksTraversal; | |||
/// Store the result of a depth first search within basic blocks contained by a | /// Store the result of a depth first search within basic blocks contained by a | |||
/// single loop. | /// single loop. | |||
/// | /// | |||
End of changes. 2 change blocks. | ||||
3 lines changed or deleted | 2 lines changed or added | |||
LoopPass.h | LoopPass.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines LoopPass class. All loop optimization | // This file defines LoopPass class. All loop optimization | |||
// and transformation passes are derived from LoopPass. | // and transformation passes are derived from LoopPass. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_LOOP_PASS_H | #ifndef LLVM_ANALYSIS_LOOPPASS_H | |||
#define LLVM_LOOP_PASS_H | #define LLVM_ANALYSIS_LOOPPASS_H | |||
#include "llvm/Analysis/LoopInfo.h" | #include "llvm/Analysis/LoopInfo.h" | |||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
#include "llvm/PassManagers.h" | #include "llvm/PassManagers.h" | |||
#include "llvm/Function.h" | ||||
#include <deque> | #include <deque> | |||
namespace llvm { | namespace llvm { | |||
class LPPassManager; | class LPPassManager; | |||
class Function; | class Function; | |||
class PMStack; | class PMStack; | |||
class LoopPass : public Pass { | class LoopPass : public Pass { | |||
public: | public: | |||
explicit LoopPass(char &pid) : Pass(PT_Loop, pid) {} | explicit LoopPass(char &pid) : Pass(PT_Loop, pid) {} | |||
/// getPrinterPass - Get a pass to print the function corresponding | /// getPrinterPass - Get a pass to print the function corresponding | |||
/// to a Loop. | /// to a Loop. | |||
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; | Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; | |||
// runOnLoop - This method should be implemented by the subclass to perfo rm | // runOnLoop - This method should be implemented by the subclass to perfo rm | |||
// whatever action is necessary for the specified Loop. | // whatever action is necessary for the specified Loop. | |||
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0; | virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0; | |||
using llvm::Pass::doInitialization; | ||||
using llvm::Pass::doFinalization; | ||||
// Initialization and finalization hooks. | // Initialization and finalization hooks. | |||
virtual bool doInitialization(Loop *L, LPPassManager &LPM) { | virtual bool doInitialization(Loop *L, LPPassManager &LPM) { | |||
return false; | return false; | |||
} | } | |||
// Finalization hook does not supply Loop because at this time | // Finalization hook does not supply Loop because at this time | |||
// loop nest is completely different. | // loop nest is completely different. | |||
virtual bool doFinalization() { return false; } | virtual bool doFinalization() { return false; } | |||
// Check if this pass is suitable for the current LPPassManager, if | // Check if this pass is suitable for the current LPPassManager, if | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 5 lines changed or added | |||
MCAsmBackend.h | MCAsmBackend.h | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
namespace llvm { | namespace llvm { | |||
class MCAsmLayout; | class MCAsmLayout; | |||
class MCAssembler; | class MCAssembler; | |||
class MCELFObjectTargetWriter; | class MCELFObjectTargetWriter; | |||
struct MCFixupKindInfo; | struct MCFixupKindInfo; | |||
class MCFragment; | class MCFragment; | |||
class MCInst; | class MCInst; | |||
class MCInstFragment; | class MCRelaxableFragment; | |||
class MCObjectWriter; | class MCObjectWriter; | |||
class MCSection; | class MCSection; | |||
class MCValue; | class MCValue; | |||
class raw_ostream; | class raw_ostream; | |||
/// MCAsmBackend - Generic interface to target specific assembler backends. | /// MCAsmBackend - Generic interface to target specific assembler backends. | |||
class MCAsmBackend { | class MCAsmBackend { | |||
MCAsmBackend(const MCAsmBackend &) LLVM_DELETED_FUNCTION; | MCAsmBackend(const MCAsmBackend &) LLVM_DELETED_FUNCTION; | |||
void operator=(const MCAsmBackend &) LLVM_DELETED_FUNCTION; | void operator=(const MCAsmBackend &) LLVM_DELETED_FUNCTION; | |||
protected: // Can only create subclasses. | protected: // Can only create subclasses. | |||
MCAsmBackend(); | MCAsmBackend(); | |||
unsigned HasReliableSymbolDifference : 1; | unsigned HasReliableSymbolDifference : 1; | |||
unsigned HasDataInCodeSupport : 1; | unsigned HasDataInCodeSupport : 1; | |||
public: | public: | |||
virtual ~MCAsmBackend(); | virtual ~MCAsmBackend(); | |||
/// lifetime management | ||||
virtual void reset() { } | ||||
/// createObjectWriter - Create a new MCObjectWriter instance for use by the | /// createObjectWriter - Create a new MCObjectWriter instance for use by the | |||
/// assembler backend to emit the final object file. | /// assembler backend to emit the final object file. | |||
virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0; | virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0; | |||
/// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to e nable | /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to e nable | |||
/// non-standard ELFObjectWriters. | /// non-standard ELFObjectWriters. | |||
virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const { | virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const { | |||
llvm_unreachable("createELFObjectTargetWriter is not supported by asm " | llvm_unreachable("createELFObjectTargetWriter is not supported by asm " | |||
"backend"); | "backend"); | |||
} | } | |||
skipping to change at line 130 | skipping to change at line 133 | |||
/// mayNeedRelaxation - Check whether the given instruction may need | /// mayNeedRelaxation - Check whether the given instruction may need | |||
/// relaxation. | /// relaxation. | |||
/// | /// | |||
/// \param Inst - The instruction to test. | /// \param Inst - The instruction to test. | |||
virtual bool mayNeedRelaxation(const MCInst &Inst) const = 0; | virtual bool mayNeedRelaxation(const MCInst &Inst) const = 0; | |||
/// fixupNeedsRelaxation - Target specific predicate for whether a given | /// fixupNeedsRelaxation - Target specific predicate for whether a given | |||
/// fixup requires the associated instruction to be relaxed. | /// fixup requires the associated instruction to be relaxed. | |||
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, | virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, | |||
uint64_t Value, | uint64_t Value, | |||
const MCInstFragment *DF, | const MCRelaxableFragment *DF, | |||
const MCAsmLayout &Layout) const = 0; | const MCAsmLayout &Layout) const = 0; | |||
/// RelaxInstruction - Relax the instruction in the given fragment to the next | /// RelaxInstruction - Relax the instruction in the given fragment to the next | |||
/// wider instruction. | /// wider instruction. | |||
/// | /// | |||
/// \param Inst The instruction to relax, which may be the same as the | /// \param Inst The instruction to relax, which may be the same as the | |||
/// output. | /// output. | |||
/// \param [out] Res On return, the relaxed instruction. | /// \param [out] Res On return, the relaxed instruction. | |||
virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0; | virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0; | |||
End of changes. 3 change blocks. | ||||
2 lines changed or deleted | 5 lines changed or added | |||
MCAsmInfo.h | MCAsmInfo.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains a class to be used as the basis for target specific | // This file contains a class to be used as the basis for target specific | |||
// asm writers. This class primarily takes care of global printing constan ts, | // asm writers. This class primarily takes care of global printing constan ts, | |||
// which are used in very similar ways across all targets. | // which are used in very similar ways across all targets. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TARGET_ASM_INFO_H | #ifndef LLVM_MC_MCASMINFO_H | |||
#define LLVM_TARGET_ASM_INFO_H | #define LLVM_MC_MCASMINFO_H | |||
#include "llvm/MC/MachineLocation.h" | ||||
#include "llvm/MC/MCDirectives.h" | #include "llvm/MC/MCDirectives.h" | |||
#include "llvm/MC/MachineLocation.h" | ||||
#include <cassert> | #include <cassert> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class MCExpr; | class MCExpr; | |||
class MCSection; | class MCSection; | |||
class MCStreamer; | class MCStreamer; | |||
class MCSymbol; | class MCSymbol; | |||
class MCContext; | class MCContext; | |||
skipping to change at line 51 | skipping to change at line 51 | |||
class MCAsmInfo { | class MCAsmInfo { | |||
protected: | protected: | |||
//===------------------------------------------------------------------ ===// | //===------------------------------------------------------------------ ===// | |||
// Properties to be set by the target writer, used to configure asm pri nter. | // Properties to be set by the target writer, used to configure asm pri nter. | |||
// | // | |||
/// PointerSize - Pointer size in bytes. | /// PointerSize - Pointer size in bytes. | |||
/// Default is 4. | /// Default is 4. | |||
unsigned PointerSize; | unsigned PointerSize; | |||
/// CalleeSaveStackSlotSize - Size of the stack slot reserved for | ||||
/// callee-saved registers, in bytes. | ||||
/// Default is same as pointer size. | ||||
unsigned CalleeSaveStackSlotSize; | ||||
/// IsLittleEndian - True if target is little endian. | /// IsLittleEndian - True if target is little endian. | |||
/// Default is true. | /// Default is true. | |||
bool IsLittleEndian; | bool IsLittleEndian; | |||
/// StackGrowsUp - True if target stack grow up. | /// StackGrowsUp - True if target stack grow up. | |||
/// Default is false. | /// Default is false. | |||
bool StackGrowsUp; | bool StackGrowsUp; | |||
/// HasSubsectionsViaSymbols - True if this target has the MachO | /// HasSubsectionsViaSymbols - True if this target has the MachO | |||
/// .subsections_via_symbols directive. | /// .subsections_via_symbols directive. | |||
skipping to change at line 105 | skipping to change at line 110 | |||
/// which asm comments should be printed. | /// which asm comments should be printed. | |||
unsigned CommentColumn; // Defaults to 40 | unsigned CommentColumn; // Defaults to 40 | |||
/// CommentString - This indicates the comment character used by the | /// CommentString - This indicates the comment character used by the | |||
/// assembler. | /// assembler. | |||
const char *CommentString; // Defaults to "#" | const char *CommentString; // Defaults to "#" | |||
/// LabelSuffix - This is appended to emitted labels. | /// LabelSuffix - This is appended to emitted labels. | |||
const char *LabelSuffix; // Defaults to ":" | const char *LabelSuffix; // Defaults to ":" | |||
/// LabelSuffix - This is appended to emitted labels. | ||||
const char *DebugLabelSuffix; // Defaults to ":" | ||||
/// GlobalPrefix - If this is set to a non-empty string, it is prepende d | /// GlobalPrefix - If this is set to a non-empty string, it is prepende d | |||
/// onto all global symbols. This is often used for "_" or ".". | /// onto all global symbols. This is often used for "_" or ".". | |||
const char *GlobalPrefix; // Defaults to "" | const char *GlobalPrefix; // Defaults to "" | |||
/// PrivateGlobalPrefix - This prefix is used for globals like constant | /// PrivateGlobalPrefix - This prefix is used for globals like constant | |||
/// pool entries that are completely private to the .s file and should not | /// pool entries that are completely private to the .s file and should not | |||
/// have names in the .o file. This is often "." or "L". | /// have names in the .o file. This is often "." or "L". | |||
const char *PrivateGlobalPrefix; // Defaults to "." | const char *PrivateGlobalPrefix; // Defaults to "." | |||
/// LinkerPrivateGlobalPrefix - This prefix is used for symbols that sh ould | /// LinkerPrivateGlobalPrefix - This prefix is used for symbols that sh ould | |||
skipping to change at line 212 | skipping to change at line 220 | |||
/// UsesELFSectionDirectiveForBSS - This is true if this target uses EL F | /// UsesELFSectionDirectiveForBSS - This is true if this target uses EL F | |||
/// '.section' directive before the '.bss' one. It's used for PPC/Linux | /// '.section' directive before the '.bss' one. It's used for PPC/Linux | |||
/// which doesn't support the '.bss' directive only. | /// which doesn't support the '.bss' directive only. | |||
bool UsesELFSectionDirectiveForBSS; // Defaults to false. | bool UsesELFSectionDirectiveForBSS; // Defaults to false. | |||
/// HasMicrosoftFastStdCallMangling - True if this target uses microsof t | /// HasMicrosoftFastStdCallMangling - True if this target uses microsof t | |||
/// style mangling for functions with X86_StdCall/X86_FastCall calling | /// style mangling for functions with X86_StdCall/X86_FastCall calling | |||
/// convention. | /// convention. | |||
bool HasMicrosoftFastStdCallMangling; // Defaults to false. | bool HasMicrosoftFastStdCallMangling; // Defaults to false. | |||
bool NeedsDwarfSectionOffsetDirective; | ||||
//===--- Alignment Information ---------------------------------------- ===// | //===--- Alignment Information ---------------------------------------- ===// | |||
/// AlignDirective - The directive used to emit round up to an alignmen t | /// AlignDirective - The directive used to emit round up to an alignmen t | |||
/// boundary. | /// boundary. | |||
/// | /// | |||
const char *AlignDirective; // Defaults to "\t.align\t" | const char *AlignDirective; // Defaults to "\t.align\t" | |||
/// AlignmentIsInBytes - If this is true (the default) then the asmprin ter | /// AlignmentIsInBytes - If this is true (the default) then the asmprin ter | |||
/// emits ".align N" directives, where N is the number of bytes to alig n to. | /// emits ".align N" directives, where N is the number of bytes to alig n to. | |||
/// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte | /// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte | |||
skipping to change at line 314 | skipping to change at line 324 | |||
/// information. | /// information. | |||
bool SupportsDebugInformation; // Defaults to false. | bool SupportsDebugInformation; // Defaults to false. | |||
/// SupportsExceptionHandling - True if target supports exception handl ing. | /// SupportsExceptionHandling - True if target supports exception handl ing. | |||
ExceptionHandling::ExceptionsType ExceptionsType; // Defaults to None | ExceptionHandling::ExceptionsType ExceptionsType; // Defaults to None | |||
/// DwarfUsesInlineInfoSection - True if DwarfDebugInlineSection is use d to | /// DwarfUsesInlineInfoSection - True if DwarfDebugInlineSection is use d to | |||
/// encode inline subroutine information. | /// encode inline subroutine information. | |||
bool DwarfUsesInlineInfoSection; // Defaults to false. | bool DwarfUsesInlineInfoSection; // Defaults to false. | |||
/// DwarfSectionOffsetDirective - Special section offset directive. | ||||
const char* DwarfSectionOffsetDirective; // Defaults to NULL | ||||
/// DwarfUsesRelocationsAcrossSections - True if Dwarf2 output generall y | /// DwarfUsesRelocationsAcrossSections - True if Dwarf2 output generall y | |||
/// uses relocations for references to other .debug_* sections. | /// uses relocations for references to other .debug_* sections. | |||
bool DwarfUsesRelocationsAcrossSections; | bool DwarfUsesRelocationsAcrossSections; | |||
/// DwarfRegNumForCFI - True if dwarf register numbers are printed | /// DwarfRegNumForCFI - True if dwarf register numbers are printed | |||
/// instead of symbolic register names in .cfi_* directives. | /// instead of symbolic register names in .cfi_* directives. | |||
bool DwarfRegNumForCFI; // Defaults to false; | bool DwarfRegNumForCFI; // Defaults to false; | |||
//===--- Prologue State ----------------------------------------------= ==// | //===--- Prologue State ----------------------------------------------= ==// | |||
skipping to change at line 342 | skipping to change at line 349 | |||
// FIXME: move these methods to DwarfPrinter when the JIT stops using t hem. | // FIXME: move these methods to DwarfPrinter when the JIT stops using t hem. | |||
static unsigned getSLEB128Size(int Value); | static unsigned getSLEB128Size(int Value); | |||
static unsigned getULEB128Size(unsigned Value); | static unsigned getULEB128Size(unsigned Value); | |||
/// getPointerSize - Get the pointer size in bytes. | /// getPointerSize - Get the pointer size in bytes. | |||
unsigned getPointerSize() const { | unsigned getPointerSize() const { | |||
return PointerSize; | return PointerSize; | |||
} | } | |||
/// islittleendian - True if the target is little endian. | /// getCalleeSaveStackSlotSize - Get the callee-saved register stack sl | |||
ot | ||||
/// size in bytes. | ||||
unsigned getCalleeSaveStackSlotSize() const { | ||||
return CalleeSaveStackSlotSize; | ||||
} | ||||
/// isLittleEndian - True if the target is little endian. | ||||
bool isLittleEndian() const { | bool isLittleEndian() const { | |||
return IsLittleEndian; | return IsLittleEndian; | |||
} | } | |||
/// isStackGrowthDirectionUp - True if target stack grow up. | /// isStackGrowthDirectionUp - True if target stack grow up. | |||
bool isStackGrowthDirectionUp() const { | bool isStackGrowthDirectionUp() const { | |||
return StackGrowsUp; | return StackGrowsUp; | |||
} | } | |||
bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols ; } | bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols ; } | |||
skipping to change at line 400 | skipping to change at line 413 | |||
} | } | |||
bool usesELFSectionDirectiveForBSS() const { | bool usesELFSectionDirectiveForBSS() const { | |||
return UsesELFSectionDirectiveForBSS; | return UsesELFSectionDirectiveForBSS; | |||
} | } | |||
bool hasMicrosoftFastStdCallMangling() const { | bool hasMicrosoftFastStdCallMangling() const { | |||
return HasMicrosoftFastStdCallMangling; | return HasMicrosoftFastStdCallMangling; | |||
} | } | |||
bool needsDwarfSectionOffsetDirective() const { | ||||
return NeedsDwarfSectionOffsetDirective; | ||||
} | ||||
// Accessors. | // Accessors. | |||
// | // | |||
bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirecti ve; } | bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirecti ve; } | |||
bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; } | bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; } | |||
bool hasStaticCtorDtorReferenceInStaticMode() const { | bool hasStaticCtorDtorReferenceInStaticMode() const { | |||
return HasStaticCtorDtorReferenceInStaticMode; | return HasStaticCtorDtorReferenceInStaticMode; | |||
} | } | |||
bool getLinkerRequiresNonEmptyDwarfLines() const { | bool getLinkerRequiresNonEmptyDwarfLines() const { | |||
return LinkerRequiresNonEmptyDwarfLines; | return LinkerRequiresNonEmptyDwarfLines; | |||
} | } | |||
skipping to change at line 428 | skipping to change at line 445 | |||
} | } | |||
unsigned getCommentColumn() const { | unsigned getCommentColumn() const { | |||
return CommentColumn; | return CommentColumn; | |||
} | } | |||
const char *getCommentString() const { | const char *getCommentString() const { | |||
return CommentString; | return CommentString; | |||
} | } | |||
const char *getLabelSuffix() const { | const char *getLabelSuffix() const { | |||
return LabelSuffix; | return LabelSuffix; | |||
} | } | |||
const char *getDebugLabelSuffix() const { | ||||
return DebugLabelSuffix; | ||||
} | ||||
const char *getGlobalPrefix() const { | const char *getGlobalPrefix() const { | |||
return GlobalPrefix; | return GlobalPrefix; | |||
} | } | |||
const char *getPrivateGlobalPrefix() const { | const char *getPrivateGlobalPrefix() const { | |||
return PrivateGlobalPrefix; | return PrivateGlobalPrefix; | |||
} | } | |||
const char *getLinkerPrivateGlobalPrefix() const { | const char *getLinkerPrivateGlobalPrefix() const { | |||
return LinkerPrivateGlobalPrefix; | return LinkerPrivateGlobalPrefix; | |||
} | } | |||
const char *getInlineAsmStart() const { | const char *getInlineAsmStart() const { | |||
skipping to change at line 540 | skipping to change at line 562 | |||
} | } | |||
bool isExceptionHandlingDwarf() const { | bool isExceptionHandlingDwarf() const { | |||
return | return | |||
(ExceptionsType == ExceptionHandling::DwarfCFI || | (ExceptionsType == ExceptionHandling::DwarfCFI || | |||
ExceptionsType == ExceptionHandling::ARM || | ExceptionsType == ExceptionHandling::ARM || | |||
ExceptionsType == ExceptionHandling::Win64); | ExceptionsType == ExceptionHandling::Win64); | |||
} | } | |||
bool doesDwarfUseInlineInfoSection() const { | bool doesDwarfUseInlineInfoSection() const { | |||
return DwarfUsesInlineInfoSection; | return DwarfUsesInlineInfoSection; | |||
} | } | |||
const char *getDwarfSectionOffsetDirective() const { | ||||
return DwarfSectionOffsetDirective; | ||||
} | ||||
bool doesDwarfUseRelocationsAcrossSections() const { | bool doesDwarfUseRelocationsAcrossSections() const { | |||
return DwarfUsesRelocationsAcrossSections; | return DwarfUsesRelocationsAcrossSections; | |||
} | } | |||
bool useDwarfRegNumForCFI() const { | bool useDwarfRegNumForCFI() const { | |||
return DwarfRegNumForCFI; | return DwarfRegNumForCFI; | |||
} | } | |||
void addInitialFrameState(MCSymbol *label, const MachineLocation &D, | void addInitialFrameState(MCSymbol *label, const MachineLocation &D, | |||
const MachineLocation &S) { | const MachineLocation &S) { | |||
InitialFrameState.push_back(MachineMove(label, D, S)); | InitialFrameState.push_back(MachineMove(label, D, S)); | |||
End of changes. 11 change blocks. | ||||
10 lines changed or deleted | 30 lines changed or added | |||
MCAsmInfoCOFF.h | MCAsmInfoCOFF.h | |||
---|---|---|---|---|
//===-- MCAsmInfoCOFF.h - COFF asm properties -------------------*- C++ -*- ===// | //===-- MCAsmInfoCOFF.h - COFF asm properties -------------------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_COFF_TARGET_ASM_INFO_H | #ifndef LLVM_MC_MCASMINFOCOFF_H | |||
#define LLVM_COFF_TARGET_ASM_INFO_H | #define LLVM_MC_MCASMINFOCOFF_H | |||
#include "llvm/MC/MCAsmInfo.h" | #include "llvm/MC/MCAsmInfo.h" | |||
namespace llvm { | namespace llvm { | |||
class MCAsmInfoCOFF : public MCAsmInfo { | class MCAsmInfoCOFF : public MCAsmInfo { | |||
virtual void anchor(); | virtual void anchor(); | |||
protected: | protected: | |||
explicit MCAsmInfoCOFF(); | explicit MCAsmInfoCOFF(); | |||
}; | }; | |||
skipping to change at line 35 | skipping to change at line 35 | |||
explicit MCAsmInfoMicrosoft(); | explicit MCAsmInfoMicrosoft(); | |||
}; | }; | |||
class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF { | class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF { | |||
virtual void anchor(); | virtual void anchor(); | |||
protected: | protected: | |||
explicit MCAsmInfoGNUCOFF(); | explicit MCAsmInfoGNUCOFF(); | |||
}; | }; | |||
} | } | |||
#endif // LLVM_COFF_TARGET_ASM_INFO_H | #endif // LLVM_MC_MCASMINFOCOFF_H | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
MCAsmInfoDarwin.h | MCAsmInfoDarwin.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines target asm properties related what form asm statements | // This file defines target asm properties related what form asm statements | |||
// should take in general on Darwin-based targets | // should take in general on Darwin-based targets | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_DARWIN_TARGET_ASM_INFO_H | #ifndef LLVM_MC_MCASMINFODARWIN_H | |||
#define LLVM_DARWIN_TARGET_ASM_INFO_H | #define LLVM_MC_MCASMINFODARWIN_H | |||
#include "llvm/MC/MCAsmInfo.h" | #include "llvm/MC/MCAsmInfo.h" | |||
namespace llvm { | namespace llvm { | |||
class MCAsmInfoDarwin : public MCAsmInfo { | class MCAsmInfoDarwin : public MCAsmInfo { | |||
virtual void anchor(); | virtual void anchor(); | |||
public: | public: | |||
explicit MCAsmInfoDarwin(); | explicit MCAsmInfoDarwin(); | |||
}; | }; | |||
} | } | |||
#endif // LLVM_DARWIN_TARGET_ASM_INFO_H | #endif // LLVM_MC_MCASMINFODARWIN_H | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
MCAsmLayout.h | MCAsmLayout.h | |||
---|---|---|---|---|
skipping to change at line 24 | skipping to change at line 24 | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
namespace llvm { | namespace llvm { | |||
class MCAssembler; | class MCAssembler; | |||
class MCFragment; | class MCFragment; | |||
class MCSectionData; | class MCSectionData; | |||
class MCSymbolData; | class MCSymbolData; | |||
/// Encapsulates the layout of an assembly file at a particular point in ti me. | /// Encapsulates the layout of an assembly file at a particular point in ti me. | |||
/// | /// | |||
/// Assembly may requiring compute multiple layouts for a particular assemb ly | /// Assembly may require computing multiple layouts for a particular assemb ly | |||
/// file as part of the relaxation process. This class encapsulates the lay out | /// file as part of the relaxation process. This class encapsulates the lay out | |||
/// at a single point in time in such a way that it is always possible to | /// at a single point in time in such a way that it is always possible to | |||
/// efficiently compute the exact addresses of any symbol in the assembly f ile, | /// efficiently compute the exact address of any symbol in the assembly fil e, | |||
/// even during the relaxation process. | /// even during the relaxation process. | |||
class MCAsmLayout { | class MCAsmLayout { | |||
public: | public: | |||
typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_itera tor; | typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_itera tor; | |||
typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator; | typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator; | |||
private: | private: | |||
MCAssembler &Assembler; | MCAssembler &Assembler; | |||
/// List of sections in layout order. | /// List of sections in layout order. | |||
llvm::SmallVector<MCSectionData*, 16> SectionOrder; | llvm::SmallVector<MCSectionData*, 16> SectionOrder; | |||
/// The last fragment which was laid out, or 0 if nothing has been laid | /// The last fragment which was laid out, or 0 if nothing has been laid | |||
/// out. Fragments are always laid out in order, so all fragments with a | /// out. Fragments are always laid out in order, so all fragments with a | |||
/// lower ordinal will be up to date. | /// lower ordinal will be valid. | |||
mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment; | mutable DenseMap<const MCSectionData*, MCFragment*> LastValidFragment; | |||
/// \brief Make sure that the layout for the given fragment is valid, laz ily | /// \brief Make sure that the layout for the given fragment is valid, laz ily | |||
/// computing it if necessary. | /// computing it if necessary. | |||
void EnsureValid(const MCFragment *F) const; | void ensureValid(const MCFragment *F) const; | |||
bool isFragmentUpToDate(const MCFragment *F) const; | /// \brief Is the layout for this fragment valid? | |||
bool isFragmentValid(const MCFragment *F) const; | ||||
/// \brief Compute the amount of padding required before this fragment to | ||||
/// obey bundling restrictions. | ||||
uint64_t computeBundlePadding(const MCFragment *F, | ||||
uint64_t FOffset, uint64_t FSize); | ||||
public: | public: | |||
MCAsmLayout(MCAssembler &_Assembler); | MCAsmLayout(MCAssembler &_Assembler); | |||
/// Get the assembler object this is a layout for. | /// Get the assembler object this is a layout for. | |||
MCAssembler &getAssembler() const { return Assembler; } | MCAssembler &getAssembler() const { return Assembler; } | |||
/// \brief Invalidate all following fragments because a fragment has been | /// \brief Invalidate the fragments starting with F because it has been | |||
/// resized. The fragments size should have already been updated. | /// resized. The fragment's size should have already been updated, but | |||
void Invalidate(MCFragment *F); | /// its bundle padding will be recomputed. | |||
void invalidateFragmentsFrom(MCFragment *F); | ||||
/// \brief Perform layout for a single fragment, assuming that the previo us | /// \brief Perform layout for a single fragment, assuming that the previo us | |||
/// fragment has already been laid out correctly, and the parent section has | /// fragment has already been laid out correctly, and the parent section has | |||
/// been initialized. | /// been initialized. | |||
void LayoutFragment(MCFragment *Fragment); | void layoutFragment(MCFragment *Fragment); | |||
/// @name Section Access (in layout order) | /// @name Section Access (in layout order) | |||
/// @{ | /// @{ | |||
llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() { | llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() { | |||
return SectionOrder; | return SectionOrder; | |||
} | } | |||
const llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() const { | const llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() const { | |||
return SectionOrder; | return SectionOrder; | |||
} | } | |||
End of changes. 7 change blocks. | ||||
10 lines changed or deleted | 17 lines changed or added | |||
MCAsmLexer.h | MCAsmLexer.h | |||
---|---|---|---|---|
//===-- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer Interface -----*- C++ -*- ===// | //===-- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer Interface -----*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCASMLEXER_H | #ifndef LLVM_MC_MCPARSER_MCASMLEXER_H | |||
#define LLVM_MC_MCASMLEXER_H | #define LLVM_MC_MCPARSER_MCASMLEXER_H | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/SMLoc.h" | #include "llvm/Support/SMLoc.h" | |||
namespace llvm { | namespace llvm { | |||
/// AsmToken - Target independent representation for an assembler token. | /// AsmToken - Target independent representation for an assembler token. | |||
class AsmToken { | class AsmToken { | |||
skipping to change at line 37 | skipping to change at line 37 | |||
// String values. | // String values. | |||
Identifier, | Identifier, | |||
String, | String, | |||
// Integer values. | // Integer values. | |||
Integer, | Integer, | |||
// Real values. | // Real values. | |||
Real, | Real, | |||
// Register values (stored in IntVal). Only used by MCTargetAsmLexer. | ||||
Register, | ||||
// No-value. | // No-value. | |||
EndOfStatement, | EndOfStatement, | |||
Colon, | Colon, | |||
Space, | Space, | |||
Plus, Minus, Tilde, | Plus, Minus, Tilde, | |||
Slash, // '/' | Slash, // '/' | |||
BackSlash, // '\' | BackSlash, // '\' | |||
LParen, RParen, LBrac, RBrac, LCurly, RCurly, | LParen, RParen, LBrac, RBrac, LCurly, RCurly, | |||
Star, Dot, Comma, Dollar, Equal, EqualEqual, | Star, Dot, Comma, Dollar, Equal, EqualEqual, | |||
skipping to change at line 107 | skipping to change at line 104 | |||
/// is safe to store across calls to Lex(). | /// is safe to store across calls to Lex(). | |||
StringRef getString() const { return Str; } | StringRef getString() const { return Str; } | |||
// FIXME: Don't compute this in advance, it makes every token larger, and is | // FIXME: Don't compute this in advance, it makes every token larger, and is | |||
// also not generally what we want (it is nicer for recovery etc. to lex 123br | // also not generally what we want (it is nicer for recovery etc. to lex 123br | |||
// as a single token, then diagnose as an invalid number). | // as a single token, then diagnose as an invalid number). | |||
int64_t getIntVal() const { | int64_t getIntVal() const { | |||
assert(Kind == Integer && "This token isn't an integer!"); | assert(Kind == Integer && "This token isn't an integer!"); | |||
return IntVal; | return IntVal; | |||
} | } | |||
/// getRegVal - Get the register number for the current token, which shou | ||||
ld | ||||
/// be a register. | ||||
unsigned getRegVal() const { | ||||
assert(Kind == Register && "This token isn't a register!"); | ||||
return static_cast<unsigned>(IntVal); | ||||
} | ||||
}; | }; | |||
/// MCAsmLexer - Generic assembler lexer interface, for use by target speci fic | /// MCAsmLexer - Generic assembler lexer interface, for use by target speci fic | |||
/// assembly lexers. | /// assembly lexers. | |||
class MCAsmLexer { | class MCAsmLexer { | |||
/// The current token, stored in the base class for faster access. | /// The current token, stored in the base class for faster access. | |||
AsmToken CurTok; | AsmToken CurTok; | |||
/// The location and description of the current error | /// The location and description of the current error | |||
SMLoc ErrLoc; | SMLoc ErrLoc; | |||
End of changes. 3 change blocks. | ||||
13 lines changed or deleted | 2 lines changed or added | |||
MCAsmParser.h | MCAsmParser.h | |||
---|---|---|---|---|
//===-- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ---*- C++ -*- ===// | //===-- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ---*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCASMPARSER_H | #ifndef LLVM_MC_MCPARSER_MCASMPARSER_H | |||
#define LLVM_MC_MCASMPARSER_H | #define LLVM_MC_MCPARSER_MCASMPARSER_H | |||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/StringRef.h" | ||||
#include "llvm/MC/MCParser/AsmLexer.h" | ||||
#include "llvm/Support/DataTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
class AsmToken; | ||||
class MCAsmInfo; | class MCAsmInfo; | |||
class MCAsmLexer; | class MCAsmLexer; | |||
class MCAsmParserExtension; | class MCAsmParserExtension; | |||
class MCContext; | class MCContext; | |||
class MCExpr; | class MCExpr; | |||
class MCInstPrinter; | class MCInstPrinter; | |||
class MCInstrInfo; | class MCInstrInfo; | |||
class MCParsedAsmOperand; | ||||
class MCStreamer; | class MCStreamer; | |||
class MCTargetAsmParser; | class MCTargetAsmParser; | |||
class SMLoc; | class SMLoc; | |||
class SMRange; | class SMRange; | |||
class SourceMgr; | class SourceMgr; | |||
class StringRef; | ||||
class Twine; | class Twine; | |||
/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser. | /// MCAsmParserSemaCallback - Generic Sema callback for assembly parser. | |||
class MCAsmParserSemaCallback { | class MCAsmParserSemaCallback { | |||
public: | public: | |||
typedef struct { | ||||
void *OpDecl; | ||||
bool IsVarDecl; | ||||
unsigned Length, Size, Type; | ||||
void clear() { | ||||
OpDecl = 0; | ||||
IsVarDecl = false; | ||||
Length = 1; | ||||
Size = 0; | ||||
Type = 0; | ||||
} | ||||
} InlineAsmIdentifierInfo; | ||||
virtual ~MCAsmParserSemaCallback(); | virtual ~MCAsmParserSemaCallback(); | |||
virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc, | virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf, | |||
unsigned &Size) = 0; | InlineAsmIdentifierInfo &Info, | |||
bool IsUnevaluatedContext) = 0; | ||||
virtual bool LookupInlineAsmField(StringRef Base, StringRef Member, | virtual bool LookupInlineAsmField(StringRef Base, StringRef Member, | |||
unsigned &Offset) = 0; | unsigned &Offset) = 0; | |||
}; | }; | |||
typedef MCAsmParserSemaCallback::InlineAsmIdentifierInfo | ||||
InlineAsmIdentifierInfo; | ||||
/// MCAsmParser - Generic assembler parser interface, for use by target spe cific | /// MCAsmParser - Generic assembler parser interface, for use by target spe cific | |||
/// assembly parsers. | /// assembly parsers. | |||
class MCAsmParser { | class MCAsmParser { | |||
public: | public: | |||
typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc) ; | typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc) ; | |||
typedef std::pair<MCAsmParserExtension*, DirectiveHandler> | ||||
ExtensionDirectiveHandler; | ||||
private: | private: | |||
MCAsmParser(const MCAsmParser &) LLVM_DELETED_FUNCTION; | MCAsmParser(const MCAsmParser &) LLVM_DELETED_FUNCTION; | |||
void operator=(const MCAsmParser &) LLVM_DELETED_FUNCTION; | void operator=(const MCAsmParser &) LLVM_DELETED_FUNCTION; | |||
MCTargetAsmParser *TargetParser; | MCTargetAsmParser *TargetParser; | |||
unsigned ShowParsedOperands : 1; | unsigned ShowParsedOperands : 1; | |||
protected: // Can only create subclasses. | protected: // Can only create subclasses. | |||
MCAsmParser(); | MCAsmParser(); | |||
public: | public: | |||
virtual ~MCAsmParser(); | virtual ~MCAsmParser(); | |||
virtual void AddDirectiveHandler(MCAsmParserExtension *Object, | virtual void addDirectiveHandler(StringRef Directive, | |||
StringRef Directive, | ExtensionDirectiveHandler Handler) = 0; | |||
DirectiveHandler Handler) = 0; | ||||
virtual SourceMgr &getSourceManager() = 0; | virtual SourceMgr &getSourceManager() = 0; | |||
virtual MCAsmLexer &getLexer() = 0; | virtual MCAsmLexer &getLexer() = 0; | |||
virtual MCContext &getContext() = 0; | virtual MCContext &getContext() = 0; | |||
/// getStreamer - Return the output streamer for the assembler. | /// getStreamer - Return the output streamer for the assembler. | |||
virtual MCStreamer &getStreamer() = 0; | virtual MCStreamer &getStreamer() = 0; | |||
skipping to change at line 92 | skipping to change at line 111 | |||
bool getShowParsedOperands() const { return ShowParsedOperands; } | bool getShowParsedOperands() const { return ShowParsedOperands; } | |||
void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; } | void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; } | |||
/// Run - Run the parser on the input source buffer. | /// Run - Run the parser on the input source buffer. | |||
virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0; | virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0; | |||
virtual void setParsingInlineAsm(bool V) = 0; | virtual void setParsingInlineAsm(bool V) = 0; | |||
virtual bool isParsingInlineAsm() = 0; | virtual bool isParsingInlineAsm() = 0; | |||
/// ParseMSInlineAsm - Parse ms-style inline assembly. | /// parseMSInlineAsm - Parse ms-style inline assembly. | |||
virtual bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, | virtual bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString, | |||
unsigned &NumOutputs, unsigned &NumInputs, | unsigned &NumOutputs, unsigned &NumInputs, | |||
SmallVectorImpl<std::pair<void *, bool> > & OpDecls, | SmallVectorImpl<std::pair<void *, bool> > & OpDecls, | |||
SmallVectorImpl<std::string> &Constraints, | SmallVectorImpl<std::string> &Constraints, | |||
SmallVectorImpl<std::string> &Clobbers, | SmallVectorImpl<std::string> &Clobbers, | |||
const MCInstrInfo *MII, | const MCInstrInfo *MII, | |||
const MCInstPrinter *IP, | const MCInstPrinter *IP, | |||
MCAsmParserSemaCallback &SI) = 0; | MCAsmParserSemaCallback &SI) = 0; | |||
/// Warning - Emit a warning at the location \p L, with the message \p Ms g. | /// Warning - Emit a warning at the location \p L, with the message \p Ms g. | |||
/// | /// | |||
/// \return The return value is true, if warnings are fatal. | /// \return The return value is true, if warnings are fatal. | |||
virtual bool Warning(SMLoc L, const Twine &Msg, | virtual bool Warning(SMLoc L, const Twine &Msg, | |||
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0; | ArrayRef<SMRange> Ranges = None) = 0; | |||
/// Error - Emit an error at the location \p L, with the message \p Msg. | /// Error - Emit an error at the location \p L, with the message \p Msg. | |||
/// | /// | |||
/// \return The return value is always true, as an idiomatic convenience to | /// \return The return value is always true, as an idiomatic convenience to | |||
/// clients. | /// clients. | |||
virtual bool Error(SMLoc L, const Twine &Msg, | virtual bool Error(SMLoc L, const Twine &Msg, | |||
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0; | ArrayRef<SMRange> Ranges = None) = 0; | |||
/// Lex - Get the next AsmToken in the stream, possibly handling file | /// Lex - Get the next AsmToken in the stream, possibly handling file | |||
/// inclusion first. | /// inclusion first. | |||
virtual const AsmToken &Lex() = 0; | virtual const AsmToken &Lex() = 0; | |||
/// getTok - Get the current AsmToken from the stream. | /// getTok - Get the current AsmToken from the stream. | |||
const AsmToken &getTok(); | const AsmToken &getTok(); | |||
/// \brief Report an error at the current lexer location. | /// \brief Report an error at the current lexer location. | |||
bool TokError(const Twine &Msg, | bool TokError(const Twine &Msg, ArrayRef<SMRange> Ranges = None); | |||
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); | ||||
/// ParseIdentifier - Parse an identifier or string (as a quoted identifi er) | /// parseIdentifier - Parse an identifier or string (as a quoted identifi er) | |||
/// and set \p Res to the identifier contents. | /// and set \p Res to the identifier contents. | |||
virtual bool ParseIdentifier(StringRef &Res) = 0; | virtual bool parseIdentifier(StringRef &Res) = 0; | |||
/// \brief Parse up to the end of statement and return the contents from the | /// \brief Parse up to the end of statement and return the contents from the | |||
/// current token until the end of the statement; the current token on ex it | /// current token until the end of the statement; the current token on ex it | |||
/// will be either the EndOfStatement or EOF. | /// will be either the EndOfStatement or EOF. | |||
virtual StringRef ParseStringToEndOfStatement() = 0; | virtual StringRef parseStringToEndOfStatement() = 0; | |||
/// parseEscapedString - Parse the current token as a string which may in | ||||
clude | ||||
/// escaped characters and return the string contents. | ||||
virtual bool parseEscapedString(std::string &Data) = 0; | ||||
/// EatToEndOfStatement - Skip to the end of the current statement, for e rror | /// eatToEndOfStatement - Skip to the end of the current statement, for e rror | |||
/// recovery. | /// recovery. | |||
virtual void EatToEndOfStatement() = 0; | virtual void eatToEndOfStatement() = 0; | |||
/// ParseExpression - Parse an arbitrary expression. | /// parseExpression - Parse an arbitrary expression. | |||
/// | /// | |||
/// @param Res - The value of the expression. The result is undefined | /// @param Res - The value of the expression. The result is undefined | |||
/// on error. | /// on error. | |||
/// @result - False on success. | /// @result - False on success. | |||
virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; | virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; | |||
bool ParseExpression(const MCExpr *&Res); | bool parseExpression(const MCExpr *&Res); | |||
/// ParseParenExpression - Parse an arbitrary expression, assuming that a | /// parsePrimaryExpr - Parse a primary expression. | |||
n | /// | |||
/// @param Res - The value of the expression. The result is undefined | ||||
/// on error. | ||||
/// @result - False on success. | ||||
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0; | ||||
/// parseParenExpression - Parse an arbitrary expression, assuming that a | ||||
n | ||||
/// initial '(' has already been consumed. | /// initial '(' has already been consumed. | |||
/// | /// | |||
/// @param Res - The value of the expression. The result is undefined | /// @param Res - The value of the expression. The result is undefined | |||
/// on error. | /// on error. | |||
/// @result - False on success. | /// @result - False on success. | |||
virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; | virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; | |||
/// ParseAbsoluteExpression - Parse an expression which must evaluate to an | /// parseAbsoluteExpression - Parse an expression which must evaluate to an | |||
/// absolute value. | /// absolute value. | |||
/// | /// | |||
/// @param Res - The value of the absolute expression. The result is unde fined | /// @param Res - The value of the absolute expression. The result is unde fined | |||
/// on error. | /// on error. | |||
/// @result - False on success. | /// @result - False on success. | |||
virtual bool ParseAbsoluteExpression(int64_t &Res) = 0; | virtual bool parseAbsoluteExpression(int64_t &Res) = 0; | |||
/// checkForValidSection - Ensure that we have a valid section set in the | ||||
/// streamer. Otherwise, report an error and switch to .text. | ||||
virtual void checkForValidSection() = 0; | ||||
}; | }; | |||
/// \brief Create an MCAsmParser instance. | /// \brief Create an MCAsmParser instance. | |||
MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, | MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, | |||
MCStreamer &, const MCAsmInfo &); | MCStreamer &, const MCAsmInfo &); | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 26 change blocks. | ||||
30 lines changed or deleted | 64 lines changed or added | |||
MCAsmParserExtension.h | MCAsmParserExtension.h | |||
---|---|---|---|---|
//===-- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks -------*- C++ -*- ===// | //===-- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks -------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCASMPARSEREXTENSION_H | #ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H | |||
#define LLVM_MC_MCASMPARSEREXTENSION_H | #define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H | |||
#include "llvm/MC/MCParser/MCAsmParser.h" | ||||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/MC/MCParser/MCAsmParser.h" | ||||
#include "llvm/Support/SMLoc.h" | #include "llvm/Support/SMLoc.h" | |||
namespace llvm { | namespace llvm { | |||
class Twine; | class Twine; | |||
/// \brief Generic interface for extending the MCAsmParser, | /// \brief Generic interface for extending the MCAsmParser, | |||
/// which is implemented by target and object file assembly parser | /// which is implemented by target and object file assembly parser | |||
/// implementations. | /// implementations. | |||
class MCAsmParserExtension { | class MCAsmParserExtension { | |||
MCAsmParserExtension(const MCAsmParserExtension &) LLVM_DELETED_FUNCTION; | MCAsmParserExtension(const MCAsmParserExtension &) LLVM_DELETED_FUNCTION; | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
MCAssembler.h | MCAssembler.h | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCASSEMBLER_H | #ifndef LLVM_MC_MCASSEMBLER_H | |||
#define LLVM_MC_MCASSEMBLER_H | #define LLVM_MC_MCASSEMBLER_H | |||
#include "llvm/MC/MCFixup.h" | ||||
#include "llvm/MC/MCInst.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/ADT/SmallString.h" | #include "llvm/ADT/SmallString.h" | |||
#include "llvm/ADT/ilist.h" | #include "llvm/ADT/ilist.h" | |||
#include "llvm/ADT/ilist_node.h" | #include "llvm/ADT/ilist_node.h" | |||
#include "llvm/MC/MCFixup.h" | ||||
#include "llvm/MC/MCInst.h" | ||||
#include "llvm/Support/Casting.h" | #include "llvm/Support/Casting.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <vector> // FIXME: Shouldn't be needed. | #include <vector> // FIXME: Shouldn't be needed. | |||
namespace llvm { | namespace llvm { | |||
class raw_ostream; | class raw_ostream; | |||
class MCAsmLayout; | class MCAsmLayout; | |||
class MCAssembler; | class MCAssembler; | |||
class MCContext; | class MCContext; | |||
class MCCodeEmitter; | class MCCodeEmitter; | |||
skipping to change at line 50 | skipping to change at line 50 | |||
class MCFragment : public ilist_node<MCFragment> { | class MCFragment : public ilist_node<MCFragment> { | |||
friend class MCAsmLayout; | friend class MCAsmLayout; | |||
MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION; | MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION; | |||
void operator=(const MCFragment&) LLVM_DELETED_FUNCTION; | void operator=(const MCFragment&) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
enum FragmentType { | enum FragmentType { | |||
FT_Align, | FT_Align, | |||
FT_Data, | FT_Data, | |||
FT_CompactEncodedInst, | ||||
FT_Fill, | FT_Fill, | |||
FT_Inst, | FT_Relaxable, | |||
FT_Org, | FT_Org, | |||
FT_Dwarf, | FT_Dwarf, | |||
FT_DwarfFrame, | FT_DwarfFrame, | |||
FT_LEB | FT_LEB | |||
}; | }; | |||
private: | private: | |||
FragmentType Kind; | FragmentType Kind; | |||
/// Parent - The data for the section this fragment is in. | /// Parent - The data for the section this fragment is in. | |||
skipping to change at line 102 | skipping to change at line 103 | |||
MCSectionData *getParent() const { return Parent; } | MCSectionData *getParent() const { return Parent; } | |||
void setParent(MCSectionData *Value) { Parent = Value; } | void setParent(MCSectionData *Value) { Parent = Value; } | |||
MCSymbolData *getAtom() const { return Atom; } | MCSymbolData *getAtom() const { return Atom; } | |||
void setAtom(MCSymbolData *Value) { Atom = Value; } | void setAtom(MCSymbolData *Value) { Atom = Value; } | |||
unsigned getLayoutOrder() const { return LayoutOrder; } | unsigned getLayoutOrder() const { return LayoutOrder; } | |||
void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } | void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } | |||
/// \brief Does this fragment have instructions emitted into it? By defau | ||||
lt | ||||
/// this is false, but specific fragment types may set it to true. | ||||
virtual bool hasInstructions() const { return false; } | ||||
/// \brief Should this fragment be placed at the end of an aligned bundle | ||||
? | ||||
virtual bool alignToBundleEnd() const { return false; } | ||||
virtual void setAlignToBundleEnd(bool V) { } | ||||
/// \brief Get the padding size that must be inserted before this fragmen | ||||
t. | ||||
/// Used for bundling. By default, no padding is inserted. | ||||
/// Note that padding size is restricted to 8 bits. This is an optimizati | ||||
on | ||||
/// to reduce the amount of space used for each fragment. In practice, la | ||||
rger | ||||
/// padding should never be required. | ||||
virtual uint8_t getBundlePadding() const { | ||||
return 0; | ||||
} | ||||
/// \brief Set the padding size for this fragment. By default it's a no-o | ||||
p, | ||||
/// and only some fragments have a meaningful implementation. | ||||
virtual void setBundlePadding(uint8_t N) { | ||||
} | ||||
void dump(); | void dump(); | |||
}; | }; | |||
class MCDataFragment : public MCFragment { | /// Interface implemented by fragments that contain encoded instructions an | |||
d/or | ||||
/// data. | ||||
/// | ||||
class MCEncodedFragment : public MCFragment { | ||||
virtual void anchor(); | virtual void anchor(); | |||
SmallString<32> Contents; | ||||
/// Fixups - The list of fixups in this fragment. | ||||
std::vector<MCFixup> Fixups; | ||||
uint8_t BundlePadding; | ||||
public: | public: | |||
typedef std::vector<MCFixup>::const_iterator const_fixup_iterator; | MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0) | |||
typedef std::vector<MCFixup>::iterator fixup_iterator; | : MCFragment(FType, SD), BundlePadding(0) | |||
{ | ||||
} | ||||
virtual ~MCEncodedFragment(); | ||||
virtual SmallVectorImpl<char> &getContents() = 0; | ||||
virtual const SmallVectorImpl<char> &getContents() const = 0; | ||||
virtual uint8_t getBundlePadding() const { | ||||
return BundlePadding; | ||||
} | ||||
virtual void setBundlePadding(uint8_t N) { | ||||
BundlePadding = N; | ||||
} | ||||
static bool classof(const MCFragment *F) { | ||||
MCFragment::FragmentType Kind = F->getKind(); | ||||
switch (Kind) { | ||||
default: | ||||
return false; | ||||
case MCFragment::FT_Relaxable: | ||||
case MCFragment::FT_CompactEncodedInst: | ||||
case MCFragment::FT_Data: | ||||
return true; | ||||
} | ||||
} | ||||
}; | ||||
/// Interface implemented by fragments that contain encoded instructions an | ||||
d/or | ||||
/// data and also have fixups registered. | ||||
/// | ||||
class MCEncodedFragmentWithFixups : public MCEncodedFragment { | ||||
virtual void anchor(); | ||||
public: | public: | |||
MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} | MCEncodedFragmentWithFixups(MCFragment::FragmentType FType, | |||
MCSectionData *SD = 0) | ||||
: MCEncodedFragment(FType, SD) | ||||
{ | ||||
} | ||||
/// @name Accessors | virtual ~MCEncodedFragmentWithFixups(); | |||
/// @{ | ||||
SmallString<32> &getContents() { return Contents; } | typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; | |||
const SmallString<32> &getContents() const { return Contents; } | typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; | |||
/// @} | virtual SmallVectorImpl<MCFixup> &getFixups() = 0; | |||
/// @name Fixup Access | virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0; | |||
/// @{ | ||||
virtual fixup_iterator fixup_begin() = 0; | ||||
virtual const_fixup_iterator fixup_begin() const = 0; | ||||
virtual fixup_iterator fixup_end() = 0; | ||||
virtual const_fixup_iterator fixup_end() const = 0; | ||||
void addFixup(MCFixup Fixup) { | static bool classof(const MCFragment *F) { | |||
// Enforce invariant that fixups are in offset order. | MCFragment::FragmentType Kind = F->getKind(); | |||
assert((Fixups.empty() || Fixup.getOffset() >= Fixups.back().getOffset( | return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; | |||
)) && | } | |||
"Fixups must be added in order!"); | }; | |||
Fixups.push_back(Fixup); | ||||
/// Fragment for data and encoded instructions. | ||||
/// | ||||
class MCDataFragment : public MCEncodedFragmentWithFixups { | ||||
virtual void anchor(); | ||||
/// \brief Does this fragment contain encoded instructions anywhere in it | ||||
? | ||||
bool HasInstructions; | ||||
/// \brief Should this fragment be aligned to the end of a bundle? | ||||
bool AlignToBundleEnd; | ||||
SmallVector<char, 32> Contents; | ||||
/// Fixups - The list of fixups in this fragment. | ||||
SmallVector<MCFixup, 4> Fixups; | ||||
public: | ||||
MCDataFragment(MCSectionData *SD = 0) | ||||
: MCEncodedFragmentWithFixups(FT_Data, SD), | ||||
HasInstructions(false), AlignToBundleEnd(false) | ||||
{ | ||||
} | } | |||
std::vector<MCFixup> &getFixups() { return Fixups; } | virtual SmallVectorImpl<char> &getContents() { return Contents; } | |||
const std::vector<MCFixup> &getFixups() const { return Fixups; } | virtual const SmallVectorImpl<char> &getContents() const { return Content | |||
s; } | ||||
SmallVectorImpl<MCFixup> &getFixups() { | ||||
return Fixups; | ||||
} | ||||
const SmallVectorImpl<MCFixup> &getFixups() const { | ||||
return Fixups; | ||||
} | ||||
virtual bool hasInstructions() const { return HasInstructions; } | ||||
virtual void setHasInstructions(bool V) { HasInstructions = V; } | ||||
virtual bool alignToBundleEnd() const { return AlignToBundleEnd; } | ||||
virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } | ||||
fixup_iterator fixup_begin() { return Fixups.begin(); } | fixup_iterator fixup_begin() { return Fixups.begin(); } | |||
const_fixup_iterator fixup_begin() const { return Fixups.begin(); } | const_fixup_iterator fixup_begin() const { return Fixups.begin(); } | |||
fixup_iterator fixup_end() {return Fixups.end();} | fixup_iterator fixup_end() {return Fixups.end();} | |||
const_fixup_iterator fixup_end() const {return Fixups.end();} | const_fixup_iterator fixup_end() const {return Fixups.end();} | |||
size_t fixup_size() const { return Fixups.size(); } | static bool classof(const MCFragment *F) { | |||
return F->getKind() == MCFragment::FT_Data; | ||||
} | ||||
}; | ||||
/// @} | /// This is a compact (memory-size-wise) fragment for holding an encoded | |||
/// instruction (non-relaxable) that has no fixups registered. When applica | ||||
ble, | ||||
/// it can be used instead of MCDataFragment and lead to lower memory | ||||
/// consumption. | ||||
/// | ||||
class MCCompactEncodedInstFragment : public MCEncodedFragment { | ||||
virtual void anchor(); | ||||
/// \brief Should this fragment be aligned to the end of a bundle? | ||||
bool AlignToBundleEnd; | ||||
SmallVector<char, 4> Contents; | ||||
public: | ||||
MCCompactEncodedInstFragment(MCSectionData *SD = 0) | ||||
: MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false) | ||||
{ | ||||
} | ||||
virtual bool hasInstructions() const { | ||||
return true; | ||||
} | ||||
virtual SmallVectorImpl<char> &getContents() { return Contents; } | ||||
virtual const SmallVectorImpl<char> &getContents() const { return Content | ||||
s; } | ||||
virtual bool alignToBundleEnd() const { return AlignToBundleEnd; } | ||||
virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } | ||||
static bool classof(const MCFragment *F) { | static bool classof(const MCFragment *F) { | |||
return F->getKind() == MCFragment::FT_Data; | return F->getKind() == MCFragment::FT_CompactEncodedInst; | |||
} | } | |||
}; | }; | |||
// FIXME: This current incarnation of MCInstFragment doesn't make much sens | /// A relaxable fragment holds on to its MCInst, since it may need to be | |||
e, as | /// relaxed during the assembler layout and relaxation stage. | |||
// it is almost entirely a duplicate of MCDataFragment. If we decide to sti | /// | |||
ck | class MCRelaxableFragment : public MCEncodedFragmentWithFixups { | |||
// with this approach (as opposed to making MCInstFragment a very light wei | ||||
ght | ||||
// object with just the MCInst and a code size, then we should just change | ||||
// MCDataFragment to have an optional MCInst at its end. | ||||
class MCInstFragment : public MCFragment { | ||||
virtual void anchor(); | virtual void anchor(); | |||
/// Inst - The instruction this is a fragment for. | /// Inst - The instruction this is a fragment for. | |||
MCInst Inst; | MCInst Inst; | |||
/// Code - Binary data for the currently encoded instruction. | /// Contents - Binary data for the currently encoded instruction. | |||
SmallString<8> Code; | SmallVector<char, 8> Contents; | |||
/// Fixups - The list of fixups in this fragment. | /// Fixups - The list of fixups in this fragment. | |||
SmallVector<MCFixup, 1> Fixups; | SmallVector<MCFixup, 1> Fixups; | |||
public: | public: | |||
typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; | MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0) | |||
typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; | : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) { | |||
public: | ||||
MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0) | ||||
: MCFragment(FT_Inst, SD), Inst(_Inst) { | ||||
} | } | |||
/// @name Accessors | virtual SmallVectorImpl<char> &getContents() { return Contents; } | |||
/// @{ | virtual const SmallVectorImpl<char> &getContents() const { return Content | |||
s; } | ||||
SmallVectorImpl<char> &getCode() { return Code; } | ||||
const SmallVectorImpl<char> &getCode() const { return Code; } | ||||
unsigned getInstSize() const { return Code.size(); } | ||||
MCInst &getInst() { return Inst; } | ||||
const MCInst &getInst() const { return Inst; } | const MCInst &getInst() const { return Inst; } | |||
void setInst(const MCInst& Value) { Inst = Value; } | void setInst(const MCInst& Value) { Inst = Value; } | |||
/// @} | SmallVectorImpl<MCFixup> &getFixups() { | |||
/// @name Fixup Access | return Fixups; | |||
/// @{ | } | |||
SmallVectorImpl<MCFixup> &getFixups() { return Fixups; } | const SmallVectorImpl<MCFixup> &getFixups() const { | |||
const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; } | return Fixups; | |||
} | ||||
virtual bool hasInstructions() const { return true; } | ||||
fixup_iterator fixup_begin() { return Fixups.begin(); } | fixup_iterator fixup_begin() { return Fixups.begin(); } | |||
const_fixup_iterator fixup_begin() const { return Fixups.begin(); } | const_fixup_iterator fixup_begin() const { return Fixups.begin(); } | |||
fixup_iterator fixup_end() {return Fixups.end();} | fixup_iterator fixup_end() {return Fixups.end();} | |||
const_fixup_iterator fixup_end() const {return Fixups.end();} | const_fixup_iterator fixup_end() const {return Fixups.end();} | |||
size_t fixup_size() const { return Fixups.size(); } | ||||
/// @} | ||||
static bool classof(const MCFragment *F) { | static bool classof(const MCFragment *F) { | |||
return F->getKind() == MCFragment::FT_Inst; | return F->getKind() == MCFragment::FT_Relaxable; | |||
} | } | |||
}; | }; | |||
class MCAlignFragment : public MCFragment { | class MCAlignFragment : public MCFragment { | |||
virtual void anchor(); | virtual void anchor(); | |||
/// Alignment - The alignment to ensure, in bytes. | /// Alignment - The alignment to ensure, in bytes. | |||
unsigned Alignment; | unsigned Alignment; | |||
/// Value - Value to use for filling padding bytes. | /// Value - Value to use for filling padding bytes. | |||
skipping to change at line 341 | skipping to change at line 454 | |||
virtual void anchor(); | virtual void anchor(); | |||
/// Value - The value this fragment should contain. | /// Value - The value this fragment should contain. | |||
const MCExpr *Value; | const MCExpr *Value; | |||
/// IsSigned - True if this is a sleb128, false if uleb128. | /// IsSigned - True if this is a sleb128, false if uleb128. | |||
bool IsSigned; | bool IsSigned; | |||
SmallString<8> Contents; | SmallString<8> Contents; | |||
public: | public: | |||
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD) | MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD = 0 ) | |||
: MCFragment(FT_LEB, SD), | : MCFragment(FT_LEB, SD), | |||
Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); } | Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); } | |||
/// @name Accessors | /// @name Accessors | |||
/// @{ | /// @{ | |||
const MCExpr &getValue() const { return *Value; } | const MCExpr &getValue() const { return *Value; } | |||
bool isSigned() const { return IsSigned; } | bool isSigned() const { return IsSigned; } | |||
skipping to change at line 377 | skipping to change at line 490 | |||
int64_t LineDelta; | int64_t LineDelta; | |||
/// AddrDelta - The expression for the difference of the two symbols that | /// AddrDelta - The expression for the difference of the two symbols that | |||
/// make up the address delta between two .loc dwarf directives. | /// make up the address delta between two .loc dwarf directives. | |||
const MCExpr *AddrDelta; | const MCExpr *AddrDelta; | |||
SmallString<8> Contents; | SmallString<8> Contents; | |||
public: | public: | |||
MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, | MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, | |||
MCSectionData *SD) | MCSectionData *SD = 0) | |||
: MCFragment(FT_Dwarf, SD), | : MCFragment(FT_Dwarf, SD), | |||
LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0) ; } | LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0) ; } | |||
/// @name Accessors | /// @name Accessors | |||
/// @{ | /// @{ | |||
int64_t getLineDelta() const { return LineDelta; } | int64_t getLineDelta() const { return LineDelta; } | |||
const MCExpr &getAddrDelta() const { return *AddrDelta; } | const MCExpr &getAddrDelta() const { return *AddrDelta; } | |||
skipping to change at line 408 | skipping to change at line 521 | |||
class MCDwarfCallFrameFragment : public MCFragment { | class MCDwarfCallFrameFragment : public MCFragment { | |||
virtual void anchor(); | virtual void anchor(); | |||
/// AddrDelta - The expression for the difference of the two symbols that | /// AddrDelta - The expression for the difference of the two symbols that | |||
/// make up the address delta between two .cfi_* dwarf directives. | /// make up the address delta between two .cfi_* dwarf directives. | |||
const MCExpr *AddrDelta; | const MCExpr *AddrDelta; | |||
SmallString<8> Contents; | SmallString<8> Contents; | |||
public: | public: | |||
MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD) | MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD = 0 ) | |||
: MCFragment(FT_DwarfFrame, SD), | : MCFragment(FT_DwarfFrame, SD), | |||
AddrDelta(&_AddrDelta) { Contents.push_back(0); } | AddrDelta(&_AddrDelta) { Contents.push_back(0); } | |||
/// @name Accessors | /// @name Accessors | |||
/// @{ | /// @{ | |||
const MCExpr &getAddrDelta() const { return *AddrDelta; } | const MCExpr &getAddrDelta() const { return *AddrDelta; } | |||
SmallString<8> &getContents() { return Contents; } | SmallString<8> &getContents() { return Contents; } | |||
const SmallString<8> &getContents() const { return Contents; } | const SmallString<8> &getContents() const { return Contents; } | |||
skipping to change at line 445 | skipping to change at line 558 | |||
public: | public: | |||
typedef iplist<MCFragment> FragmentListType; | typedef iplist<MCFragment> FragmentListType; | |||
typedef FragmentListType::const_iterator const_iterator; | typedef FragmentListType::const_iterator const_iterator; | |||
typedef FragmentListType::iterator iterator; | typedef FragmentListType::iterator iterator; | |||
typedef FragmentListType::const_reverse_iterator const_reverse_iterator; | typedef FragmentListType::const_reverse_iterator const_reverse_iterator; | |||
typedef FragmentListType::reverse_iterator reverse_iterator; | typedef FragmentListType::reverse_iterator reverse_iterator; | |||
/// \brief Express the state of bundle locked groups while emitting code. | ||||
enum BundleLockStateType { | ||||
NotBundleLocked, | ||||
BundleLocked, | ||||
BundleLockedAlignToEnd | ||||
}; | ||||
private: | private: | |||
FragmentListType Fragments; | FragmentListType Fragments; | |||
const MCSection *Section; | const MCSection *Section; | |||
/// Ordinal - The section index in the assemblers section list. | /// Ordinal - The section index in the assemblers section list. | |||
unsigned Ordinal; | unsigned Ordinal; | |||
/// LayoutOrder - The index of this section in the layout order. | /// LayoutOrder - The index of this section in the layout order. | |||
unsigned LayoutOrder; | unsigned LayoutOrder; | |||
/// Alignment - The maximum alignment seen in this section. | /// Alignment - The maximum alignment seen in this section. | |||
unsigned Alignment; | unsigned Alignment; | |||
/// \brief Keeping track of bundle-locked state. | ||||
BundleLockStateType BundleLockState; | ||||
/// \brief We've seen a bundle_lock directive but not its first instructi | ||||
on | ||||
/// yet. | ||||
bool BundleGroupBeforeFirstInst; | ||||
/// @name Assembler Backend Data | /// @name Assembler Backend Data | |||
/// @{ | /// @{ | |||
// | // | |||
// FIXME: This could all be kept private to the assembler implementation. | // FIXME: This could all be kept private to the assembler implementation. | |||
/// HasInstructions - Whether this section has had instructions emitted i nto | /// HasInstructions - Whether this section has had instructions emitted i nto | |||
/// it. | /// it. | |||
unsigned HasInstructions : 1; | unsigned HasInstructions : 1; | |||
/// Mapping from subsection number to insertion point for subsection numb | ||||
ers | ||||
/// below that number. | ||||
SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap; | ||||
/// @} | /// @} | |||
public: | public: | |||
// Only for use as sentinel. | // Only for use as sentinel. | |||
MCSectionData(); | MCSectionData(); | |||
MCSectionData(const MCSection &Section, MCAssembler *A = 0); | MCSectionData(const MCSection &Section, MCAssembler *A = 0); | |||
const MCSection &getSection() const { return *Section; } | const MCSection &getSection() const { return *Section; } | |||
unsigned getAlignment() const { return Alignment; } | unsigned getAlignment() const { return Alignment; } | |||
skipping to change at line 510 | skipping to change at line 640 | |||
reverse_iterator rbegin() { return Fragments.rbegin(); } | reverse_iterator rbegin() { return Fragments.rbegin(); } | |||
const_reverse_iterator rbegin() const { return Fragments.rbegin(); } | const_reverse_iterator rbegin() const { return Fragments.rbegin(); } | |||
reverse_iterator rend() { return Fragments.rend(); } | reverse_iterator rend() { return Fragments.rend(); } | |||
const_reverse_iterator rend() const { return Fragments.rend(); } | const_reverse_iterator rend() const { return Fragments.rend(); } | |||
size_t size() const { return Fragments.size(); } | size_t size() const { return Fragments.size(); } | |||
bool empty() const { return Fragments.empty(); } | bool empty() const { return Fragments.empty(); } | |||
iterator getSubsectionInsertionPoint(unsigned Subsection); | ||||
bool isBundleLocked() const { | ||||
return BundleLockState != NotBundleLocked; | ||||
} | ||||
BundleLockStateType getBundleLockState() const { | ||||
return BundleLockState; | ||||
} | ||||
void setBundleLockState(BundleLockStateType NewState) { | ||||
BundleLockState = NewState; | ||||
} | ||||
bool isBundleGroupBeforeFirstInst() const { | ||||
return BundleGroupBeforeFirstInst; | ||||
} | ||||
void setBundleGroupBeforeFirstInst(bool IsFirst) { | ||||
BundleGroupBeforeFirstInst = IsFirst; | ||||
} | ||||
void dump(); | void dump(); | |||
/// @} | /// @} | |||
}; | }; | |||
// FIXME: Same concerns as with SectionData. | // FIXME: Same concerns as with SectionData. | |||
class MCSymbolData : public ilist_node<MCSymbolData> { | class MCSymbolData : public ilist_node<MCSymbolData> { | |||
public: | public: | |||
const MCSymbol *Symbol; | const MCSymbol *Symbol; | |||
skipping to change at line 705 | skipping to change at line 857 | |||
DenseMap<const MCSection*, MCSectionData*> SectionMap; | DenseMap<const MCSection*, MCSectionData*> SectionMap; | |||
/// The map of symbols to their associated assembler backend data. | /// The map of symbols to their associated assembler backend data. | |||
// | // | |||
// FIXME: Avoid this indirection? | // FIXME: Avoid this indirection? | |||
DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; | DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; | |||
std::vector<IndirectSymbolData> IndirectSymbols; | std::vector<IndirectSymbolData> IndirectSymbols; | |||
std::vector<DataRegionData> DataRegions; | std::vector<DataRegionData> DataRegions; | |||
/// The list of linker options to propagate into the object file. | ||||
std::vector<std::vector<std::string> > LinkerOptions; | ||||
/// The set of function symbols for which a .thumb_func directive has | /// The set of function symbols for which a .thumb_func directive has | |||
/// been seen. | /// been seen. | |||
// | // | |||
// FIXME: We really would like this in target specific code rather than | // FIXME: We really would like this in target specific code rather than | |||
// here. Maybe when the relocation stuff moves to target specific, | // here. Maybe when the relocation stuff moves to target specific, | |||
// this can go with it? The streamer would need some target specific | // this can go with it? The streamer would need some target specific | |||
// refactoring too. | // refactoring too. | |||
SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; | SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; | |||
/// \brief The bundle alignment size currently set in the assembler. | ||||
/// | ||||
/// By default it's 0, which means bundling is disabled. | ||||
unsigned BundleAlignSize; | ||||
unsigned RelaxAll : 1; | unsigned RelaxAll : 1; | |||
unsigned NoExecStack : 1; | unsigned NoExecStack : 1; | |||
unsigned SubsectionsViaSymbols : 1; | unsigned SubsectionsViaSymbols : 1; | |||
/// ELF specific e_header flags | ||||
// It would be good if there were an MCELFAssembler class to hold this. | ||||
// ELF header flags are used both by the integrated and standalone assemb | ||||
lers. | ||||
// Access to the flags is necessary in cases where assembler directives a | ||||
ffect | ||||
// which flags to be set. | ||||
unsigned ELFHeaderEFlags; | ||||
private: | private: | |||
/// Evaluate a fixup to a relocatable expression and the value which shou ld be | /// Evaluate a fixup to a relocatable expression and the value which shou ld be | |||
/// placed into the fixup. | /// placed into the fixup. | |||
/// | /// | |||
/// \param Layout The layout to use for evaluation. | /// \param Layout The layout to use for evaluation. | |||
/// \param Fixup The fixup to evaluate. | /// \param Fixup The fixup to evaluate. | |||
/// \param DF The fragment the fixup is inside. | /// \param DF The fragment the fixup is inside. | |||
/// \param Target [out] On return, the relocatable expression the fixup | /// \param Target [out] On return, the relocatable expression the fixup | |||
/// evaluates to. | /// evaluates to. | |||
/// \param Value [out] On return, the value of the fixup as currently lai d | /// \param Value [out] On return, the value of the fixup as currently lai d | |||
/// out. | /// out. | |||
/// \return Whether the fixup value was fully resolved. This is true if t he | /// \return Whether the fixup value was fully resolved. This is true if t he | |||
/// \p Value result is fixed, otherwise the value may change due to | /// \p Value result is fixed, otherwise the value may change due to | |||
/// relocation. | /// relocation. | |||
bool evaluateFixup(const MCAsmLayout &Layout, | bool evaluateFixup(const MCAsmLayout &Layout, | |||
const MCFixup &Fixup, const MCFragment *DF, | const MCFixup &Fixup, const MCFragment *DF, | |||
MCValue &Target, uint64_t &Value) const; | MCValue &Target, uint64_t &Value) const; | |||
/// Check whether a fixup can be satisfied, or whether it needs to be rel axed | /// Check whether a fixup can be satisfied, or whether it needs to be rel axed | |||
/// (increased in size, in order to hold its value correctly). | /// (increased in size, in order to hold its value correctly). | |||
bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF, | bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF, | |||
const MCAsmLayout &Layout) const; | const MCAsmLayout &Layout) const; | |||
/// Check whether the given fragment needs relaxation. | /// Check whether the given fragment needs relaxation. | |||
bool fragmentNeedsRelaxation(const MCInstFragment *IF, | bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF, | |||
const MCAsmLayout &Layout) const; | const MCAsmLayout &Layout) const; | |||
/// layoutOnce - Perform one layout iteration and return true if any offs ets | /// \brief Perform one layout iteration and return true if any offsets | |||
/// were adjusted. | /// were adjusted. | |||
bool layoutOnce(MCAsmLayout &Layout); | bool layoutOnce(MCAsmLayout &Layout); | |||
/// \brief Perform one layout iteration of the given section and return t | ||||
rue | ||||
/// if any offsets were adjusted. | ||||
bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); | bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); | |||
bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); | bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF); | |||
bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); | bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); | |||
bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF) ; | bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF) ; | |||
bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, | bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, | |||
MCDwarfCallFrameFragment &DF); | MCDwarfCallFrameFragment &DF); | |||
/// finishLayout - Finalize a layout, including fragment lowering. | /// finishLayout - Finalize a layout, including fragment lowering. | |||
void finishLayout(MCAsmLayout &Layout); | void finishLayout(MCAsmLayout &Layout); | |||
skipping to change at line 793 | skipping to change at line 962 | |||
const MCAsmLayout &Layout) const; | const MCAsmLayout &Layout) const; | |||
/// Check whether a given symbol has been flagged with .thumb_func. | /// Check whether a given symbol has been flagged with .thumb_func. | |||
bool isThumbFunc(const MCSymbol *Func) const { | bool isThumbFunc(const MCSymbol *Func) const { | |||
return ThumbFuncs.count(Func); | return ThumbFuncs.count(Func); | |||
} | } | |||
/// Flag a function symbol as the target of a .thumb_func directive. | /// Flag a function symbol as the target of a .thumb_func directive. | |||
void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } | void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } | |||
/// ELF e_header flags | ||||
unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;} | ||||
void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;} | ||||
public: | public: | |||
/// Construct a new assembler instance. | /// Construct a new assembler instance. | |||
/// | /// | |||
/// \param OS The stream to output to. | /// \param OS The stream to output to. | |||
// | // | |||
// FIXME: How are we going to parameterize this? Two obvious options are stay | // FIXME: How are we going to parameterize this? Two obvious options are stay | |||
// concrete and require clients to pass in a target like object. The othe r | // concrete and require clients to pass in a target like object. The othe r | |||
// option is to make this abstract, and have targets provide concrete | // option is to make this abstract, and have targets provide concrete | |||
// implementations as we do with AsmParser. | // implementations as we do with AsmParser. | |||
MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, | MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, | |||
MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, | MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, | |||
raw_ostream &OS); | raw_ostream &OS); | |||
~MCAssembler(); | ~MCAssembler(); | |||
/// Reuse an assembler instance | ||||
/// | ||||
void reset(); | ||||
MCContext &getContext() const { return Context; } | MCContext &getContext() const { return Context; } | |||
MCAsmBackend &getBackend() const { return Backend; } | MCAsmBackend &getBackend() const { return Backend; } | |||
MCCodeEmitter &getEmitter() const { return Emitter; } | MCCodeEmitter &getEmitter() const { return Emitter; } | |||
MCObjectWriter &getWriter() const { return Writer; } | MCObjectWriter &getWriter() const { return Writer; } | |||
/// Finish - Do final processing and write the object to the output strea m. | /// Finish - Do final processing and write the object to the output strea m. | |||
/// \p Writer is used for custom object writer (as the MCJIT does), | /// \p Writer is used for custom object writer (as the MCJIT does), | |||
skipping to change at line 834 | skipping to change at line 1011 | |||
void setSubsectionsViaSymbols(bool Value) { | void setSubsectionsViaSymbols(bool Value) { | |||
SubsectionsViaSymbols = Value; | SubsectionsViaSymbols = Value; | |||
} | } | |||
bool getRelaxAll() const { return RelaxAll; } | bool getRelaxAll() const { return RelaxAll; } | |||
void setRelaxAll(bool Value) { RelaxAll = Value; } | void setRelaxAll(bool Value) { RelaxAll = Value; } | |||
bool getNoExecStack() const { return NoExecStack; } | bool getNoExecStack() const { return NoExecStack; } | |||
void setNoExecStack(bool Value) { NoExecStack = Value; } | void setNoExecStack(bool Value) { NoExecStack = Value; } | |||
bool isBundlingEnabled() const { | ||||
return BundleAlignSize != 0; | ||||
} | ||||
unsigned getBundleAlignSize() const { | ||||
return BundleAlignSize; | ||||
} | ||||
void setBundleAlignSize(unsigned Size) { | ||||
assert((Size == 0 || !(Size & (Size - 1))) && | ||||
"Expect a power-of-two bundle align size"); | ||||
BundleAlignSize = Size; | ||||
} | ||||
/// @name Section List Access | /// @name Section List Access | |||
/// @{ | /// @{ | |||
const SectionDataListType &getSectionList() const { return Sections; } | const SectionDataListType &getSectionList() const { return Sections; } | |||
SectionDataListType &getSectionList() { return Sections; } | SectionDataListType &getSectionList() { return Sections; } | |||
iterator begin() { return Sections.begin(); } | iterator begin() { return Sections.begin(); } | |||
const_iterator begin() const { return Sections.begin(); } | const_iterator begin() const { return Sections.begin(); } | |||
iterator end() { return Sections.end(); } | iterator end() { return Sections.end(); } | |||
skipping to change at line 891 | skipping to change at line 1082 | |||
indirect_symbol_iterator indirect_symbol_end() { | indirect_symbol_iterator indirect_symbol_end() { | |||
return IndirectSymbols.end(); | return IndirectSymbols.end(); | |||
} | } | |||
const_indirect_symbol_iterator indirect_symbol_end() const { | const_indirect_symbol_iterator indirect_symbol_end() const { | |||
return IndirectSymbols.end(); | return IndirectSymbols.end(); | |||
} | } | |||
size_t indirect_symbol_size() const { return IndirectSymbols.size(); } | size_t indirect_symbol_size() const { return IndirectSymbols.size(); } | |||
/// @} | /// @} | |||
/// @name Linker Option List Access | ||||
/// @{ | ||||
std::vector<std::vector<std::string> > &getLinkerOptions() { | ||||
return LinkerOptions; | ||||
} | ||||
/// @} | ||||
/// @name Data Region List Access | /// @name Data Region List Access | |||
/// @{ | /// @{ | |||
// FIXME: This is a total hack, this should not be here. Once things are | // FIXME: This is a total hack, this should not be here. Once things are | |||
// factored so that the streamer has direct access to the .o writer, it c an | // factored so that the streamer has direct access to the .o writer, it c an | |||
// disappear. | // disappear. | |||
std::vector<DataRegionData> &getDataRegions() { | std::vector<DataRegionData> &getDataRegions() { | |||
return DataRegions; | return DataRegions; | |||
} | } | |||
End of changes. 47 change blocks. | ||||
72 lines changed or deleted | 285 lines changed or added | |||
MCAtom.h | MCAtom.h | |||
---|---|---|---|---|
skipping to change at line 49 | skipping to change at line 49 | |||
uint64_t Begin, End; | uint64_t Begin, End; | |||
std::vector<std::pair<uint64_t, MCInst> > Text; | std::vector<std::pair<uint64_t, MCInst> > Text; | |||
std::vector<MCData> Data; | std::vector<MCData> Data; | |||
// Private constructor - only callable by MCModule | // Private constructor - only callable by MCModule | |||
MCAtom(AtomType T, MCModule *P, uint64_t B, uint64_t E) | MCAtom(AtomType T, MCModule *P, uint64_t B, uint64_t E) | |||
: Type(T), Parent(P), Begin(B), End(E) { } | : Type(T), Parent(P), Begin(B), End(E) { } | |||
public: | public: | |||
bool isTextAtom() { return Type == TextAtom; } | bool isTextAtom() const { return Type == TextAtom; } | |||
bool isDataAtom() { return Type == DataAtom; } | bool isDataAtom() const { return Type == DataAtom; } | |||
void addInst(const MCInst &I, uint64_t Address, unsigned Size); | void addInst(const MCInst &I, uint64_t Address, unsigned Size); | |||
void addData(const MCData &D); | void addData(const MCData &D); | |||
/// split - Splits the atom in two at a given address, which must align w ith | /// split - Splits the atom in two at a given address, which must align w ith | |||
/// and instruction boundary if this is a TextAtom. Returns the newly cr eated | /// and instruction boundary if this is a TextAtom. Returns the newly cr eated | |||
/// atom representing the high part of the split. | /// atom representing the high part of the split. | |||
MCAtom *split(uint64_t SplitPt); | MCAtom *split(uint64_t SplitPt); | |||
/// truncate - Truncates an atom so that TruncPt is the last byte address | /// truncate - Truncates an atom so that TruncPt is the last byte address | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
MCCodeEmitter.h | MCCodeEmitter.h | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
class MCCodeEmitter { | class MCCodeEmitter { | |||
private: | private: | |||
MCCodeEmitter(const MCCodeEmitter &) LLVM_DELETED_FUNCTION; | MCCodeEmitter(const MCCodeEmitter &) LLVM_DELETED_FUNCTION; | |||
void operator=(const MCCodeEmitter &) LLVM_DELETED_FUNCTION; | void operator=(const MCCodeEmitter &) LLVM_DELETED_FUNCTION; | |||
protected: // Can only create subclasses. | protected: // Can only create subclasses. | |||
MCCodeEmitter(); | MCCodeEmitter(); | |||
public: | public: | |||
virtual ~MCCodeEmitter(); | virtual ~MCCodeEmitter(); | |||
/// Lifetime management | ||||
virtual void reset() { } | ||||
/// EncodeInstruction - Encode the given \p Inst to bytes on the output | /// EncodeInstruction - Encode the given \p Inst to bytes on the output | |||
/// stream \p OS. | /// stream \p OS. | |||
virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, | virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, | |||
SmallVectorImpl<MCFixup> &Fixups) const = 0; | SmallVectorImpl<MCFixup> &Fixups) const = 0; | |||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 3 lines changed or added | |||
MCContext.h | MCContext.h | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCCONTEXT_H | #ifndef LLVM_MC_MCCONTEXT_H | |||
#define LLVM_MC_MCCONTEXT_H | #define LLVM_MC_MCCONTEXT_H | |||
#include "llvm/MC/SectionKind.h" | ||||
#include "llvm/MC/MCDwarf.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/StringMap.h" | #include "llvm/ADT/StringMap.h" | |||
#include "llvm/MC/MCDwarf.h" | ||||
#include "llvm/MC/SectionKind.h" | ||||
#include "llvm/Support/Allocator.h" | #include "llvm/Support/Allocator.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
#include <map> | ||||
#include <vector> // FIXME: Shouldn't be needed. | #include <vector> // FIXME: Shouldn't be needed. | |||
namespace llvm { | namespace llvm { | |||
class MCAsmInfo; | class MCAsmInfo; | |||
class MCExpr; | class MCExpr; | |||
class MCSection; | class MCSection; | |||
class MCSymbol; | class MCSymbol; | |||
class MCLabel; | class MCLabel; | |||
class MCDwarfFile; | class MCDwarfFile; | |||
class MCDwarfLoc; | class MCDwarfLoc; | |||
skipping to change at line 97 | skipping to change at line 99 | |||
/// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_uniqu e | /// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_uniqu e | |||
/// directive is used or it is an error. | /// directive is used or it is an error. | |||
char *SecureLogFile; | char *SecureLogFile; | |||
/// The stream that gets written to for the .secure_log_unique directiv e. | /// The stream that gets written to for the .secure_log_unique directiv e. | |||
raw_ostream *SecureLog; | raw_ostream *SecureLog; | |||
/// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to | /// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to | |||
/// catch errors if .secure_log_unique appears twice without | /// catch errors if .secure_log_unique appears twice without | |||
/// .secure_log_reset appearing between them. | /// .secure_log_reset appearing between them. | |||
bool SecureLogUsed; | bool SecureLogUsed; | |||
/// The compilation directory to use for DW_AT_comp_dir. | ||||
std::string CompilationDir; | ||||
/// The main file name if passed in explicitly. | ||||
std::string MainFileName; | ||||
/// The dwarf file and directory tables from the dwarf .file directive. | /// The dwarf file and directory tables from the dwarf .file directive. | |||
std::vector<MCDwarfFile *> MCDwarfFiles; | /// We now emit a line table for each compile unit. To reduce the prolo | |||
std::vector<StringRef> MCDwarfDirs; | gue | |||
/// size of each line table, the files and directories used by each com | ||||
pile | ||||
/// unit are separated. | ||||
typedef std::map<unsigned, SmallVector<MCDwarfFile *, 4> > MCDwarfFiles | ||||
Map; | ||||
MCDwarfFilesMap MCDwarfFilesCUMap; | ||||
std::map<unsigned, SmallVector<StringRef, 4> > MCDwarfDirsCUMap; | ||||
/// The current dwarf line information from the last dwarf .loc directi ve. | /// The current dwarf line information from the last dwarf .loc directi ve. | |||
MCDwarfLoc CurrentDwarfLoc; | MCDwarfLoc CurrentDwarfLoc; | |||
bool DwarfLocSeen; | bool DwarfLocSeen; | |||
/// Generate dwarf debugging info for assembly source files. | /// Generate dwarf debugging info for assembly source files. | |||
bool GenDwarfForAssembly; | bool GenDwarfForAssembly; | |||
/// The current dwarf file number when generate dwarf debugging info fo r | /// The current dwarf file number when generate dwarf debugging info fo r | |||
/// assembly source files. | /// assembly source files. | |||
skipping to change at line 126 | skipping to change at line 138 | |||
MCSymbol *GenDwarfSectionStartSym, *GenDwarfSectionEndSym; | MCSymbol *GenDwarfSectionStartSym, *GenDwarfSectionEndSym; | |||
/// The information gathered from labels that will have dwarf label | /// The information gathered from labels that will have dwarf label | |||
/// entries when generating dwarf assembly source files. | /// entries when generating dwarf assembly source files. | |||
std::vector<const MCGenDwarfLabelEntry *> MCGenDwarfLabelEntries; | std::vector<const MCGenDwarfLabelEntry *> MCGenDwarfLabelEntries; | |||
/// The string to embed in the debug information for the compile unit, if | /// The string to embed in the debug information for the compile unit, if | |||
/// non-empty. | /// non-empty. | |||
StringRef DwarfDebugFlags; | StringRef DwarfDebugFlags; | |||
/// The string to embed in as the dwarf AT_producer for the compile uni | ||||
t, if | ||||
/// non-empty. | ||||
StringRef DwarfDebugProducer; | ||||
/// Honor temporary labels, this is useful for debugging semantic | /// Honor temporary labels, this is useful for debugging semantic | |||
/// differences between temporary and non-temporary labels (primarily o n | /// differences between temporary and non-temporary labels (primarily o n | |||
/// Darwin). | /// Darwin). | |||
bool AllowTemporaryLabels; | bool AllowTemporaryLabels; | |||
/// The dwarf line information from the .loc directives for the section s | /// The dwarf line information from the .loc directives for the section s | |||
/// with assembled machine instructions have after seeing .loc directiv es. | /// with assembled machine instructions have after seeing .loc directiv es. | |||
DenseMap<const MCSection *, MCLineSection *> MCLineSections; | DenseMap<const MCSection *, MCLineSection *> MCLineSections; | |||
/// We need a deterministic iteration order, so we remember the order | /// We need a deterministic iteration order, so we remember the order | |||
/// the elements were added. | /// the elements were added. | |||
std::vector<const MCSection *> MCLineSectionOrder; | std::vector<const MCSection *> MCLineSectionOrder; | |||
/// The Compile Unit ID that we are currently processing. | ||||
unsigned DwarfCompileUnitID; | ||||
/// The line table start symbol for each Compile Unit. | ||||
DenseMap<unsigned, MCSymbol *> MCLineTableSymbols; | ||||
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; | void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; | |||
/// Do automatic reset in destructor | ||||
bool AutoReset; | ||||
MCSymbol *CreateSymbol(StringRef Name); | MCSymbol *CreateSymbol(StringRef Name); | |||
public: | public: | |||
explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, | explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, | |||
const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = | const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = | |||
0); | 0, | |||
bool DoAutoReset = true); | ||||
~MCContext(); | ~MCContext(); | |||
const SourceMgr *getSourceManager() const { return SrcMgr; } | 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; } | const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; } | |||
void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value ; } | void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value ; } | |||
/// @name Module Lifetime Management | ||||
/// @{ | ||||
/// reset - return object to right after construction state to prepare | ||||
/// to process a new module | ||||
void reset(); | ||||
/// @} | ||||
/// @name Symbol Management | /// @name Symbol Management | |||
/// @{ | /// @{ | |||
/// CreateTempSymbol - Create and return a new assembler temporary symb ol | /// CreateTempSymbol - Create and return a new assembler temporary symb ol | |||
/// with a unique but unspecified name. | /// with a unique but unspecified name. | |||
MCSymbol *CreateTempSymbol(); | MCSymbol *CreateTempSymbol(); | |||
/// getUniqueSymbolID() - Return a unique identifier for use in constru cting | /// getUniqueSymbolID() - Return a unique identifier for use in constru cting | |||
/// symbol names. | /// symbol names. | |||
unsigned getUniqueSymbolID() { return NextUniqueID++; } | unsigned getUniqueSymbolID() { return NextUniqueID++; } | |||
skipping to change at line 237 | skipping to change at line 270 | |||
const MCSection *getCOFFSection(StringRef Section, unsigned Characteris tics, | const MCSection *getCOFFSection(StringRef Section, unsigned Characteris tics, | |||
SectionKind Kind) { | SectionKind Kind) { | |||
return getCOFFSection (Section, Characteristics, 0, Kind); | return getCOFFSection (Section, Characteristics, 0, Kind); | |||
} | } | |||
/// @} | /// @} | |||
/// @name Dwarf Management | /// @name Dwarf Management | |||
/// @{ | /// @{ | |||
/// \brief Get the compilation directory for DW_AT_comp_dir | ||||
/// This can be overridden by clients which want to control the reporte | ||||
d | ||||
/// compilation directory and have it be something other than the curre | ||||
nt | ||||
/// working directory. | ||||
const std::string &getCompilationDir() const { return CompilationDir; } | ||||
/// \brief Set the compilation directory for DW_AT_comp_dir | ||||
/// Override the default (CWD) compilation directory. | ||||
void setCompilationDir(StringRef S) { CompilationDir = S.str(); } | ||||
/// \brief Get the main file name for use in error messages and debug | ||||
/// info. This can be set to ensure we've got the correct file name | ||||
/// after preprocessing or for -save-temps. | ||||
const std::string &getMainFileName() const { return MainFileName; } | ||||
/// \brief Set the main file name and override the default. | ||||
void setMainFileName(StringRef S) { MainFileName = S.str(); } | ||||
/// GetDwarfFile - creates an entry in the dwarf file and directory tab les. | /// GetDwarfFile - creates an entry in the dwarf file and directory tab les. | |||
unsigned GetDwarfFile(StringRef Directory, StringRef FileName, | unsigned GetDwarfFile(StringRef Directory, StringRef FileName, | |||
unsigned FileNumber); | unsigned FileNumber, unsigned CUID); | |||
bool isValidDwarfFileNumber(unsigned FileNumber); | bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0); | |||
bool hasDwarfFiles() const { | bool hasDwarfFiles() const { | |||
return !MCDwarfFiles.empty(); | // Traverse MCDwarfFilesCUMap and check whether each entry is empty. | |||
MCDwarfFilesMap::const_iterator MapB, MapE; | ||||
for (MapB = MCDwarfFilesCUMap.begin(), MapE = MCDwarfFilesCUMap.end() | ||||
; | ||||
MapB != MapE; MapB++) | ||||
if (!MapB->second.empty()) | ||||
return true; | ||||
return false; | ||||
} | } | |||
const std::vector<MCDwarfFile *> &getMCDwarfFiles() { | const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0 | |||
return MCDwarfFiles; | ) { | |||
return MCDwarfFilesCUMap[CUID]; | ||||
} | } | |||
const std::vector<StringRef> &getMCDwarfDirs() { | const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) { | |||
return MCDwarfDirs; | return MCDwarfDirsCUMap[CUID]; | |||
} | } | |||
const DenseMap<const MCSection *, MCLineSection *> | const DenseMap<const MCSection *, MCLineSection *> | |||
&getMCLineSections() const { | &getMCLineSections() const { | |||
return MCLineSections; | return MCLineSections; | |||
} | } | |||
const std::vector<const MCSection *> &getMCLineSectionOrder() const { | const std::vector<const MCSection *> &getMCLineSectionOrder() const { | |||
return MCLineSectionOrder; | return MCLineSectionOrder; | |||
} | } | |||
void addMCLineSection(const MCSection *Sec, MCLineSection *Line) { | void addMCLineSection(const MCSection *Sec, MCLineSection *Line) { | |||
MCLineSections[Sec] = Line; | MCLineSections[Sec] = Line; | |||
MCLineSectionOrder.push_back(Sec); | MCLineSectionOrder.push_back(Sec); | |||
} | } | |||
unsigned getDwarfCompileUnitID() { | ||||
return DwarfCompileUnitID; | ||||
} | ||||
void setDwarfCompileUnitID(unsigned CUIndex) { | ||||
DwarfCompileUnitID = CUIndex; | ||||
} | ||||
const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const { | ||||
return MCLineTableSymbols; | ||||
} | ||||
MCSymbol *getMCLineTableSymbol(unsigned ID) const { | ||||
DenseMap<unsigned, MCSymbol *>::const_iterator CIter = | ||||
MCLineTableSymbols.find(ID); | ||||
if (CIter == MCLineTableSymbols.end()) | ||||
return NULL; | ||||
return CIter->second; | ||||
} | ||||
void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) { | ||||
MCLineTableSymbols[ID] = Sym; | ||||
} | ||||
/// setCurrentDwarfLoc - saves the information from the currently parse d | /// setCurrentDwarfLoc - saves the information from the currently parse d | |||
/// dwarf .loc directive and sets DwarfLocSeen. When the next instruct ion | /// dwarf .loc directive and sets DwarfLocSeen. When the next instruct ion | |||
/// is assembled an entry in the line number table with this informatio n and | /// is assembled an entry in the line number table with this informatio n and | |||
/// the address of the instruction will be created. | /// the address of the instruction will be created. | |||
void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Colum n, | void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Colum n, | |||
unsigned Flags, unsigned Isa, | unsigned Flags, unsigned Isa, | |||
unsigned Discriminator) { | unsigned Discriminator) { | |||
CurrentDwarfLoc.setFileNum(FileNum); | CurrentDwarfLoc.setFileNum(FileNum); | |||
CurrentDwarfLoc.setLine(Line); | CurrentDwarfLoc.setLine(Line); | |||
skipping to change at line 311 | skipping to change at line 387 | |||
&getMCGenDwarfLabelEntries() const { | &getMCGenDwarfLabelEntries() const { | |||
return MCGenDwarfLabelEntries; | return MCGenDwarfLabelEntries; | |||
} | } | |||
void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry *E) { | void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry *E) { | |||
MCGenDwarfLabelEntries.push_back(E); | MCGenDwarfLabelEntries.push_back(E); | |||
} | } | |||
void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; } | void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; } | |||
StringRef getDwarfDebugFlags() { return DwarfDebugFlags; } | StringRef getDwarfDebugFlags() { return DwarfDebugFlags; } | |||
void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; } | ||||
StringRef getDwarfDebugProducer() { return DwarfDebugProducer; } | ||||
/// @} | /// @} | |||
char *getSecureLogFile() { return SecureLogFile; } | char *getSecureLogFile() { return SecureLogFile; } | |||
raw_ostream *getSecureLog() { return SecureLog; } | raw_ostream *getSecureLog() { return SecureLog; } | |||
bool getSecureLogUsed() { return SecureLogUsed; } | bool getSecureLogUsed() { return SecureLogUsed; } | |||
void setSecureLog(raw_ostream *Value) { | void setSecureLog(raw_ostream *Value) { | |||
SecureLog = Value; | SecureLog = Value; | |||
} | } | |||
void setSecureLogUsed(bool Value) { | void setSecureLogUsed(bool Value) { | |||
SecureLogUsed = Value; | SecureLogUsed = Value; | |||
End of changes. 19 change blocks. | ||||
13 lines changed or deleted | 100 lines changed or added | |||
MCDisassembler.h | MCDisassembler.h | |||
---|---|---|---|---|
//===-- llvm/MC/MCDisassembler.h - Disassembler interface -------*- C++ -*- ===// | //===-- llvm/MC/MCDisassembler.h - Disassembler interface -------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef MCDISASSEMBLER_H | #ifndef LLVM_MC_MCDISASSEMBLER_H | |||
#define MCDISASSEMBLER_H | #define LLVM_MC_MCDISASSEMBLER_H | |||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm-c/Disassembler.h" | #include "llvm-c/Disassembler.h" | |||
#include "llvm/Support/DataTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
class MCInst; | class MCInst; | |||
class MCSubtargetInfo; | class MCSubtargetInfo; | |||
class MemoryObject; | class MemoryObject; | |||
class raw_ostream; | class raw_ostream; | |||
class MCContext; | class MCContext; | |||
struct EDInstInfo; | ||||
/// MCDisassembler - Superclass for all disassemblers. Consumes a memory r egion | /// MCDisassembler - Superclass for all disassemblers. Consumes a memory r egion | |||
/// and provides an array of assembly instructions. | /// and provides an array of assembly instructions. | |||
class MCDisassembler { | class MCDisassembler { | |||
public: | public: | |||
/// Ternary decode status. Most backends will just use Fail and | /// Ternary decode status. Most backends will just use Fail and | |||
/// Success, however some have a concept of an instruction with | /// Success, however some have a concept of an instruction with | |||
/// understandable semantics but which is architecturally | /// understandable semantics but which is architecturally | |||
/// incorrect. An example of this is ARM UNPREDICTABLE instructions | /// incorrect. An example of this is ARM UNPREDICTABLE instructions | |||
/// which are disassemblable but cause undefined behaviour. | /// which are disassemblable but cause undefined behaviour. | |||
/// | /// | |||
skipping to change at line 87 | skipping to change at line 85 | |||
/// MCDisassembler::SoftFail if the instruction was | /// MCDisassembler::SoftFail if the instruction was | |||
/// disassemblable but invalid , | /// disassemblable but invalid , | |||
/// MCDisassembler::Fail if the instruction was invalid . | /// MCDisassembler::Fail if the instruction was invalid . | |||
virtual DecodeStatus getInstruction(MCInst& instr, | virtual DecodeStatus getInstruction(MCInst& instr, | |||
uint64_t& size, | uint64_t& size, | |||
const MemoryObject ®ion, | const MemoryObject ®ion, | |||
uint64_t address, | uint64_t address, | |||
raw_ostream &vStream, | raw_ostream &vStream, | |||
raw_ostream &cStream) const = 0; | raw_ostream &cStream) const = 0; | |||
/// getEDInfo - Returns the enhanced instruction information correspondin | ||||
g to | ||||
/// the disassembler. | ||||
/// | ||||
/// @return - An array of instruction information, with one entry | ||||
for | ||||
/// each MCInst opcode this disassembler returns. | ||||
/// NULL if there is no info for this target. | ||||
virtual const EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; } | ||||
private: | private: | |||
// | // | |||
// Hooks for symbolic disassembly via the public 'C' interface. | // Hooks for symbolic disassembly via the public 'C' interface. | |||
// | // | |||
// The function to get the symbolic information for operands. | // The function to get the symbolic information for operands. | |||
LLVMOpInfoCallback GetOpInfo; | LLVMOpInfoCallback GetOpInfo; | |||
// The function to lookup a symbol name. | // The function to lookup a symbol name. | |||
LLVMSymbolLookupCallback SymbolLookUp; | LLVMSymbolLookupCallback SymbolLookUp; | |||
// The pointer to the block of symbolic information for above call back. | // The pointer to the block of symbolic information for above call back. | |||
void *DisInfo; | void *DisInfo; | |||
End of changes. 5 change blocks. | ||||
15 lines changed or deleted | 3 lines changed or added | |||
MCDwarf.h | MCDwarf.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file contains the declaration of the MCDwarfFile to support the dwa rf | // This file contains the declaration of the MCDwarfFile to support the dwa rf | |||
// .file directive and the .loc directive. | // .file directive and the .loc directive. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCDWARF_H | #ifndef LLVM_MC_MCDWARF_H | |||
#define LLVM_MC_MCDWARF_H | #define LLVM_MC_MCDWARF_H | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/MC/MachineLocation.h" | ||||
#include "llvm/Support/raw_ostream.h" | ||||
#include "llvm/Support/Dwarf.h" | ||||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/Dwarf.h" | ||||
#include "llvm/Support/raw_ostream.h" | ||||
#include <map> | ||||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class MCContext; | class MCContext; | |||
class MCObjectWriter; | class MCObjectWriter; | |||
class MCSection; | class MCSection; | |||
class MCStreamer; | class MCStreamer; | |||
class MCSymbol; | class MCSymbol; | |||
class SourceMgr; | class SourceMgr; | |||
class SMLoc; | class SMLoc; | |||
skipping to change at line 189 | skipping to change at line 189 | |||
private: | private: | |||
MCLineSection(const MCLineSection&) LLVM_DELETED_FUNCTION; | MCLineSection(const MCLineSection&) LLVM_DELETED_FUNCTION; | |||
void operator=(const MCLineSection&) LLVM_DELETED_FUNCTION; | void operator=(const MCLineSection&) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
// Constructor to create an MCLineSection with an empty MCLineEntries | // Constructor to create an MCLineSection with an empty MCLineEntries | |||
// vector. | // vector. | |||
MCLineSection() {} | MCLineSection() {} | |||
// addLineEntry - adds an entry to this MCLineSection's line entries | // addLineEntry - adds an entry to this MCLineSection's line entries | |||
void addLineEntry(const MCLineEntry &LineEntry) { | void addLineEntry(const MCLineEntry &LineEntry, unsigned CUID) { | |||
MCLineEntries.push_back(LineEntry); | MCLineDivisions[CUID].push_back(LineEntry); | |||
} | } | |||
typedef std::vector<MCLineEntry> MCLineEntryCollection; | typedef std::vector<MCLineEntry> MCLineEntryCollection; | |||
typedef MCLineEntryCollection::iterator iterator; | typedef MCLineEntryCollection::iterator iterator; | |||
typedef MCLineEntryCollection::const_iterator const_iterator; | typedef MCLineEntryCollection::const_iterator const_iterator; | |||
typedef std::map<unsigned, MCLineEntryCollection> MCLineDivisionMap; | ||||
private: | private: | |||
MCLineEntryCollection MCLineEntries; | // A collection of MCLineEntry for each Compile Unit ID. | |||
MCLineDivisionMap MCLineDivisions; | ||||
public: | public: | |||
const MCLineEntryCollection *getMCLineEntries() const { | // Returns whether MCLineSection contains entries for a given Compile | |||
return &MCLineEntries; | // Unit ID. | |||
bool containEntriesForID(unsigned CUID) const { | ||||
return MCLineDivisions.count(CUID); | ||||
} | ||||
// Returns the collection of MCLineEntry for a given Compile Unit ID. | ||||
const MCLineEntryCollection &getMCLineEntries(unsigned CUID) const { | ||||
MCLineDivisionMap::const_iterator CIter = MCLineDivisions.find(CUID); | ||||
assert(CIter != MCLineDivisions.end()); | ||||
return CIter->second; | ||||
} | } | |||
}; | }; | |||
class MCDwarfFileTable { | class MCDwarfFileTable { | |||
public: | public: | |||
// | // | |||
// This emits the Dwarf file and the line tables. | // This emits the Dwarf file and the line tables for all Compile Units. | |||
// | // | |||
static const MCSymbol *Emit(MCStreamer *MCOS); | static const MCSymbol *Emit(MCStreamer *MCOS); | |||
// | ||||
// This emits the Dwarf file and the line tables for a given Compile Un | ||||
it. | ||||
// | ||||
static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID); | ||||
}; | }; | |||
class MCDwarfLineAddr { | class MCDwarfLineAddr { | |||
public: | public: | |||
/// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas . | /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas . | |||
static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream & OS); | static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream & OS); | |||
/// Utility function to emit the encoding to a streamer. | /// Utility function to emit the encoding to a streamer. | |||
static void Emit(MCStreamer *MCOS, | static void Emit(MCStreamer *MCOS, | |||
int64_t LineDelta,uint64_t AddrDelta); | int64_t LineDelta,uint64_t AddrDelta); | |||
skipping to change at line 268 | skipping to change at line 282 | |||
MCSymbol *getLabel() const { return Label; } | MCSymbol *getLabel() const { return Label; } | |||
// This is called when label is created when we are generating dwarf fo r | // This is called when label is created when we are generating dwarf fo r | |||
// assembly source files. | // assembly source files. | |||
static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, | static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, | |||
SMLoc &Loc); | SMLoc &Loc); | |||
}; | }; | |||
class MCCFIInstruction { | class MCCFIInstruction { | |||
public: | public: | |||
enum OpType { SameValue, RememberState, RestoreState, Move, RelMove, Es | enum OpType { OpSameValue, OpRememberState, OpRestoreState, OpOffset, | |||
cape, | OpDefCfaRegister, OpDefCfaOffset, OpDefCfa, OpRelOffset, | |||
Restore}; | OpAdjustCfaOffset, OpEscape, OpRestore, OpUndefined, | |||
OpRegister }; | ||||
private: | private: | |||
OpType Operation; | OpType Operation; | |||
MCSymbol *Label; | MCSymbol *Label; | |||
// Move to & from location. | unsigned Register; | |||
MachineLocation Destination; | union { | |||
MachineLocation Source; | int Offset; | |||
unsigned Register2; | ||||
}; | ||||
std::vector<char> Values; | std::vector<char> Values; | |||
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V | ||||
) : | ||||
Operation(Op), Label(L), Register(R), Offset(O), | ||||
Values(V.begin(), V.end()) { | ||||
assert(Op != OpRegister); | ||||
} | ||||
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2) : | ||||
Operation(Op), Label(L), Register(R1), Register2(R2) { | ||||
assert(Op == OpRegister); | ||||
} | ||||
public: | public: | |||
MCCFIInstruction(OpType Op, MCSymbol *L) | static MCCFIInstruction | |||
: Operation(Op), Label(L) { | createOffset(MCSymbol *L, unsigned Register, int Offset) { | |||
assert(Op == RememberState || Op == RestoreState); | return MCCFIInstruction(OpOffset, L, Register, Offset, ""); | |||
} | } | |||
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register) | ||||
: Operation(Op), Label(L), Destination(Register) { | static MCCFIInstruction | |||
assert(Op == SameValue || Op == Restore); | createDefCfaRegister(MCSymbol *L, unsigned Register) { | |||
} | return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, ""); | |||
MCCFIInstruction(MCSymbol *L, const MachineLocation &D, | } | |||
const MachineLocation &S) | ||||
: Operation(Move), Label(L), Destination(D), Source(S) { | static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) { | |||
} | return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, ""); | |||
MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D, | } | |||
const MachineLocation &S) | ||||
: Operation(Op), Label(L), Destination(D), Source(S) { | static MCCFIInstruction | |||
assert(Op == RelMove); | createDefCfa(MCSymbol *L, unsigned Register, int Offset) { | |||
} | return MCCFIInstruction(OpDefCfa, L, Register, -Offset, ""); | |||
MCCFIInstruction(OpType Op, MCSymbol *L, StringRef Vals) | } | |||
: Operation(Op), Label(L), Values(Vals.begin(), Vals.end()) { | ||||
assert(Op == Escape); | static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) | |||
{ | ||||
return MCCFIInstruction(OpUndefined, L, Register, 0, ""); | ||||
} | ||||
static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) { | ||||
return MCCFIInstruction(OpRestore, L, Register, 0, ""); | ||||
} | } | |||
static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) | ||||
{ | ||||
return MCCFIInstruction(OpSameValue, L, Register, 0, ""); | ||||
} | ||||
static MCCFIInstruction createRestoreState(MCSymbol *L) { | ||||
return MCCFIInstruction(OpRestoreState, L, 0, 0, ""); | ||||
} | ||||
static MCCFIInstruction createRememberState(MCSymbol *L) { | ||||
return MCCFIInstruction(OpRememberState, L, 0, 0, ""); | ||||
} | ||||
static MCCFIInstruction | ||||
createRelOffset(MCSymbol *L, unsigned Register, int Offset) { | ||||
return MCCFIInstruction(OpRelOffset, L, Register, Offset, ""); | ||||
} | ||||
static MCCFIInstruction | ||||
createAdjustCfaOffset(MCSymbol *L, int Adjustment) { | ||||
return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, ""); | ||||
} | ||||
static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) { | ||||
return MCCFIInstruction(OpEscape, L, 0, 0, Vals); | ||||
} | ||||
static MCCFIInstruction | ||||
createRegister(MCSymbol *L, unsigned Register1, unsigned Register2) { | ||||
return MCCFIInstruction(OpRegister, L, Register1, Register2); | ||||
} | ||||
OpType getOperation() const { return Operation; } | OpType getOperation() const { return Operation; } | |||
MCSymbol *getLabel() const { return Label; } | MCSymbol *getLabel() const { return Label; } | |||
const MachineLocation &getDestination() const { return Destination; } | ||||
const MachineLocation &getSource() const { return Source; } | unsigned getRegister() const { | |||
assert(Operation == OpDefCfa || Operation == OpOffset || | ||||
Operation == OpRestore || Operation == OpUndefined || | ||||
Operation == OpSameValue || Operation == OpDefCfaRegister || | ||||
Operation == OpRelOffset || Operation == OpRegister); | ||||
return Register; | ||||
} | ||||
unsigned getRegister2() const { | ||||
assert(Operation == OpRegister); | ||||
return Register2; | ||||
} | ||||
int getOffset() const { | ||||
assert(Operation == OpDefCfa || Operation == OpOffset || | ||||
Operation == OpRelOffset || Operation == OpDefCfaOffset || | ||||
Operation == OpAdjustCfaOffset); | ||||
return Offset; | ||||
} | ||||
const StringRef getValues() const { | const StringRef getValues() const { | |||
assert(Operation == OpEscape); | ||||
return StringRef(&Values[0], Values.size()); | return StringRef(&Values[0], Values.size()); | |||
} | } | |||
}; | }; | |||
struct MCDwarfFrameInfo { | struct MCDwarfFrameInfo { | |||
MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), | MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), | |||
Function(0), Instructions(), PersonalityEncoding() , | Function(0), Instructions(), PersonalityEncoding() , | |||
LsdaEncoding(0), CompactUnwindEncoding(0), | LsdaEncoding(0), CompactUnwindEncoding(0), | |||
IsSignalFrame(false) {} | IsSignalFrame(false) {} | |||
MCSymbol *Begin; | MCSymbol *Begin; | |||
End of changes. 15 change blocks. | ||||
37 lines changed or deleted | 127 lines changed or added | |||
MCELFObjectWriter.h | MCELFObjectWriter.h | |||
---|---|---|---|---|
skipping to change at line 48 | skipping to change at line 48 | |||
ELFRelocationEntry() | ELFRelocationEntry() | |||
: r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {} | : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {} | |||
ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType, | ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType, | |||
const MCSymbol *Sym, uint64_t Addend, const MCFixup &F ixup) | const MCSymbol *Sym, uint64_t Addend, const MCFixup &F ixup) | |||
: r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym), | : r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym), | |||
r_addend(Addend), Fixup(&Fixup) {} | r_addend(Addend), Fixup(&Fixup) {} | |||
// Support lexicographic sorting. | // Support lexicographic sorting. | |||
bool operator<(const ELFRelocationEntry &RE) const { | bool operator<(const ELFRelocationEntry &RE) const { | |||
return RE.r_offset < r_offset; | if (RE.r_offset != r_offset) | |||
return RE.r_offset < r_offset; | ||||
if (Type != RE.Type) | ||||
return Type < RE.Type; | ||||
if (Index != RE.Index) | ||||
return Index < RE.Index; | ||||
llvm_unreachable("ELFRelocs might be unstable!"); | ||||
return 0; | ||||
} | } | |||
}; | }; | |||
class MCELFObjectTargetWriter { | class MCELFObjectTargetWriter { | |||
const uint8_t OSABI; | const uint8_t OSABI; | |||
const uint16_t EMachine; | const uint16_t EMachine; | |||
const unsigned HasRelocationAddend : 1; | const unsigned HasRelocationAddend : 1; | |||
const unsigned Is64Bit : 1; | const unsigned Is64Bit : 1; | |||
const unsigned IsN64 : 1; | const unsigned IsN64 : 1; | |||
skipping to change at line 82 | skipping to change at line 89 | |||
default: | default: | |||
return ELF::ELFOSABI_NONE; | return ELF::ELFOSABI_NONE; | |||
} | } | |||
} | } | |||
virtual ~MCELFObjectTargetWriter() {} | virtual ~MCELFObjectTargetWriter() {} | |||
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup , | virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup , | |||
bool IsPCRel, bool IsRelocWithSymbol, | bool IsPCRel, bool IsRelocWithSymbol, | |||
int64_t Addend) const = 0; | int64_t Addend) const = 0; | |||
virtual unsigned getEFlags() const; | ||||
virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, | virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, | |||
const MCValue &Target, | const MCValue &Target, | |||
const MCFragment &F, | const MCFragment &F, | |||
const MCFixup &Fixup, | const MCFixup &Fixup, | |||
bool IsPCRel) const; | bool IsPCRel) const; | |||
virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, | virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, | |||
const MCFixup &Fixup, | const MCFixup &Fixup, | |||
bool IsPCRel) const; | bool IsPCRel) const; | |||
virtual void adjustFixupOffset(const MCFixup &Fixup, | virtual void adjustFixupOffset(const MCFixup &Fixup, | |||
uint64_t &RelocOffset); | uint64_t &RelocOffset); | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 8 lines changed or added | |||
MCExpr.h | MCExpr.h | |||
---|---|---|---|---|
skipping to change at line 163 | skipping to change at line 163 | |||
VK_GOTNTPOFF, | VK_GOTNTPOFF, | |||
VK_PLT, | VK_PLT, | |||
VK_TLSGD, | VK_TLSGD, | |||
VK_TLSLD, | VK_TLSLD, | |||
VK_TLSLDM, | VK_TLSLDM, | |||
VK_TPOFF, | VK_TPOFF, | |||
VK_DTPOFF, | VK_DTPOFF, | |||
VK_TLVP, // Mach-O thread local variable relocation | VK_TLVP, // Mach-O thread local variable relocation | |||
VK_SECREL, | VK_SECREL, | |||
// FIXME: We'd really like to use the generic Kinds listed above for th ese. | // FIXME: We'd really like to use the generic Kinds listed above for th ese. | |||
VK_ARM_NONE, | ||||
VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT | VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT | |||
VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF | VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF | |||
VK_ARM_GOT, | VK_ARM_GOT, | |||
VK_ARM_GOTOFF, | VK_ARM_GOTOFF, | |||
VK_ARM_TPOFF, | VK_ARM_TPOFF, | |||
VK_ARM_GOTTPOFF, | VK_ARM_GOTTPOFF, | |||
VK_ARM_TARGET1, | VK_ARM_TARGET1, | |||
VK_ARM_TARGET2, | VK_ARM_TARGET2, | |||
VK_ARM_PREL31, | ||||
VK_PPC_TOC, // TOC base | VK_PPC_TOC, // TOC base | |||
VK_PPC_TOC_ENTRY, // TOC entry | VK_PPC_TOC_ENTRY, // TOC entry | |||
VK_PPC_DARWIN_HA16, // ha16(symbol) | VK_PPC_DARWIN_HA16, // ha16(symbol) | |||
VK_PPC_DARWIN_LO16, // lo16(symbol) | VK_PPC_DARWIN_LO16, // lo16(symbol) | |||
VK_PPC_GAS_HA16, // symbol@ha | VK_PPC_GAS_HA16, // symbol@ha | |||
VK_PPC_GAS_LO16, // symbol@l | VK_PPC_GAS_LO16, // symbol@l | |||
VK_PPC_TPREL16_HA, // symbol@tprel@ha | VK_PPC_TPREL16_HA, // symbol@tprel@ha | |||
VK_PPC_TPREL16_LO, // symbol@tprel@l | 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_TLS, // symbol@tls | ||||
VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha | ||||
VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l | ||||
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_TLSLD, // symbol@tlsld | ||||
VK_Mips_GPREL, | VK_Mips_GPREL, | |||
VK_Mips_GOT_CALL, | VK_Mips_GOT_CALL, | |||
VK_Mips_GOT16, | VK_Mips_GOT16, | |||
VK_Mips_GOT, | VK_Mips_GOT, | |||
VK_Mips_ABS_HI, | VK_Mips_ABS_HI, | |||
VK_Mips_ABS_LO, | VK_Mips_ABS_LO, | |||
VK_Mips_TLSGD, | VK_Mips_TLSGD, | |||
VK_Mips_TLSLDM, | VK_Mips_TLSLDM, | |||
VK_Mips_DTPREL_HI, | VK_Mips_DTPREL_HI, | |||
skipping to change at line 204 | skipping to change at line 219 | |||
VK_Mips_GPOFF_HI, | VK_Mips_GPOFF_HI, | |||
VK_Mips_GPOFF_LO, | VK_Mips_GPOFF_LO, | |||
VK_Mips_GOT_DISP, | VK_Mips_GOT_DISP, | |||
VK_Mips_GOT_PAGE, | VK_Mips_GOT_PAGE, | |||
VK_Mips_GOT_OFST, | VK_Mips_GOT_OFST, | |||
VK_Mips_HIGHER, | VK_Mips_HIGHER, | |||
VK_Mips_HIGHEST, | VK_Mips_HIGHEST, | |||
VK_Mips_GOT_HI16, | VK_Mips_GOT_HI16, | |||
VK_Mips_GOT_LO16, | VK_Mips_GOT_LO16, | |||
VK_Mips_CALL_HI16, | VK_Mips_CALL_HI16, | |||
VK_Mips_CALL_LO16 | VK_Mips_CALL_LO16, | |||
VK_COFF_IMGREL32 // symbol@imgrel (image-relative) | ||||
}; | }; | |||
private: | private: | |||
/// The symbol being referenced. | /// The symbol being referenced. | |||
const MCSymbol *Symbol; | const MCSymbol *Symbol; | |||
/// The symbol reference modifier. | /// The symbol reference modifier. | |||
const VariantKind Kind; | const VariantKind Kind; | |||
explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) | explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) | |||
skipping to change at line 460 | skipping to change at line 477 | |||
MCTargetExpr() : MCExpr(Target) {} | MCTargetExpr() : MCExpr(Target) {} | |||
virtual ~MCTargetExpr() {} | virtual ~MCTargetExpr() {} | |||
public: | public: | |||
virtual void PrintImpl(raw_ostream &OS) const = 0; | virtual void PrintImpl(raw_ostream &OS) const = 0; | |||
virtual bool EvaluateAsRelocatableImpl(MCValue &Res, | virtual bool EvaluateAsRelocatableImpl(MCValue &Res, | |||
const MCAsmLayout *Layout) const = 0; | const MCAsmLayout *Layout) const = 0; | |||
virtual void AddValueSymbols(MCAssembler *) const = 0; | virtual void AddValueSymbols(MCAssembler *) const = 0; | |||
virtual const MCSection *FindAssociatedSection() const = 0; | virtual const MCSection *FindAssociatedSection() const = 0; | |||
virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; | ||||
static bool classof(const MCExpr *E) { | static bool classof(const MCExpr *E) { | |||
return E->getKind() == MCExpr::Target; | return E->getKind() == MCExpr::Target; | |||
} | } | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 6 change blocks. | ||||
2 lines changed or deleted | 21 lines changed or added | |||
MCFixedLenDisassembler.h | MCFixedLenDisassembler.h | |||
---|---|---|---|---|
//===-- llvm/MC/MCFixedLenDisassembler.h - Decoder driver -------*- C++ -*- ===// | //===-- llvm/MC/MCFixedLenDisassembler.h - Decoder driver -------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Fixed length disassembler decoder state machine driver. | // Fixed length disassembler decoder state machine driver. | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef MCFIXEDLENDISASSEMBLER_H | #ifndef LLVM_MC_MCFIXEDLENDISASSEMBLER_H | |||
#define MCFIXEDLENDISASSEMBLER_H | #define LLVM_MC_MCFIXEDLENDISASSEMBLER_H | |||
namespace llvm { | namespace llvm { | |||
namespace MCD { | namespace MCD { | |||
// Disassembler state machine opcodes. | // Disassembler state machine opcodes. | |||
enum DecoderOps { | enum DecoderOps { | |||
OPC_ExtractField = 1, // OPC_ExtractField(uint8_t Start, uint8_t Len) | OPC_ExtractField = 1, // OPC_ExtractField(uint8_t Start, uint8_t Len) | |||
OPC_FilterValue, // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip) | OPC_FilterValue, // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip) | |||
OPC_CheckField, // OPC_CheckField(uint8_t Start, uint8_t Len, | OPC_CheckField, // OPC_CheckField(uint8_t Start, uint8_t Len, | |||
// uleb128 Val, uint16_t NumToSkip) | // uleb128 Val, uint16_t NumToSkip) | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
MCInst.h | MCInst.h | |||
---|---|---|---|---|
skipping to change at line 174 | skipping to change at line 174 | |||
MCOperand &getOperand(unsigned i) { return Operands[i]; } | MCOperand &getOperand(unsigned i) { return Operands[i]; } | |||
unsigned getNumOperands() const { return Operands.size(); } | unsigned getNumOperands() const { return Operands.size(); } | |||
void addOperand(const MCOperand &Op) { | void addOperand(const MCOperand &Op) { | |||
Operands.push_back(Op); | Operands.push_back(Op); | |||
} | } | |||
void clear() { Operands.clear(); } | void clear() { Operands.clear(); } | |||
size_t size() { return Operands.size(); } | size_t size() { return Operands.size(); } | |||
typedef SmallVector<MCOperand, 8>::iterator iterator; | typedef SmallVectorImpl<MCOperand>::iterator iterator; | |||
iterator begin() { return Operands.begin(); } | iterator begin() { return Operands.begin(); } | |||
iterator end() { return Operands.end(); } | iterator end() { return Operands.end(); } | |||
iterator insert(iterator I, const MCOperand &Op) { | iterator insert(iterator I, const MCOperand &Op) { | |||
return Operands.insert(I, Op); | return Operands.insert(I, Op); | |||
} | } | |||
void print(raw_ostream &OS, const MCAsmInfo *MAI) const; | void print(raw_ostream &OS, const MCAsmInfo *MAI) const; | |||
void dump() const; | void dump() const; | |||
/// \brief Dump the MCInst as prettily as possible using the additional M C | /// \brief Dump the MCInst as prettily as possible using the additional M C | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
MCInstPrinter.h | MCInstPrinter.h | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCINSTPRINTER_H | #ifndef LLVM_MC_MCINSTPRINTER_H | |||
#define LLVM_MC_MCINSTPRINTER_H | #define LLVM_MC_MCINSTPRINTER_H | |||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/Support/Format.h" | ||||
namespace llvm { | namespace llvm { | |||
class MCInst; | class MCInst; | |||
class raw_ostream; | class raw_ostream; | |||
class MCAsmInfo; | class MCAsmInfo; | |||
class MCInstrInfo; | class MCInstrInfo; | |||
class MCRegisterInfo; | class MCRegisterInfo; | |||
class StringRef; | class StringRef; | |||
/// MCInstPrinter - This is an instance of a target assembly language print er | /// MCInstPrinter - This is an instance of a target assembly language print er | |||
/// that converts an MCInst to valid target assembly syntax. | /// that converts an MCInst to valid target assembly syntax. | |||
skipping to change at line 39 | skipping to change at line 42 | |||
const MCAsmInfo &MAI; | const MCAsmInfo &MAI; | |||
const MCInstrInfo &MII; | const MCInstrInfo &MII; | |||
const MCRegisterInfo &MRI; | const MCRegisterInfo &MRI; | |||
/// The current set of available features. | /// The current set of available features. | |||
unsigned AvailableFeatures; | unsigned AvailableFeatures; | |||
/// True if we are printing marked up assembly. | /// True if we are printing marked up assembly. | |||
bool UseMarkup; | bool UseMarkup; | |||
/// True if we are printing immediates as hex. | ||||
bool PrintImmHex; | ||||
/// Utility function for printing annotations. | /// Utility function for printing annotations. | |||
void printAnnotation(raw_ostream &OS, StringRef Annot); | void printAnnotation(raw_ostream &OS, StringRef Annot); | |||
public: | public: | |||
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, | MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, | |||
const MCRegisterInfo &mri) | const MCRegisterInfo &mri) | |||
: CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0), | : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0), | |||
UseMarkup(0) {} | UseMarkup(0), PrintImmHex(0) {} | |||
virtual ~MCInstPrinter(); | virtual ~MCInstPrinter(); | |||
/// setCommentStream - Specify a stream to emit comments to. | /// setCommentStream - Specify a stream to emit comments to. | |||
void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } | void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } | |||
/// printInst - Print the specified MCInst to the specified raw_ostream. | /// printInst - Print the specified MCInst to the specified raw_ostream. | |||
/// | /// | |||
virtual void printInst(const MCInst *MI, raw_ostream &OS, | virtual void printInst(const MCInst *MI, raw_ostream &OS, | |||
StringRef Annot) = 0; | StringRef Annot) = 0; | |||
skipping to change at line 73 | skipping to change at line 79 | |||
unsigned getAvailableFeatures() const { return AvailableFeatures; } | unsigned getAvailableFeatures() const { return AvailableFeatures; } | |||
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } | void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } | |||
bool getUseMarkup() const { return UseMarkup; } | bool getUseMarkup() const { return UseMarkup; } | |||
void setUseMarkup(bool Value) { UseMarkup = Value; } | void setUseMarkup(bool Value) { UseMarkup = Value; } | |||
/// Utility functions to make adding mark ups simpler. | /// Utility functions to make adding mark ups simpler. | |||
StringRef markup(StringRef s) const; | StringRef markup(StringRef s) const; | |||
StringRef markup(StringRef a, StringRef b) const; | StringRef markup(StringRef a, StringRef b) const; | |||
bool getPrintImmHex() const { return PrintImmHex; } | ||||
void setPrintImmHex(bool Value) { PrintImmHex = Value; } | ||||
/// Utility function to print immediates in decimal or hex. | ||||
format_object1<int64_t> formatImm(const int64_t Value) const; | ||||
}; | }; | |||
} // namespace llvm | } // namespace llvm | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
1 lines changed or deleted | 13 lines changed or added | |||
MCInstrDesc.h | MCInstrDesc.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the MCOperandInfo and MCInstrDesc classes, which | // This file defines the MCOperandInfo and MCInstrDesc classes, which | |||
// are used to describe target instructions and their operands. | // are used to describe target instructions and their operands. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCINSTRDESC_H | #ifndef LLVM_MC_MCINSTRDESC_H | |||
#define LLVM_MC_MCINSTRDESC_H | #define LLVM_MC_MCINSTRDESC_H | |||
#include "llvm/MC/MCInst.h" | ||||
#include "llvm/MC/MCRegisterInfo.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Machine Operand Flags and Description | // Machine Operand Flags and Description | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
namespace MCOI { | namespace MCOI { | |||
// Operand constraints | // Operand constraints | |||
skipping to change at line 146 | skipping to change at line 148 | |||
unsigned short NumOperands; // Num of args (may be more if variable_op s) | unsigned short NumOperands; // Num of args (may be more if variable_op s) | |||
unsigned short NumDefs; // Num of args that are definitions | unsigned short NumDefs; // Num of args that are definitions | |||
unsigned short SchedClass; // enum identifying instr sched class | unsigned short SchedClass; // enum identifying instr sched class | |||
unsigned short Size; // Number of bytes in encoding. | unsigned short Size; // Number of bytes in encoding. | |||
unsigned Flags; // Flags identifying machine instr class | unsigned Flags; // Flags identifying machine instr class | |||
uint64_t TSFlags; // Target Specific Flag values | uint64_t TSFlags; // Target Specific Flag values | |||
const uint16_t *ImplicitUses; // Registers implicitly read by this instr | const uint16_t *ImplicitUses; // Registers implicitly read by this instr | |||
const uint16_t *ImplicitDefs; // Registers implicitly defined by this in str | const uint16_t *ImplicitDefs; // Registers implicitly defined by this in str | |||
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands | const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands | |||
/// getOperandConstraint - Returns the value of the specific constraint i f | /// \brief Returns the value of the specific constraint if | |||
/// it is set. Returns -1 if it is not set. | /// it is set. Returns -1 if it is not set. | |||
int getOperandConstraint(unsigned OpNum, | int getOperandConstraint(unsigned OpNum, | |||
MCOI::OperandConstraint Constraint) const { | MCOI::OperandConstraint Constraint) const { | |||
if (OpNum < NumOperands && | if (OpNum < NumOperands && | |||
(OpInfo[OpNum].Constraints & (1 << Constraint))) { | (OpInfo[OpNum].Constraints & (1 << Constraint))) { | |||
unsigned Pos = 16 + Constraint * 4; | unsigned Pos = 16 + Constraint * 4; | |||
return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf; | return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf; | |||
} | } | |||
return -1; | return -1; | |||
} | } | |||
/// getOpcode - Return the opcode number for this descriptor. | /// \brief Return the opcode number for this descriptor. | |||
unsigned getOpcode() const { | unsigned getOpcode() const { | |||
return Opcode; | return Opcode; | |||
} | } | |||
/// getNumOperands - Return the number of declared MachineOperands for th is | /// \brief Return the number of declared MachineOperands for this | |||
/// MachineInstruction. Note that variadic (isVariadic() returns true) | /// MachineInstruction. Note that variadic (isVariadic() returns true) | |||
/// instructions may have additional operands at the end of the list, and note | /// instructions may have additional operands at the end of the list, and note | |||
/// that the machine instruction may include implicit register def/uses a s | /// that the machine instruction may include implicit register def/uses a s | |||
/// well. | /// well. | |||
unsigned getNumOperands() const { | unsigned getNumOperands() const { | |||
return NumOperands; | return NumOperands; | |||
} | } | |||
/// getNumDefs - Return the number of MachineOperands that are register | /// \brief Return the number of MachineOperands that are register | |||
/// definitions. Register definitions always occur at the start of the | /// definitions. Register definitions always occur at the start of the | |||
/// machine operand list. This is the number of "outs" in the .td file, | /// machine operand list. This is the number of "outs" in the .td file, | |||
/// and does not include implicit defs. | /// and does not include implicit defs. | |||
unsigned getNumDefs() const { | unsigned getNumDefs() const { | |||
return NumDefs; | return NumDefs; | |||
} | } | |||
/// getFlags - Return flags of this instruction. | /// \brief Return flags of this instruction. | |||
/// | ||||
unsigned getFlags() const { return Flags; } | unsigned getFlags() const { return Flags; } | |||
/// isVariadic - Return true if this instruction can have a variable numb er of | /// \brief Return true if this instruction can have a variable number of | |||
/// operands. In this case, the variable operands will be after the norm al | /// operands. In this case, the variable operands will be after the norm al | |||
/// operands but before the implicit definitions and uses (if any are | /// operands but before the implicit definitions and uses (if any are | |||
/// present). | /// present). | |||
bool isVariadic() const { | bool isVariadic() const { | |||
return Flags & (1 << MCID::Variadic); | return Flags & (1 << MCID::Variadic); | |||
} | } | |||
/// hasOptionalDef - Set if this instruction has an optional definition, e.g. | /// \brief Set if this instruction has an optional definition, e.g. | |||
/// ARM instructions which can set condition code if 's' bit is set. | /// ARM instructions which can set condition code if 's' bit is set. | |||
bool hasOptionalDef() const { | bool hasOptionalDef() const { | |||
return Flags & (1 << MCID::HasOptionalDef); | return Flags & (1 << MCID::HasOptionalDef); | |||
} | } | |||
/// isPseudo - Return true if this is a pseudo instruction that doesn't | /// \brief Return true if this is a pseudo instruction that doesn't | |||
/// correspond to a real machine instruction. | /// correspond to a real machine instruction. | |||
/// | /// | |||
bool isPseudo() const { | bool isPseudo() const { | |||
return Flags & (1 << MCID::Pseudo); | return Flags & (1 << MCID::Pseudo); | |||
} | } | |||
/// \brief Return true if the instruction is a return. | ||||
bool isReturn() const { | bool isReturn() const { | |||
return Flags & (1 << MCID::Return); | return Flags & (1 << MCID::Return); | |||
} | } | |||
/// \brief Return true if the instruction is a call. | ||||
bool isCall() const { | bool isCall() const { | |||
return Flags & (1 << MCID::Call); | return Flags & (1 << MCID::Call); | |||
} | } | |||
/// isBarrier - Returns true if the specified instruction stops control f low | /// \brief Returns true if the specified instruction stops control flow | |||
/// from executing the instruction immediately following it. Examples in clude | /// from executing the instruction immediately following it. Examples in clude | |||
/// unconditional branches and return instructions. | /// unconditional branches and return instructions. | |||
bool isBarrier() const { | bool isBarrier() const { | |||
return Flags & (1 << MCID::Barrier); | return Flags & (1 << MCID::Barrier); | |||
} | } | |||
/// isTerminator - Returns true if this instruction part of the terminato r for | /// \brief Returns true if this instruction part of the terminator for | |||
/// a basic block. Typically this is things like return and branch | /// a basic block. Typically this is things like return and branch | |||
/// instructions. | /// instructions. | |||
/// | /// | |||
/// Various passes use this to insert code into the bottom of a basic blo ck, | /// Various passes use this to insert code into the bottom of a basic blo ck, | |||
/// but before control flow occurs. | /// but before control flow occurs. | |||
bool isTerminator() const { | bool isTerminator() const { | |||
return Flags & (1 << MCID::Terminator); | return Flags & (1 << MCID::Terminator); | |||
} | } | |||
/// isBranch - Returns true if this is a conditional, unconditional, or | /// \brief Returns true if this is a conditional, unconditional, or | |||
/// indirect branch. Predicates below can be used to discriminate betwee n | /// indirect branch. Predicates below can be used to discriminate betwee n | |||
/// these cases, and the TargetInstrInfo::AnalyzeBranch method can be use d to | /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be use d to | |||
/// get more information. | /// get more information. | |||
bool isBranch() const { | bool isBranch() const { | |||
return Flags & (1 << MCID::Branch); | return Flags & (1 << MCID::Branch); | |||
} | } | |||
/// isIndirectBranch - Return true if this is an indirect branch, such as a | /// \brief Return true if this is an indirect branch, such as a | |||
/// branch through a register. | /// branch through a register. | |||
bool isIndirectBranch() const { | bool isIndirectBranch() const { | |||
return Flags & (1 << MCID::IndirectBranch); | return Flags & (1 << MCID::IndirectBranch); | |||
} | } | |||
/// isConditionalBranch - Return true if this is a branch which may fall | /// \brief Return true if this is a branch which may fall | |||
/// through to the next instruction or may transfer control flow to some other | /// through to the next instruction or may transfer control flow to some other | |||
/// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more | /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more | |||
/// information about this branch. | /// information about this branch. | |||
bool isConditionalBranch() const { | bool isConditionalBranch() const { | |||
return isBranch() & !isBarrier() & !isIndirectBranch(); | return isBranch() & !isBarrier() & !isIndirectBranch(); | |||
} | } | |||
/// isUnconditionalBranch - Return true if this is a branch which always | /// \brief Return true if this is a branch which always | |||
/// transfers control flow to some other block. The | /// transfers control flow to some other block. The | |||
/// TargetInstrInfo::AnalyzeBranch method can be used to get more informa tion | /// TargetInstrInfo::AnalyzeBranch method can be used to get more informa tion | |||
/// about this branch. | /// about this branch. | |||
bool isUnconditionalBranch() const { | bool isUnconditionalBranch() const { | |||
return isBranch() & isBarrier() & !isIndirectBranch(); | return isBranch() & isBarrier() & !isIndirectBranch(); | |||
} | } | |||
// isPredicable - Return true if this instruction has a predicate operand | /// \brief Return true if this is a branch or an instruction which direct | |||
that | ly | |||
// controls execution. It may be set to 'always', or may be set to other | /// writes to the program counter. Considered 'may' affect rather than | |||
/// values. There are various methods in TargetInstrInfo that can be us | /// 'does' affect as things like predication are not taken into account. | |||
ed to | bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) con | |||
st { | ||||
if (isBranch() || isCall() || isReturn() || isIndirectBranch()) | ||||
return true; | ||||
unsigned PC = RI.getProgramCounter(); | ||||
if (PC == 0) return false; | ||||
return hasDefOfPhysReg(MI, PC, RI); | ||||
} | ||||
/// \brief Return true if this instruction has a predicate operand | ||||
/// that controls execution. It may be set to 'always', or may be set to | ||||
other | ||||
/// values. There are various methods in TargetInstrInfo that can be used | ||||
to | ||||
/// control and modify the predicate in this instruction. | /// control and modify the predicate in this instruction. | |||
bool isPredicable() const { | bool isPredicable() const { | |||
return Flags & (1 << MCID::Predicable); | return Flags & (1 << MCID::Predicable); | |||
} | } | |||
/// isCompare - Return true if this instruction is a comparison. | /// \brief Return true if this instruction is a comparison. | |||
bool isCompare() const { | bool isCompare() const { | |||
return Flags & (1 << MCID::Compare); | return Flags & (1 << MCID::Compare); | |||
} | } | |||
/// isMoveImmediate - Return true if this instruction is a move immediate | /// \brief Return true if this instruction is a move immediate | |||
/// (including conditional moves) instruction. | /// (including conditional moves) instruction. | |||
bool isMoveImmediate() const { | bool isMoveImmediate() const { | |||
return Flags & (1 << MCID::MoveImm); | return Flags & (1 << MCID::MoveImm); | |||
} | } | |||
/// isBitcast - Return true if this instruction is a bitcast instruction. | /// \brief Return true if this instruction is a bitcast instruction. | |||
/// | ||||
bool isBitcast() const { | bool isBitcast() const { | |||
return Flags & (1 << MCID::Bitcast); | return Flags & (1 << MCID::Bitcast); | |||
} | } | |||
/// isSelect - Return true if this is a select instruction. | /// \brief Return true if this is a select instruction. | |||
/// | ||||
bool isSelect() const { | bool isSelect() const { | |||
return Flags & (1 << MCID::Select); | return Flags & (1 << MCID::Select); | |||
} | } | |||
/// isNotDuplicable - Return true if this instruction cannot be safely | /// \brief Return true if this instruction cannot be safely | |||
/// duplicated. For example, if the instruction has a unique labels atta ched | /// duplicated. For example, if the instruction has a unique labels atta ched | |||
/// to it, duplicating it would cause multiple definition errors. | /// to it, duplicating it would cause multiple definition errors. | |||
bool isNotDuplicable() const { | bool isNotDuplicable() const { | |||
return Flags & (1 << MCID::NotDuplicable); | return Flags & (1 << MCID::NotDuplicable); | |||
} | } | |||
/// hasDelaySlot - Returns true if the specified instruction has a delay slot | /// hasDelaySlot - Returns true if the specified instruction has a delay slot | |||
/// which must be filled by the code generator. | /// which must be filled by the code generator. | |||
bool hasDelaySlot() const { | bool hasDelaySlot() const { | |||
return Flags & (1 << MCID::DelaySlot); | return Flags & (1 << MCID::DelaySlot); | |||
skipping to change at line 320 | skipping to change at line 332 | |||
/// This should only be set on instructions that return a value in their | /// This should only be set on instructions that return a value in their | |||
/// only virtual register definition. | /// only virtual register definition. | |||
bool canFoldAsLoad() const { | bool canFoldAsLoad() const { | |||
return Flags & (1 << MCID::FoldableAsLoad); | return Flags & (1 << MCID::FoldableAsLoad); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Side Effect Analysis | // Side Effect Analysis | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// mayLoad - Return true if this instruction could possibly read memory. | /// \brief Return true if this instruction could possibly read memory. | |||
/// Instructions with this flag set are not necessarily simple load | /// Instructions with this flag set are not necessarily simple load | |||
/// instructions, they may load a value and modify it, for example. | /// instructions, they may load a value and modify it, for example. | |||
bool mayLoad() const { | bool mayLoad() const { | |||
return Flags & (1 << MCID::MayLoad); | return Flags & (1 << MCID::MayLoad); | |||
} | } | |||
/// mayStore - Return true if this instruction could possibly modify memo ry. | /// \brief Return true if this instruction could possibly modify memory. | |||
/// Instructions with this flag set are not necessarily simple store | /// Instructions with this flag set are not necessarily simple store | |||
/// instructions, they may store a modified value based on their operands , or | /// instructions, they may store a modified value based on their operands , or | |||
/// may not actually modify anything, for example. | /// may not actually modify anything, for example. | |||
bool mayStore() const { | bool mayStore() const { | |||
return Flags & (1 << MCID::MayStore); | return Flags & (1 << MCID::MayStore); | |||
} | } | |||
/// hasUnmodeledSideEffects - Return true if this instruction has side | /// hasUnmodeledSideEffects - Return true if this instruction has side | |||
/// effects that are not modeled by other flags. This does not return tr ue | /// effects that are not modeled by other flags. This does not return tr ue | |||
/// for instructions whose effects are captured by: | /// for instructions whose effects are captured by: | |||
skipping to change at line 459 | skipping to change at line 471 | |||
/// from the flags register. In this case, the instruction is marked as | /// from the flags register. In this case, the instruction is marked as | |||
/// implicitly reading the flags. Likewise, the variable shift instructi on on | /// implicitly reading the flags. Likewise, the variable shift instructi on on | |||
/// X86 is marked as implicitly reading the 'CL' register, which it alway s | /// X86 is marked as implicitly reading the 'CL' register, which it alway s | |||
/// does. | /// does. | |||
/// | /// | |||
/// This method returns null if the instruction has no implicit uses. | /// This method returns null if the instruction has no implicit uses. | |||
const uint16_t *getImplicitUses() const { | const uint16_t *getImplicitUses() const { | |||
return ImplicitUses; | return ImplicitUses; | |||
} | } | |||
/// getNumImplicitUses - Return the number of implicit uses this instruct | /// \brief Return the number of implicit uses this instruction has. | |||
ion | ||||
/// has. | ||||
unsigned getNumImplicitUses() const { | unsigned getNumImplicitUses() const { | |||
if (ImplicitUses == 0) return 0; | if (ImplicitUses == 0) return 0; | |||
unsigned i = 0; | unsigned i = 0; | |||
for (; ImplicitUses[i]; ++i) /*empty*/; | for (; ImplicitUses[i]; ++i) /*empty*/; | |||
return i; | return i; | |||
} | } | |||
/// getImplicitDefs - Return a list of registers that are potentially | /// getImplicitDefs - Return a list of registers that are potentially | |||
/// written by any instance of this machine instruction. For example, on X86, | /// written by any instance of this machine instruction. For example, on X86, | |||
/// many instructions implicitly set the flags register. In this case, t hey | /// many instructions implicitly set the flags register. In this case, t hey | |||
skipping to change at line 482 | skipping to change at line 493 | |||
/// deposit their result in a physical register. For example, the X86 di vide | /// deposit their result in a physical register. For example, the X86 di vide | |||
/// instruction always deposits the quotient and remainder in the EAX/EDX | /// instruction always deposits the quotient and remainder in the EAX/EDX | |||
/// registers. For that instruction, this will return a list containing the | /// registers. For that instruction, this will return a list containing the | |||
/// EAX/EDX/EFLAGS registers. | /// EAX/EDX/EFLAGS registers. | |||
/// | /// | |||
/// This method returns null if the instruction has no implicit defs. | /// This method returns null if the instruction has no implicit defs. | |||
const uint16_t *getImplicitDefs() const { | const uint16_t *getImplicitDefs() const { | |||
return ImplicitDefs; | return ImplicitDefs; | |||
} | } | |||
/// getNumImplicitDefs - Return the number of implicit defs this instruct | /// \brief Return the number of implicit defs this instruct has. | |||
ion | ||||
/// has. | ||||
unsigned getNumImplicitDefs() const { | unsigned getNumImplicitDefs() const { | |||
if (ImplicitDefs == 0) return 0; | if (ImplicitDefs == 0) return 0; | |||
unsigned i = 0; | unsigned i = 0; | |||
for (; ImplicitDefs[i]; ++i) /*empty*/; | for (; ImplicitDefs[i]; ++i) /*empty*/; | |||
return i; | return i; | |||
} | } | |||
/// hasImplicitUseOfPhysReg - Return true if this instruction implicitly | /// \brief Return true if this instruction implicitly | |||
/// uses the specified physical register. | /// uses the specified physical register. | |||
bool hasImplicitUseOfPhysReg(unsigned Reg) const { | bool hasImplicitUseOfPhysReg(unsigned Reg) const { | |||
if (const uint16_t *ImpUses = ImplicitUses) | if (const uint16_t *ImpUses = ImplicitUses) | |||
for (; *ImpUses; ++ImpUses) | for (; *ImpUses; ++ImpUses) | |||
if (*ImpUses == Reg) return true; | if (*ImpUses == Reg) return true; | |||
return false; | return false; | |||
} | } | |||
/// hasImplicitDefOfPhysReg - Return true if this instruction implicitly | /// \brief Return true if this instruction implicitly | |||
/// defines the specified physical register. | /// defines the specified physical register. | |||
bool hasImplicitDefOfPhysReg(unsigned Reg) const { | bool hasImplicitDefOfPhysReg(unsigned Reg, | |||
const MCRegisterInfo *MRI = 0) const { | ||||
if (const uint16_t *ImpDefs = ImplicitDefs) | if (const uint16_t *ImpDefs = ImplicitDefs) | |||
for (; *ImpDefs; ++ImpDefs) | for (; *ImpDefs; ++ImpDefs) | |||
if (*ImpDefs == Reg) return true; | if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs))) | |||
return true; | ||||
return false; | return false; | |||
} | } | |||
/// getSchedClass - Return the scheduling class for this instruction. Th | /// \brief Return true if this instruction defines the specified physical | |||
e | /// register, either explicitly or implicitly. | |||
bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg, | ||||
const MCRegisterInfo &RI) const { | ||||
for (int i = 0, e = NumDefs; i != e; ++i) | ||||
if (MI.getOperand(i).isReg() && | ||||
RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) | ||||
return true; | ||||
return hasImplicitDefOfPhysReg(Reg, &RI); | ||||
} | ||||
/// \brief Return the scheduling class for this instruction. The | ||||
/// scheduling class is an index into the InstrItineraryData table. This | /// scheduling class is an index into the InstrItineraryData table. This | |||
/// returns zero if there is no known scheduling information for the | /// returns zero if there is no known scheduling information for the | |||
/// instruction. | /// instruction. | |||
/// | ||||
unsigned getSchedClass() const { | unsigned getSchedClass() const { | |||
return SchedClass; | return SchedClass; | |||
} | } | |||
/// getSize - Return the number of bytes in the encoding of this instruct ion, | /// \brief Return the number of bytes in the encoding of this instruction , | |||
/// or zero if the encoding size cannot be known from the opcode. | /// or zero if the encoding size cannot be known from the opcode. | |||
unsigned getSize() const { | unsigned getSize() const { | |||
return Size; | return Size; | |||
} | } | |||
/// findFirstPredOperandIdx() - Find the index of the first operand in th e | /// \brief Find the index of the first operand in the | |||
/// operand list that is used to represent the predicate. It returns -1 i f | /// operand list that is used to represent the predicate. It returns -1 i f | |||
/// none is found. | /// none is found. | |||
int findFirstPredOperandIdx() const { | int findFirstPredOperandIdx() const { | |||
if (isPredicable()) { | if (isPredicable()) { | |||
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) | for (unsigned i = 0, e = getNumOperands(); i != e; ++i) | |||
if (OpInfo[i].isPredicate()) | if (OpInfo[i].isPredicate()) | |||
return i; | return i; | |||
} | } | |||
return -1; | return -1; | |||
} | } | |||
End of changes. 35 change blocks. | ||||
44 lines changed or deleted | 65 lines changed or added | |||
MCJIT.h | MCJIT.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file forces the MCJIT to link in on certain operating systems. | // This file forces the MCJIT to link in on certain operating systems. | |||
// (Windows). | // (Windows). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_EXECUTION_ENGINE_MCJIT_H | #ifndef LLVM_EXECUTIONENGINE_MCJIT_H | |||
#define LLVM_EXECUTION_ENGINE_MCJIT_H | #define LLVM_EXECUTIONENGINE_MCJIT_H | |||
#include "llvm/ExecutionEngine/ExecutionEngine.h" | #include "llvm/ExecutionEngine/ExecutionEngine.h" | |||
#include <cstdlib> | #include <cstdlib> | |||
extern "C" void LLVMLinkInMCJIT(); | extern "C" void LLVMLinkInMCJIT(); | |||
namespace { | namespace { | |||
struct ForceMCJITLinking { | struct ForceMCJITLinking { | |||
ForceMCJITLinking() { | ForceMCJITLinking() { | |||
// We must reference MCJIT in such a way that compilers will not | // We must reference MCJIT in such a way that compilers will not | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
MCMachObjectWriter.h | MCMachObjectWriter.h | |||
---|---|---|---|---|
skipping to change at line 48 | skipping to change at line 48 | |||
uint32_t CPUSubtype_, | uint32_t CPUSubtype_, | |||
bool UseAggressiveSymbolFolding_ = false); | bool UseAggressiveSymbolFolding_ = false); | |||
void setLocalDifferenceRelocationType(unsigned Type) { | void setLocalDifferenceRelocationType(unsigned Type) { | |||
LocalDifference_RIT = Type; | LocalDifference_RIT = Type; | |||
} | } | |||
public: | public: | |||
virtual ~MCMachObjectTargetWriter(); | virtual ~MCMachObjectTargetWriter(); | |||
/// @name Lifetime Management | ||||
/// @{ | ||||
virtual void reset() {}; | ||||
/// @} | ||||
/// @name Accessors | /// @name Accessors | |||
/// @{ | /// @{ | |||
bool is64Bit() const { return Is64Bit; } | bool is64Bit() const { return Is64Bit; } | |||
bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFoldi ng; } | bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFoldi ng; } | |||
uint32_t getCPUType() const { return CPUType; } | uint32_t getCPUType() const { return CPUType; } | |||
uint32_t getCPUSubtype() const { return CPUSubtype; } | uint32_t getCPUSubtype() const { return CPUSubtype; } | |||
unsigned getLocalDifferenceRelocationType() const { | unsigned getLocalDifferenceRelocationType() const { | |||
return LocalDifference_RIT; | return LocalDifference_RIT; | |||
} | } | |||
skipping to change at line 114 | skipping to change at line 121 | |||
std::vector<MachSymbolData> UndefinedSymbolData; | std::vector<MachSymbolData> UndefinedSymbolData; | |||
/// @} | /// @} | |||
public: | public: | |||
MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS, | MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS, | |||
bool _IsLittleEndian) | bool _IsLittleEndian) | |||
: MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) { | : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) { | |||
} | } | |||
/// @name Lifetime management Methods | ||||
/// @{ | ||||
virtual void reset(); | ||||
/// @} | ||||
/// @name Utility Methods | /// @name Utility Methods | |||
/// @{ | /// @{ | |||
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); | bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); | |||
SectionAddrMap SectionAddress; | SectionAddrMap SectionAddress; | |||
SectionAddrMap &getSectionAddressMap() { return SectionAddress; } | SectionAddrMap &getSectionAddressMap() { return SectionAddress; } | |||
uint64_t getSectionAddress(const MCSectionData* SD) const { | uint64_t getSectionAddress(const MCSectionData* SD) const { | |||
skipping to change at line 185 | skipping to change at line 199 | |||
uint32_t FirstUndefinedSymbol, | uint32_t FirstUndefinedSymbol, | |||
uint32_t NumUndefinedSymbols, | uint32_t NumUndefinedSymbols, | |||
uint32_t IndirectSymbolOffset, | uint32_t IndirectSymbolOffset, | |||
uint32_t NumIndirectSymbols); | uint32_t NumIndirectSymbols); | |||
void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout); | void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout); | |||
void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, | void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, | |||
uint32_t DataSize); | uint32_t DataSize); | |||
void WriteLinkerOptionsLoadCommand(const std::vector<std::string> &Option | ||||
s); | ||||
// FIXME: We really need to improve the relocation validation. Basically, we | // FIXME: We really need to improve the relocation validation. Basically, we | |||
// want to implement a separate computation which evaluates the relocatio n | // want to implement a separate computation which evaluates the relocatio n | |||
// entry as the linker would, and verifies that the resultant fixup value is | // entry as the linker would, and verifies that the resultant fixup value is | |||
// exactly what the encoder wanted. This will catch several classes of | // exactly what the encoder wanted. This will catch several classes of | |||
// problems: | // problems: | |||
// | // | |||
// - Relocation entry bugs, the two algorithms are unlikely to have the same | // - Relocation entry bugs, the two algorithms are unlikely to have the same | |||
// exact bug. | // exact bug. | |||
// | // | |||
// - Relaxation issues, where we forget to relax something. | // - Relaxation issues, where we forget to relax something. | |||
skipping to change at line 226 | skipping to change at line 242 | |||
void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, | void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, | |||
const MCFragment *Fragment, const MCFixup &Fixup, | const MCFragment *Fragment, const MCFixup &Fixup, | |||
MCValue Target, uint64_t &FixedValue); | MCValue Target, uint64_t &FixedValue); | |||
void BindIndirectSymbols(MCAssembler &Asm); | void BindIndirectSymbols(MCAssembler &Asm); | |||
/// ComputeSymbolTable - Compute the symbol table data | /// ComputeSymbolTable - Compute the symbol table data | |||
/// | /// | |||
/// \param StringTable [out] - The string table data. | /// \param StringTable [out] - The string table data. | |||
/// \param StringIndexMap [out] - Map from symbol names to offsets in the | ||||
/// string table. | ||||
void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, | void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, | |||
std::vector<MachSymbolData> &LocalSymbolData, | std::vector<MachSymbolData> &LocalSymbolData, | |||
std::vector<MachSymbolData> &ExternalSymbolData, | std::vector<MachSymbolData> &ExternalSymbolData, | |||
std::vector<MachSymbolData> &UndefinedSymbolData) ; | std::vector<MachSymbolData> &UndefinedSymbolData) ; | |||
void computeSectionAddresses(const MCAssembler &Asm, | void computeSectionAddresses(const MCAssembler &Asm, | |||
const MCAsmLayout &Layout); | const MCAsmLayout &Layout); | |||
void markAbsoluteVariableSymbols(MCAssembler &Asm, | void markAbsoluteVariableSymbols(MCAssembler &Asm, | |||
const MCAsmLayout &Layout); | const MCAsmLayout &Layout); | |||
End of changes. 4 change blocks. | ||||
2 lines changed or deleted | 17 lines changed or added | |||
MCObjectFileInfo.h | MCObjectFileInfo.h | |||
---|---|---|---|---|
skipping to change at line 49 | skipping to change at line 49 | |||
/// non-.globl label. This defaults to true. | /// non-.globl label. This defaults to true. | |||
bool IsFunctionEHFrameSymbolPrivate; | bool IsFunctionEHFrameSymbolPrivate; | |||
/// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some | /// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some | |||
/// encoding values for EH. | /// encoding values for EH. | |||
unsigned PersonalityEncoding; | unsigned PersonalityEncoding; | |||
unsigned LSDAEncoding; | unsigned LSDAEncoding; | |||
unsigned FDEEncoding; | unsigned FDEEncoding; | |||
unsigned FDECFIEncoding; | unsigned FDECFIEncoding; | |||
unsigned TTypeEncoding; | unsigned TTypeEncoding; | |||
// Section flags for eh_frame | ||||
/// Section flags for eh_frame | ||||
unsigned EHSectionType; | unsigned EHSectionType; | |||
unsigned EHSectionFlags; | unsigned EHSectionFlags; | |||
/// CompactUnwindDwarfEHFrameOnly - Compact unwind encoding indicating th | ||||
at we | ||||
/// should emit only an EH frame. | ||||
unsigned CompactUnwindDwarfEHFrameOnly; | ||||
/// TextSection - Section directive for standard text. | /// TextSection - Section directive for standard text. | |||
/// | /// | |||
const MCSection *TextSection; | const MCSection *TextSection; | |||
/// DataSection - Section directive for standard data. | /// DataSection - Section directive for standard data. | |||
/// | /// | |||
const MCSection *DataSection; | const MCSection *DataSection; | |||
/// BSSSection - Section that is default initialized to zero. | /// BSSSection - Section that is default initialized to zero. | |||
const MCSection *BSSSection; | const MCSection *BSSSection; | |||
skipping to change at line 87 | skipping to change at line 92 | |||
/// LSDASection - If exception handling is supported by the target, this is | /// LSDASection - If exception handling is supported by the target, this is | |||
/// the section the Language Specific Data Area information is emitted to . | /// the section the Language Specific Data Area information is emitted to . | |||
const MCSection *LSDASection; | const MCSection *LSDASection; | |||
/// CompactUnwindSection - If exception handling is supported by the targ et | /// CompactUnwindSection - If exception handling is supported by the targ et | |||
/// and the target can support a compact representation of the CIE and FD E, | /// and the target can support a compact representation of the CIE and FD E, | |||
/// this is the section to emit them into. | /// this is the section to emit them into. | |||
const MCSection *CompactUnwindSection; | const MCSection *CompactUnwindSection; | |||
/// DwarfAccelNamesSection, DwarfAccelObjCSection, | ||||
/// DwarfAccelNamespaceSection, DwarfAccelTypesSection - | ||||
/// If we use the DWARF accelerated hash tables then we want toe emit the | ||||
se | ||||
/// sections. | ||||
const MCSection *DwarfAccelNamesSection; | ||||
const MCSection *DwarfAccelObjCSection; | ||||
const MCSection *DwarfAccelNamespaceSection; | ||||
const MCSection *DwarfAccelTypesSection; | ||||
// Dwarf sections for debug info. If a target supports debug info, these must | // Dwarf sections for debug info. If a target supports debug info, these must | |||
// be set. | // be set. | |||
const MCSection *DwarfAbbrevSection; | const MCSection *DwarfAbbrevSection; | |||
const MCSection *DwarfInfoSection; | const MCSection *DwarfInfoSection; | |||
const MCSection *DwarfLineSection; | const MCSection *DwarfLineSection; | |||
const MCSection *DwarfFrameSection; | const MCSection *DwarfFrameSection; | |||
const MCSection *DwarfPubTypesSection; | const MCSection *DwarfPubTypesSection; | |||
const MCSection *DwarfDebugInlineSection; | const MCSection *DwarfDebugInlineSection; | |||
const MCSection *DwarfStrSection; | const MCSection *DwarfStrSection; | |||
const MCSection *DwarfLocSection; | const MCSection *DwarfLocSection; | |||
const MCSection *DwarfARangesSection; | const MCSection *DwarfARangesSection; | |||
const MCSection *DwarfRangesSection; | const MCSection *DwarfRangesSection; | |||
const MCSection *DwarfMacroInfoSection; | const MCSection *DwarfMacroInfoSection; | |||
// The pubnames section is no longer generated by default. The generatio | ||||
n | ||||
// can be enabled by a compiler flag. | ||||
const MCSection *DwarfPubNamesSection; | ||||
// DWARF5 Experimental Debug Info Sections | ||||
/// DwarfAccelNamesSection, DwarfAccelObjCSection, | ||||
/// DwarfAccelNamespaceSection, DwarfAccelTypesSection - | ||||
/// If we use the DWARF accelerated hash tables then we want to emit thes | ||||
e | ||||
/// sections. | ||||
const MCSection *DwarfAccelNamesSection; | ||||
const MCSection *DwarfAccelObjCSection; | ||||
const MCSection *DwarfAccelNamespaceSection; | ||||
const MCSection *DwarfAccelTypesSection; | ||||
/// These are used for the Fission separate debug information files. | ||||
const MCSection *DwarfInfoDWOSection; | ||||
const MCSection *DwarfAbbrevDWOSection; | ||||
const MCSection *DwarfStrDWOSection; | ||||
const MCSection *DwarfLineDWOSection; | ||||
const MCSection *DwarfLocDWOSection; | ||||
const MCSection *DwarfStrOffDWOSection; | ||||
const MCSection *DwarfAddrSection; | ||||
// Extra TLS Variable Data section. If the target needs to put additiona l | // Extra TLS Variable Data section. If the target needs to put additiona l | |||
// information for a TLS variable, it'll go here. | // information for a TLS variable, it'll go here. | |||
const MCSection *TLSExtraDataSection; | const MCSection *TLSExtraDataSection; | |||
/// TLSDataSection - Section directive for Thread Local data. | /// TLSDataSection - Section directive for Thread Local data. | |||
/// ELF, MachO and COFF. | /// ELF, MachO and COFF. | |||
const MCSection *TLSDataSection; // Defaults to ".tdata". | const MCSection *TLSDataSection; // Defaults to ".tdata". | |||
/// TLSBSSSection - Section directive for Thread Local uninitialized data . | /// TLSBSSSection - Section directive for Thread Local uninitialized data . | |||
skipping to change at line 190 | skipping to change at line 208 | |||
return CommDirectiveSupportsAlignment; | return CommDirectiveSupportsAlignment; | |||
} | } | |||
unsigned getPersonalityEncoding() const { return PersonalityEncoding; } | unsigned getPersonalityEncoding() const { return PersonalityEncoding; } | |||
unsigned getLSDAEncoding() const { return LSDAEncoding; } | unsigned getLSDAEncoding() const { return LSDAEncoding; } | |||
unsigned getFDEEncoding(bool CFI) const { | unsigned getFDEEncoding(bool CFI) const { | |||
return CFI ? FDECFIEncoding : FDEEncoding; | return CFI ? FDECFIEncoding : FDEEncoding; | |||
} | } | |||
unsigned getTTypeEncoding() const { return TTypeEncoding; } | unsigned getTTypeEncoding() const { return TTypeEncoding; } | |||
unsigned getCompactUnwindDwarfEHFrameOnly() const { | ||||
return CompactUnwindDwarfEHFrameOnly; | ||||
} | ||||
const MCSection *getTextSection() const { return TextSection; } | const MCSection *getTextSection() const { return TextSection; } | |||
const MCSection *getDataSection() const { return DataSection; } | const MCSection *getDataSection() const { return DataSection; } | |||
const MCSection *getBSSSection() const { return BSSSection; } | const MCSection *getBSSSection() const { return BSSSection; } | |||
const MCSection *getLSDASection() const { return LSDASection; } | const MCSection *getLSDASection() const { return LSDASection; } | |||
const MCSection *getCompactUnwindSection() const{ | const MCSection *getCompactUnwindSection() const{ | |||
return CompactUnwindSection; | return CompactUnwindSection; | |||
} | } | |||
const MCSection *getDwarfAccelNamesSection() const { | ||||
return DwarfAccelNamesSection; | ||||
} | ||||
const MCSection *getDwarfAccelObjCSection() const { | ||||
return DwarfAccelObjCSection; | ||||
} | ||||
const MCSection *getDwarfAccelNamespaceSection() const { | ||||
return DwarfAccelNamespaceSection; | ||||
} | ||||
const MCSection *getDwarfAccelTypesSection() const { | ||||
return DwarfAccelTypesSection; | ||||
} | ||||
const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSectio n; } | const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSectio n; } | |||
const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; } | const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; } | |||
const MCSection *getDwarfLineSection() const { return DwarfLineSection; } | const MCSection *getDwarfLineSection() const { return DwarfLineSection; } | |||
const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; } | const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; } | |||
const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSect ion;} | ||||
const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSect ion;} | const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSect ion;} | |||
const MCSection *getDwarfDebugInlineSection() const { | const MCSection *getDwarfDebugInlineSection() const { | |||
return DwarfDebugInlineSection; | return DwarfDebugInlineSection; | |||
} | } | |||
const MCSection *getDwarfStrSection() const { return DwarfStrSection; } | const MCSection *getDwarfStrSection() const { return DwarfStrSection; } | |||
const MCSection *getDwarfLocSection() const { return DwarfLocSection; } | const MCSection *getDwarfLocSection() const { return DwarfLocSection; } | |||
const MCSection *getDwarfARangesSection() const { return DwarfARangesSect ion;} | const MCSection *getDwarfARangesSection() const { return DwarfARangesSect ion;} | |||
const MCSection *getDwarfRangesSection() const { return DwarfRangesSectio n; } | const MCSection *getDwarfRangesSection() const { return DwarfRangesSectio n; } | |||
const MCSection *getDwarfMacroInfoSection() const { | const MCSection *getDwarfMacroInfoSection() const { | |||
return DwarfMacroInfoSection; | return DwarfMacroInfoSection; | |||
} | } | |||
// DWARF5 Experimental Debug Info Sections | ||||
const MCSection *getDwarfAccelNamesSection() const { | ||||
return DwarfAccelNamesSection; | ||||
} | ||||
const MCSection *getDwarfAccelObjCSection() const { | ||||
return DwarfAccelObjCSection; | ||||
} | ||||
const MCSection *getDwarfAccelNamespaceSection() const { | ||||
return DwarfAccelNamespaceSection; | ||||
} | ||||
const MCSection *getDwarfAccelTypesSection() const { | ||||
return DwarfAccelTypesSection; | ||||
} | ||||
const MCSection *getDwarfInfoDWOSection() const { | ||||
return DwarfInfoDWOSection; | ||||
} | ||||
const MCSection *getDwarfAbbrevDWOSection() const { | ||||
return DwarfAbbrevDWOSection; | ||||
} | ||||
const MCSection *getDwarfStrDWOSection() const { | ||||
return DwarfStrDWOSection; | ||||
} | ||||
const MCSection *getDwarfLineDWOSection() const { | ||||
return DwarfLineDWOSection; | ||||
} | ||||
const MCSection *getDwarfLocDWOSection() const { | ||||
return DwarfLocDWOSection; | ||||
} | ||||
const MCSection *getDwarfStrOffDWOSection() const { | ||||
return DwarfStrOffDWOSection; | ||||
} | ||||
const MCSection *getDwarfAddrSection() const { | ||||
return DwarfAddrSection; | ||||
} | ||||
const MCSection *getTLSExtraDataSection() const { | const MCSection *getTLSExtraDataSection() const { | |||
return TLSExtraDataSection; | return TLSExtraDataSection; | |||
} | } | |||
const MCSection *getTLSDataSection() const { return TLSDataSection; } | const MCSection *getTLSDataSection() const { return TLSDataSection; } | |||
const MCSection *getTLSBSSSection() const { return TLSBSSSection; } | const MCSection *getTLSBSSSection() const { return TLSBSSSection; } | |||
/// ELF specific sections. | /// ELF specific sections. | |||
/// | /// | |||
const MCSection *getDataRelSection() const { return DataRelSection; } | const MCSection *getDataRelSection() const { return DataRelSection; } | |||
const MCSection *getDataRelLocalSection() const { | const MCSection *getDataRelLocalSection() const { | |||
End of changes. 8 change blocks. | ||||
23 lines changed or deleted | 72 lines changed or added | |||
MCObjectStreamer.h | MCObjectStreamer.h | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCOBJECTSTREAMER_H | #ifndef LLVM_MC_MCOBJECTSTREAMER_H | |||
#define LLVM_MC_MCOBJECTSTREAMER_H | #define LLVM_MC_MCOBJECTSTREAMER_H | |||
#include "llvm/MC/MCAssembler.h" | ||||
#include "llvm/MC/MCStreamer.h" | #include "llvm/MC/MCStreamer.h" | |||
namespace llvm { | namespace llvm { | |||
class MCAssembler; | class MCAssembler; | |||
class MCCodeEmitter; | class MCCodeEmitter; | |||
class MCSectionData; | class MCSectionData; | |||
class MCExpr; | class MCExpr; | |||
class MCFragment; | class MCFragment; | |||
class MCDataFragment; | class MCDataFragment; | |||
class MCAsmBackend; | class MCAsmBackend; | |||
skipping to change at line 35 | skipping to change at line 36 | |||
/// \brief Streaming object file generation interface. | /// \brief Streaming object file generation interface. | |||
/// | /// | |||
/// This class provides an implementation of the MCStreamer interface which is | /// This class provides an implementation of the MCStreamer interface which is | |||
/// suitable for use with the assembler backend. Specific object file forma ts | /// suitable for use with the assembler backend. Specific object file forma ts | |||
/// are expected to subclass this interface to implement directives specifi c | /// are expected to subclass this interface to implement directives specifi c | |||
/// to that file format or custom semantics expected by the object writer | /// to that file format or custom semantics expected by the object writer | |||
/// implementation. | /// implementation. | |||
class MCObjectStreamer : public MCStreamer { | class MCObjectStreamer : public MCStreamer { | |||
MCAssembler *Assembler; | MCAssembler *Assembler; | |||
MCSectionData *CurSectionData; | MCSectionData *CurSectionData; | |||
MCSectionData::iterator CurInsertionPoint; | ||||
virtual void EmitInstToData(const MCInst &Inst) = 0; | virtual void EmitInstToData(const MCInst &Inst) = 0; | |||
virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); | virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); | |||
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame); | virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame); | |||
protected: | protected: | |||
MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, | MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB , | |||
raw_ostream &_OS, MCCodeEmitter *_Emitter); | raw_ostream &_OS, MCCodeEmitter *_Emitter); | |||
MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, | MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB , | |||
raw_ostream &_OS, MCCodeEmitter *_Emitter, | raw_ostream &_OS, MCCodeEmitter *_Emitter, | |||
MCAssembler *_Assembler); | MCAssembler *_Assembler); | |||
~MCObjectStreamer(); | ~MCObjectStreamer(); | |||
public: | ||||
/// state management | ||||
virtual void reset(); | ||||
protected: | ||||
MCSectionData *getCurrentSectionData() const { | MCSectionData *getCurrentSectionData() const { | |||
return CurSectionData; | return CurSectionData; | |||
} | } | |||
MCFragment *getCurrentFragment() const; | MCFragment *getCurrentFragment() const; | |||
void insert(MCFragment *F) const { | ||||
CurSectionData->getFragmentList().insert(CurInsertionPoint, F); | ||||
F->setParent(CurSectionData); | ||||
} | ||||
/// Get a data fragment to write into, creating a new one if the current | /// Get a data fragment to write into, creating a new one if the current | |||
/// fragment is not a data fragment. | /// fragment is not a data fragment. | |||
MCDataFragment *getOrCreateDataFragment() const; | MCDataFragment *getOrCreateDataFragment() const; | |||
const MCExpr *AddValueSymbols(const MCExpr *Value); | const MCExpr *AddValueSymbols(const MCExpr *Value); | |||
public: | public: | |||
MCAssembler &getAssembler() { return *Assembler; } | MCAssembler &getAssembler() { return *Assembler; } | |||
/// @name MCStreamer Interface | /// @name MCStreamer Interface | |||
/// @{ | /// @{ | |||
virtual void EmitLabel(MCSymbol *Symbol); | 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, | virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, | |||
unsigned AddrSpace); | unsigned AddrSpace); | |||
virtual void EmitULEB128Value(const MCExpr *Value); | virtual void EmitULEB128Value(const MCExpr *Value); | |||
virtual void EmitSLEB128Value(const MCExpr *Value); | virtual void EmitSLEB128Value(const MCExpr *Value); | |||
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); | virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); | |||
virtual void ChangeSection(const MCSection *Section); | virtual void ChangeSection(const MCSection *Section, | |||
const MCExpr *Subsection); | ||||
virtual void EmitInstruction(const MCInst &Inst); | virtual void EmitInstruction(const MCInst &Inst); | |||
/// \brief Emit an instruction to a special fragment, because this instru | ||||
ction | ||||
/// can change its size during relaxation. | ||||
virtual void EmitInstToFragment(const MCInst &Inst); | virtual void EmitInstToFragment(const MCInst &Inst); | |||
virtual void EmitBytes(StringRef Data, unsigned AddrSpace); | ||||
virtual void EmitBundleAlignMode(unsigned AlignPow2); | ||||
virtual void EmitBundleLock(bool AlignToEnd); | ||||
virtual void EmitBundleUnlock(); | ||||
virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0); | ||||
virtual void EmitValueToAlignment(unsigned ByteAlignment, | virtual void EmitValueToAlignment(unsigned ByteAlignment, | |||
int64_t Value = 0, | int64_t Value = 0, | |||
unsigned ValueSize = 1, | unsigned ValueSize = 1, | |||
unsigned MaxBytesToEmit = 0); | unsigned MaxBytesToEmit = 0); | |||
virtual void EmitCodeAlignment(unsigned ByteAlignment, | virtual void EmitCodeAlignment(unsigned ByteAlignment, | |||
unsigned MaxBytesToEmit = 0); | unsigned MaxBytesToEmit = 0); | |||
virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value) ; | virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value) ; | |||
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, | virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, | |||
const MCSymbol *LastLabel, | const MCSymbol *LastLabel, | |||
const MCSymbol *Label, | const MCSymbol *Label, | |||
unsigned PointerSize); | unsigned PointerSize); | |||
virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, | virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, | |||
const MCSymbol *Label); | const MCSymbol *Label); | |||
virtual void EmitGPRel32Value(const MCExpr *Value); | virtual void EmitGPRel32Value(const MCExpr *Value); | |||
virtual void EmitGPRel64Value(const MCExpr *Value); | virtual void EmitGPRel64Value(const MCExpr *Value); | |||
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, | virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, | |||
unsigned AddrSpace); | unsigned AddrSpace = 0); | |||
virtual void FinishImpl(); | virtual void FinishImpl(); | |||
/// @} | /// @} | |||
static bool classof(const MCStreamer *S) { | ||||
return S->getKind() >= SK_ELFStreamer && S->getKind() <= SK_WinCOFFStre | ||||
amer; | ||||
} | ||||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 12 change blocks. | ||||
5 lines changed or deleted | 33 lines changed or added | |||
MCObjectWriter.h | MCObjectWriter.h | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCOBJECTWRITER_H | #ifndef LLVM_MC_MCOBJECTWRITER_H | |||
#define LLVM_MC_MCOBJECTWRITER_H | #define LLVM_MC_MCOBJECTWRITER_H | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/raw_ostream.h" | ||||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
class MCAsmLayout; | class MCAsmLayout; | |||
class MCAssembler; | class MCAssembler; | |||
class MCFixup; | class MCFixup; | |||
class MCFragment; | class MCFragment; | |||
class MCSymbolData; | class MCSymbolData; | |||
class MCSymbolRefExpr; | class MCSymbolRefExpr; | |||
class MCValue; | class MCValue; | |||
skipping to change at line 54 | skipping to change at line 55 | |||
unsigned IsLittleEndian : 1; | unsigned IsLittleEndian : 1; | |||
protected: // Can only create subclasses. | protected: // Can only create subclasses. | |||
MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian) | MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian) | |||
: OS(_OS), IsLittleEndian(_IsLittleEndian) {} | : OS(_OS), IsLittleEndian(_IsLittleEndian) {} | |||
public: | public: | |||
virtual ~MCObjectWriter(); | virtual ~MCObjectWriter(); | |||
/// lifetime management | ||||
virtual void reset() { } | ||||
bool isLittleEndian() const { return IsLittleEndian; } | bool isLittleEndian() const { return IsLittleEndian; } | |||
raw_ostream &getStream() { return OS; } | raw_ostream &getStream() { return OS; } | |||
/// @name High-Level API | /// @name High-Level API | |||
/// @{ | /// @{ | |||
/// Perform any late binding of symbols (for example, to assign symbol in | /// \brief Perform any late binding of symbols (for example, to assign sy | |||
dices | mbol | |||
/// for use when generating relocations). | /// indices for use when generating relocations). | |||
/// | /// | |||
/// This routine is called by the assembler after layout and relaxation i s | /// This routine is called by the assembler after layout and relaxation i s | |||
/// complete. | /// complete. | |||
virtual void ExecutePostLayoutBinding(MCAssembler &Asm, | virtual void ExecutePostLayoutBinding(MCAssembler &Asm, | |||
const MCAsmLayout &Layout) = 0; | const MCAsmLayout &Layout) = 0; | |||
/// Record a relocation entry. | /// \brief Record a relocation entry. | |||
/// | /// | |||
/// This routine is called by the assembler after layout and relaxation, and | /// This routine is called by the assembler after layout and relaxation, and | |||
/// post layout binding. The implementation is responsible for storing | /// post layout binding. The implementation is responsible for storing | |||
/// information about the relocation so that it can be emitted during | /// information about the relocation so that it can be emitted during | |||
/// WriteObject(). | /// WriteObject(). | |||
virtual void RecordRelocation(const MCAssembler &Asm, | virtual void RecordRelocation(const MCAssembler &Asm, | |||
const MCAsmLayout &Layout, | const MCAsmLayout &Layout, | |||
const MCFragment *Fragment, | const MCFragment *Fragment, | |||
const MCFixup &Fixup, MCValue Target, | const MCFixup &Fixup, MCValue Target, | |||
uint64_t &FixedValue) = 0; | uint64_t &FixedValue) = 0; | |||
skipping to change at line 99 | skipping to change at line 103 | |||
const MCSymbolRefExpr *B, | const MCSymbolRefExpr *B, | |||
bool InSet) const; | bool InSet) const; | |||
virtual bool | virtual bool | |||
IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, | IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, | |||
const MCSymbolData &DataA, | const MCSymbolData &DataA, | |||
const MCFragment &FB, | const MCFragment &FB, | |||
bool InSet, | bool InSet, | |||
bool IsPCRel) const; | bool IsPCRel) const; | |||
/// Write the object file. | /// \brief Write the object file. | |||
/// | /// | |||
/// This routine is called by the assembler after layout and relaxation i s | /// This routine is called by the assembler after layout and relaxation i s | |||
/// complete, fixups have been evaluated and applied, and relocations | /// complete, fixups have been evaluated and applied, and relocations | |||
/// generated. | /// generated. | |||
virtual void WriteObject(MCAssembler &Asm, | virtual void WriteObject(MCAssembler &Asm, | |||
const MCAsmLayout &Layout) = 0; | const MCAsmLayout &Layout) = 0; | |||
/// @} | /// @} | |||
/// @name Binary Output | /// @name Binary Output | |||
/// @{ | /// @{ | |||
skipping to change at line 175 | skipping to change at line 179 | |||
void WriteZeros(unsigned N) { | void WriteZeros(unsigned N) { | |||
const char Zeros[16] = { 0 }; | const char Zeros[16] = { 0 }; | |||
for (unsigned i = 0, e = N / 16; i != e; ++i) | for (unsigned i = 0, e = N / 16; i != e; ++i) | |||
OS << StringRef(Zeros, 16); | OS << StringRef(Zeros, 16); | |||
OS << StringRef(Zeros, N % 16); | OS << StringRef(Zeros, N % 16); | |||
} | } | |||
void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSi | ||||
ze = 0) { | ||||
WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); | ||||
} | ||||
void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { | void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { | |||
// TODO: this version may need to go away once all fragment contents ar | ||||
e | ||||
// converted to SmallVector<char, N> | ||||
assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && | assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && | |||
"data size greater than fill size, unexpected large write will occur" ); | "data size greater than fill size, unexpected large write will occur" ); | |||
OS << Str; | OS << Str; | |||
if (ZeroFillSize) | if (ZeroFillSize) | |||
WriteZeros(ZeroFillSize - Str.size()); | WriteZeros(ZeroFillSize - Str.size()); | |||
} | } | |||
/// @} | /// @} | |||
}; | }; | |||
End of changes. 8 change blocks. | ||||
6 lines changed or deleted | 18 lines changed or added | |||
MCParsedAsmOperand.h | MCParsedAsmOperand.h | |||
---|---|---|---|---|
//===-- llvm/MC/MCParsedAsmOperand.h - Asm Parser Operand -------*- C++ -*- ===// | //===-- llvm/MC/MCParsedAsmOperand.h - Asm Parser Operand -------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCASMOPERAND_H | #ifndef LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H | |||
#define LLVM_MC_MCASMOPERAND_H | #define LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H | |||
namespace llvm { | namespace llvm { | |||
class SMLoc; | class SMLoc; | |||
class raw_ostream; | class raw_ostream; | |||
/// MCParsedAsmOperand - This abstract class represents a source-level asse mbly | /// MCParsedAsmOperand - This abstract class represents a source-level asse mbly | |||
/// instruction operand. It should be subclassed by target-specific code. This | /// instruction operand. It should be subclassed by target-specific code. This | |||
/// base class is used by target-independent clients and is the interface | /// base class is used by target-independent clients and is the interface | |||
/// between parsing an asm instruction and recognizing it. | /// between parsing an asm instruction and recognizing it. | |||
class MCParsedAsmOperand { | class MCParsedAsmOperand { | |||
skipping to change at line 40 | skipping to change at line 40 | |||
public: | public: | |||
MCParsedAsmOperand() {} | MCParsedAsmOperand() {} | |||
virtual ~MCParsedAsmOperand() {} | virtual ~MCParsedAsmOperand() {} | |||
void setConstraint(StringRef C) { Constraint = C.str(); } | void setConstraint(StringRef C) { Constraint = C.str(); } | |||
StringRef getConstraint() { return Constraint; } | StringRef getConstraint() { return Constraint; } | |||
void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; } | void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; } | |||
unsigned getMCOperandNum() { return MCOperandNum; } | unsigned getMCOperandNum() { return MCOperandNum; } | |||
unsigned getNameLen() { | virtual StringRef getSymName() { return StringRef(); } | |||
assert (getStartLoc().isValid() && "Invalid StartLoc!"); | virtual void *getOpDecl() { return 0; } | |||
assert (getEndLoc().isValid() && "Invalid EndLoc!"); | ||||
return getEndLoc().getPointer() - getStartLoc().getPointer(); | ||||
} | ||||
StringRef getName() { | ||||
return StringRef(getStartLoc().getPointer(), getNameLen()); | ||||
} | ||||
/// isToken - Is this a token operand? | /// isToken - Is this a token operand? | |||
virtual bool isToken() const = 0; | virtual bool isToken() const = 0; | |||
/// isImm - Is this an immediate operand? | /// isImm - Is this an immediate operand? | |||
virtual bool isImm() const = 0; | virtual bool isImm() const = 0; | |||
/// isReg - Is this a register operand? | /// isReg - Is this a register operand? | |||
virtual bool isReg() const = 0; | virtual bool isReg() const = 0; | |||
virtual unsigned getReg() const = 0; | virtual unsigned getReg() const = 0; | |||
/// isMem - Is this a memory operand? | /// isMem - Is this a memory operand? | |||
virtual bool isMem() const = 0; | virtual bool isMem() const = 0; | |||
virtual unsigned getMemSize() const { return 0; } | ||||
/// getStartLoc - Get the location of the first token of this operand. | /// getStartLoc - Get the location of the first token of this operand. | |||
virtual SMLoc getStartLoc() const = 0; | virtual SMLoc getStartLoc() const = 0; | |||
/// getEndLoc - Get the location of the last token of this operand. | /// getEndLoc - Get the location of the last token of this operand. | |||
virtual SMLoc getEndLoc() const = 0; | virtual SMLoc getEndLoc() const = 0; | |||
/// needAsmRewrite - AsmRewrites happen in both the target-independent an | /// needAddressOf - Do we need to emit code to get the address of the | |||
d | /// variable/label? Only valid when parsing MS-style inline assembly. | |||
/// target-dependent parsers. The target-independent parser calls this | virtual bool needAddressOf() const { return false; } | |||
/// function to determine if the target-dependent parser has already take | ||||
n | ||||
/// care of the rewrites. Only valid when parsing MS-style inline assemb | ||||
ly. | ||||
virtual bool needAsmRewrite() const { return true; } | ||||
/// isOffsetOf - Do we need to emit code to get the offset of the variabl e, | /// isOffsetOf - Do we need to emit code to get the offset of the variabl e, | |||
/// rather then the value of the variable? Only valid when parsing MS-s tyle | /// rather then the value of the variable? Only valid when parsing MS-s tyle | |||
/// inline assembly. | /// inline assembly. | |||
virtual bool isOffsetOf() const { return false; } | virtual bool isOffsetOf() const { return false; } | |||
/// getOffsetOfLoc - Get the location of the offset operator. | /// getOffsetOfLoc - Get the location of the offset operator. | |||
virtual SMLoc getOffsetOfLoc() const { return SMLoc(); } | virtual SMLoc getOffsetOfLoc() const { return SMLoc(); } | |||
/// needSizeDirective - Do we need to emit a sizing directive for this | ||||
/// operand? Only valid when parsing MS-style inline assembly. | ||||
virtual bool needSizeDirective() const { return false; } | ||||
/// print - Print a debug representation of the operand to the given stre am. | /// print - Print a debug representation of the operand to the given stre am. | |||
virtual void print(raw_ostream &OS) const = 0; | virtual void print(raw_ostream &OS) const = 0; | |||
/// dump - Print to the debug stream. | /// dump - Print to the debug stream. | |||
virtual void dump() const; | virtual void dump() const; | |||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Debugging Support | // Debugging Support | |||
inline raw_ostream& operator<<(raw_ostream &OS, const MCParsedAsmOperand &M O) { | inline raw_ostream& operator<<(raw_ostream &OS, const MCParsedAsmOperand &M O) { | |||
End of changes. 5 change blocks. | ||||
24 lines changed or deleted | 7 lines changed or added | |||
MCRegisterInfo.h | MCRegisterInfo.h | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
#ifndef LLVM_MC_MCREGISTERINFO_H | #ifndef LLVM_MC_MCREGISTERINFO_H | |||
#define LLVM_MC_MCREGISTERINFO_H | #define LLVM_MC_MCREGISTERINFO_H | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
/// An unsigned integer type large enough to represent all physical registe | ||||
rs, | ||||
/// but not necessarily virtual registers. | ||||
typedef uint16_t MCPhysReg; | ||||
/// MCRegisterClass - Base class of TargetRegisterClass. | /// MCRegisterClass - Base class of TargetRegisterClass. | |||
class MCRegisterClass { | class MCRegisterClass { | |||
public: | public: | |||
typedef const uint16_t* iterator; | typedef const MCPhysReg* iterator; | |||
typedef const uint16_t* const_iterator; | typedef const MCPhysReg* const_iterator; | |||
const char *Name; | const char *Name; | |||
const iterator RegsBegin; | const iterator RegsBegin; | |||
const uint8_t *const RegSet; | const uint8_t *const RegSet; | |||
const uint16_t RegsSize; | const uint16_t RegsSize; | |||
const uint16_t RegSetSize; | const uint16_t RegSetSize; | |||
const uint16_t ID; | const uint16_t ID; | |||
const uint16_t RegSize, Alignment; // Size & Alignment of register in byt es | const uint16_t RegSize, Alignment; // Size & Alignment of register in byt es | |||
const int8_t CopyCost; | const int8_t CopyCost; | |||
const bool Allocatable; | const bool Allocatable; | |||
skipping to change at line 151 | skipping to change at line 155 | |||
struct DwarfLLVMRegPair { | struct DwarfLLVMRegPair { | |||
unsigned FromReg; | unsigned FromReg; | |||
unsigned ToReg; | unsigned ToReg; | |||
bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromR eg; } | bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromR eg; } | |||
}; | }; | |||
private: | private: | |||
const MCRegisterDesc *Desc; // Pointer to the descriptor array | const MCRegisterDesc *Desc; // Pointer to the descriptor array | |||
unsigned NumRegs; // Number of entries in the a rray | unsigned NumRegs; // Number of entries in the a rray | |||
unsigned RAReg; // Return address register | unsigned RAReg; // Return address register | |||
unsigned PCReg; // Program counter register | ||||
const MCRegisterClass *Classes; // Pointer to the regclass ar ray | const MCRegisterClass *Classes; // Pointer to the regclass ar ray | |||
unsigned NumClasses; // Number of entries in the a rray | unsigned NumClasses; // Number of entries in the a rray | |||
unsigned NumRegUnits; // Number of regunits. | unsigned NumRegUnits; // Number of regunits. | |||
const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root ta ble. | const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root ta ble. | |||
const uint16_t *DiffLists; // Pointer to the difflists a rray | const MCPhysReg *DiffLists; // Pointer to the difflists a rray | |||
const char *RegStrings; // Pointer to the string tabl e. | const char *RegStrings; // Pointer to the string tabl e. | |||
const uint16_t *SubRegIndices; // Pointer to the subreg look up | const uint16_t *SubRegIndices; // Pointer to the subreg look up | |||
// array. | // array. | |||
unsigned NumSubRegIndices; // Number of subreg indices. | unsigned NumSubRegIndices; // Number of subreg indices. | |||
const uint16_t *RegEncodingTable; // Pointer to array of regist er | const uint16_t *RegEncodingTable; // Pointer to array of regist er | |||
// encodings. | // encodings. | |||
unsigned L2DwarfRegsSize; | unsigned L2DwarfRegsSize; | |||
unsigned EHL2DwarfRegsSize; | unsigned EHL2DwarfRegsSize; | |||
unsigned Dwarf2LRegsSize; | unsigned Dwarf2LRegsSize; | |||
skipping to change at line 180 | skipping to change at line 185 | |||
const DwarfLLVMRegPair *EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH | const DwarfLLVMRegPair *EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH | |||
DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping | DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping | |||
public: | public: | |||
/// DiffListIterator - Base iterator class that can traverse the | /// DiffListIterator - Base iterator class that can traverse the | |||
/// differentially encoded register and regunit lists in DiffLists. | /// differentially encoded register and regunit lists in DiffLists. | |||
/// Don't use this class directly, use one of the specialized sub-classes | /// Don't use this class directly, use one of the specialized sub-classes | |||
/// defined below. | /// defined below. | |||
class DiffListIterator { | class DiffListIterator { | |||
uint16_t Val; | uint16_t Val; | |||
const uint16_t *List; | const MCPhysReg *List; | |||
protected: | protected: | |||
/// Create an invalid iterator. Call init() to point to something usefu l. | /// Create an invalid iterator. Call init() to point to something usefu l. | |||
DiffListIterator() : Val(0), List(0) {} | DiffListIterator() : Val(0), List(0) {} | |||
/// init - Point the iterator to InitVal, decoding subsequent values fr om | /// init - Point the iterator to InitVal, decoding subsequent values fr om | |||
/// DiffList. The iterator will initially point to InitVal, sub-classes are | /// DiffList. The iterator will initially point to InitVal, sub-classes are | |||
/// responsible for skipping the seed value if it is not part of the li st. | /// responsible for skipping the seed value if it is not part of the li st. | |||
void init(uint16_t InitVal, const uint16_t *DiffList) { | void init(MCPhysReg InitVal, const MCPhysReg *DiffList) { | |||
Val = InitVal; | Val = InitVal; | |||
List = DiffList; | List = DiffList; | |||
} | } | |||
/// advance - Move to the next list position, return the applied | /// advance - Move to the next list position, return the applied | |||
/// differential. This function does not detect the end of the list, th at | /// differential. This function does not detect the end of the list, th at | |||
/// is the caller's responsibility (by checking for a 0 return value). | /// is the caller's responsibility (by checking for a 0 return value). | |||
unsigned advance() { | unsigned advance() { | |||
assert(isValid() && "Cannot move off the end of the list."); | assert(isValid() && "Cannot move off the end of the list."); | |||
uint16_t D = *List++; | MCPhysReg D = *List++; | |||
Val += D; | Val += D; | |||
return D; | return D; | |||
} | } | |||
public: | public: | |||
/// isValid - returns true if this iterator is not yet at the end. | /// isValid - returns true if this iterator is not yet at the end. | |||
bool isValid() const { return List; } | bool isValid() const { return List; } | |||
/// Dereference the iterator to get the value at the current position. | /// Dereference the iterator to get the value at the current position. | |||
skipping to change at line 228 | skipping to change at line 233 | |||
}; | }; | |||
// These iterators are allowed to sub-class DiffListIterator and access | // These iterators are allowed to sub-class DiffListIterator and access | |||
// internal list pointers. | // internal list pointers. | |||
friend class MCSubRegIterator; | friend class MCSubRegIterator; | |||
friend class MCSuperRegIterator; | friend class MCSuperRegIterator; | |||
friend class MCRegAliasIterator; | friend class MCRegAliasIterator; | |||
friend class MCRegUnitIterator; | friend class MCRegUnitIterator; | |||
friend class MCRegUnitRootIterator; | friend class MCRegUnitRootIterator; | |||
/// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen | /// \brief Initialize MCRegisterInfo, called by TableGen | |||
/// auto-generated routines. *DO NOT USE*. | /// auto-generated routines. *DO NOT USE*. | |||
void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA , | void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA , | |||
unsigned PC, | ||||
const MCRegisterClass *C, unsigned NC, | const MCRegisterClass *C, unsigned NC, | |||
const uint16_t (*RURoots)[2], | const uint16_t (*RURoots)[2], | |||
unsigned NRU, | unsigned NRU, | |||
const uint16_t *DL, | const MCPhysReg *DL, | |||
const char *Strings, | const char *Strings, | |||
const uint16_t *SubIndices, | const uint16_t *SubIndices, | |||
unsigned NumIndices, | unsigned NumIndices, | |||
const uint16_t *RET) { | const uint16_t *RET) { | |||
Desc = D; | Desc = D; | |||
NumRegs = NR; | NumRegs = NR; | |||
RAReg = RA; | RAReg = RA; | |||
PCReg = PC; | ||||
Classes = C; | Classes = C; | |||
DiffLists = DL; | DiffLists = DL; | |||
RegStrings = Strings; | RegStrings = Strings; | |||
NumClasses = NC; | NumClasses = NC; | |||
RegUnitRoots = RURoots; | RegUnitRoots = RURoots; | |||
NumRegUnits = NRU; | NumRegUnits = NRU; | |||
SubRegIndices = SubIndices; | SubRegIndices = SubIndices; | |||
NumSubRegIndices = NumIndices; | NumSubRegIndices = NumIndices; | |||
RegEncodingTable = RET; | RegEncodingTable = RET; | |||
} | } | |||
/// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf | /// \brief Used to initialize LLVM register to Dwarf | |||
/// register number mapping. Called by TableGen auto-generated routines. | /// register number mapping. Called by TableGen auto-generated routines. | |||
/// *DO NOT USE*. | /// *DO NOT USE*. | |||
void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size, | void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size, | |||
bool isEH) { | bool isEH) { | |||
if (isEH) { | if (isEH) { | |||
EHL2DwarfRegs = Map; | EHL2DwarfRegs = Map; | |||
EHL2DwarfRegsSize = Size; | EHL2DwarfRegsSize = Size; | |||
} else { | } else { | |||
L2DwarfRegs = Map; | L2DwarfRegs = Map; | |||
L2DwarfRegsSize = Size; | L2DwarfRegsSize = Size; | |||
} | } | |||
} | } | |||
/// mapDwarfRegsToLLVMRegs - Used to initialize Dwarf register to LLVM | /// \brief Used to initialize Dwarf register to LLVM | |||
/// register number mapping. Called by TableGen auto-generated routines. | /// register number mapping. Called by TableGen auto-generated routines. | |||
/// *DO NOT USE*. | /// *DO NOT USE*. | |||
void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size, | void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size, | |||
bool isEH) { | bool isEH) { | |||
if (isEH) { | if (isEH) { | |||
EHDwarf2LRegs = Map; | EHDwarf2LRegs = Map; | |||
EHDwarf2LRegsSize = Size; | EHDwarf2LRegsSize = Size; | |||
} else { | } else { | |||
Dwarf2LRegs = Map; | Dwarf2LRegs = Map; | |||
Dwarf2LRegsSize = Size; | Dwarf2LRegsSize = Size; | |||
skipping to change at line 290 | skipping to change at line 297 | |||
/// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register | /// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register | |||
/// number mapping. By default the SEH register number is just the same | /// number mapping. By default the SEH register number is just the same | |||
/// as the LLVM register number. | /// as the LLVM register number. | |||
/// FIXME: TableGen these numbers. Currently this requires target specifi c | /// FIXME: TableGen these numbers. Currently this requires target specifi c | |||
/// initialization code. | /// initialization code. | |||
void mapLLVMRegToSEHReg(unsigned LLVMReg, int SEHReg) { | void mapLLVMRegToSEHReg(unsigned LLVMReg, int SEHReg) { | |||
L2SEHRegs[LLVMReg] = SEHReg; | L2SEHRegs[LLVMReg] = SEHReg; | |||
} | } | |||
/// getRARegister - This method should return the register where the retu rn | /// \brief This method should return the register where the return | |||
/// address can be found. | /// address can be found. | |||
unsigned getRARegister() const { | unsigned getRARegister() const { | |||
return RAReg; | return RAReg; | |||
} | } | |||
/// Return the register which is the program counter. | ||||
unsigned getProgramCounter() const { | ||||
return PCReg; | ||||
} | ||||
const MCRegisterDesc &operator[](unsigned RegNo) const { | const MCRegisterDesc &operator[](unsigned RegNo) const { | |||
assert(RegNo < NumRegs && | assert(RegNo < NumRegs && | |||
"Attempting to access record for invalid register number!"); | "Attempting to access record for invalid register number!"); | |||
return Desc[RegNo]; | return Desc[RegNo]; | |||
} | } | |||
/// Provide a get method, equivalent to [], but more useful if we have a | /// \brief Provide a get method, equivalent to [], but more useful with a | |||
/// pointer to this object. | /// pointer to this object. | |||
/// | ||||
const MCRegisterDesc &get(unsigned RegNo) const { | const MCRegisterDesc &get(unsigned RegNo) const { | |||
return operator[](RegNo); | return operator[](RegNo); | |||
} | } | |||
/// getSubReg - Returns the physical register number of sub-register "Ind ex" | /// \brief Returns the physical register number of sub-register "Index" | |||
/// for physical register RegNo. Return zero if the sub-register does not | /// for physical register RegNo. Return zero if the sub-register does not | |||
/// exist. | /// exist. | |||
unsigned getSubReg(unsigned Reg, unsigned Idx) const; | unsigned getSubReg(unsigned Reg, unsigned Idx) const; | |||
/// getMatchingSuperReg - Return a super-register of the specified regist er | /// \brief Return a super-register of the specified register | |||
/// Reg so its sub-register of index SubIdx is Reg. | /// Reg so its sub-register of index SubIdx is Reg. | |||
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, | unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, | |||
const MCRegisterClass *RC) const; | const MCRegisterClass *RC) const; | |||
/// getSubRegIndex - For a given register pair, return the sub-register i ndex | /// \brief For a given register pair, return the sub-register index | |||
/// if the second register is a sub-register of the first. Return zero | /// if the second register is a sub-register of the first. Return zero | |||
/// otherwise. | /// otherwise. | |||
unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const; | unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const; | |||
/// getName - Return the human-readable symbolic target-specific name for the | /// \brief Return the human-readable symbolic target-specific name for th e | |||
/// specified physical register. | /// specified physical register. | |||
const char *getName(unsigned RegNo) const { | const char *getName(unsigned RegNo) const { | |||
return RegStrings + get(RegNo).Name; | return RegStrings + get(RegNo).Name; | |||
} | } | |||
/// getNumRegs - Return the number of registers this target has (useful f or | /// \brief Return the number of registers this target has (useful for | |||
/// sizing arrays holding per register information) | /// sizing arrays holding per register information) | |||
unsigned getNumRegs() const { | unsigned getNumRegs() const { | |||
return NumRegs; | return NumRegs; | |||
} | } | |||
/// getNumSubRegIndices - Return the number of sub-register indices | /// \brief Return the number of sub-register indices | |||
/// understood by the target. Index 0 is reserved for the no-op sub-regis ter, | /// understood by the target. Index 0 is reserved for the no-op sub-regis ter, | |||
/// while 1 to getNumSubRegIndices() - 1 represent real sub-registers. | /// while 1 to getNumSubRegIndices() - 1 represent real sub-registers. | |||
unsigned getNumSubRegIndices() const { | unsigned getNumSubRegIndices() const { | |||
return NumSubRegIndices; | return NumSubRegIndices; | |||
} | } | |||
/// getNumRegUnits - Return the number of (native) register units in the | /// \brief Return the number of (native) register units in the | |||
/// target. Register units are numbered from 0 to getNumRegUnits() - 1. T hey | /// target. Register units are numbered from 0 to getNumRegUnits() - 1. T hey | |||
/// can be accessed through MCRegUnitIterator defined below. | /// can be accessed through MCRegUnitIterator defined below. | |||
unsigned getNumRegUnits() const { | unsigned getNumRegUnits() const { | |||
return NumRegUnits; | return NumRegUnits; | |||
} | } | |||
/// getDwarfRegNum - Map a target register to an equivalent dwarf registe r | /// \brief Map a target register to an equivalent dwarf register | |||
/// number. Returns -1 if there is no equivalent value. The second | /// number. Returns -1 if there is no equivalent value. The second | |||
/// parameter allows targets to use different numberings for EH info and | /// parameter allows targets to use different numberings for EH info and | |||
/// debugging info. | /// debugging info. | |||
int getDwarfRegNum(unsigned RegNum, bool isEH) const; | int getDwarfRegNum(unsigned RegNum, bool isEH) const; | |||
/// getLLVMRegNum - Map a dwarf register back to a target register. | /// \brief Map a dwarf register back to a target register. | |||
/// | ||||
int getLLVMRegNum(unsigned RegNum, bool isEH) const; | int getLLVMRegNum(unsigned RegNum, bool isEH) const; | |||
/// getSEHRegNum - Map a target register to an equivalent SEH register | /// \brief Map a target register to an equivalent SEH register | |||
/// number. Returns LLVM register number if there is no equivalent value . | /// number. Returns LLVM register number if there is no equivalent value . | |||
int getSEHRegNum(unsigned RegNum) const; | int getSEHRegNum(unsigned RegNum) const; | |||
regclass_iterator regclass_begin() const { return Classes; } | regclass_iterator regclass_begin() const { return Classes; } | |||
regclass_iterator regclass_end() const { return Classes+NumClasses; } | regclass_iterator regclass_end() const { return Classes+NumClasses; } | |||
unsigned getNumRegClasses() const { | unsigned getNumRegClasses() const { | |||
return (unsigned)(regclass_end()-regclass_begin()); | return (unsigned)(regclass_end()-regclass_begin()); | |||
} | } | |||
/// getRegClass - Returns the register class associated with the enumerat ion | /// \brief Returns the register class associated with the enumeration | |||
/// value. See class MCOperandInfo. | /// value. See class MCOperandInfo. | |||
const MCRegisterClass& getRegClass(unsigned i) const { | const MCRegisterClass& getRegClass(unsigned i) const { | |||
assert(i < getNumRegClasses() && "Register Class ID out of range"); | assert(i < getNumRegClasses() && "Register Class ID out of range"); | |||
return Classes[i]; | return Classes[i]; | |||
} | } | |||
/// getEncodingValue - Returns the encoding for RegNo | /// \brief Returns the encoding for RegNo | |||
uint16_t getEncodingValue(unsigned RegNo) const { | uint16_t getEncodingValue(unsigned RegNo) const { | |||
assert(RegNo < NumRegs && | assert(RegNo < NumRegs && | |||
"Attempting to get encoding for invalid register number!"); | "Attempting to get encoding for invalid register number!"); | |||
return RegEncodingTable[RegNo]; | return RegEncodingTable[RegNo]; | |||
} | } | |||
/// \brief Returns true if RegB is a sub-register of RegA. | ||||
bool isSubRegister(unsigned RegA, unsigned RegB) const { | ||||
return isSuperRegister(RegB, RegA); | ||||
} | ||||
/// \brief Returns true if RegB is a super-register of RegA. | ||||
bool isSuperRegister(unsigned RegA, unsigned RegB) const; | ||||
/// \brief Returns true if RegB is a sub-register of RegA or if RegB == R | ||||
egA. | ||||
bool isSubRegisterEq(unsigned RegA, unsigned RegB) const { | ||||
return isSuperRegisterEq(RegB, RegA); | ||||
} | ||||
/// \brief Returns true if RegB is a super-register of RegA or if | ||||
/// RegB == RegA. | ||||
bool isSuperRegisterEq(unsigned RegA, unsigned RegB) const { | ||||
return RegA == RegB || isSuperRegister(RegA, RegB); | ||||
} | ||||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Register List Iterators | // Register List Iterators | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// MCRegisterInfo provides lists of super-registers, sub-registers, and | // MCRegisterInfo provides lists of super-registers, sub-registers, and | |||
// aliasing registers. Use these iterator classes to traverse the lists. | // aliasing registers. Use these iterator classes to traverse the lists. | |||
/// MCSubRegIterator enumerates all sub-registers of Reg. | /// MCSubRegIterator enumerates all sub-registers of Reg. | |||
skipping to change at line 425 | skipping to change at line 454 | |||
public: | public: | |||
MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI, | MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI, | |||
bool IncludeSelf) { | bool IncludeSelf) { | |||
init(Reg, MCRI->DiffLists + MCRI->get(Reg).Overlaps); | init(Reg, MCRI->DiffLists + MCRI->get(Reg).Overlaps); | |||
// Initially, the iterator points to Reg itself. | // Initially, the iterator points to Reg itself. | |||
if (!IncludeSelf) | if (!IncludeSelf) | |||
++*this; | ++*this; | |||
} | } | |||
}; | }; | |||
// Definition for isSuperRegister. Put it down here since it needs the | ||||
// iterator defined above in addition to the MCRegisterInfo class itself. | ||||
inline bool MCRegisterInfo::isSuperRegister(unsigned RegA, unsigned RegB) c | ||||
onst{ | ||||
for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I) | ||||
if (*I == RegB) | ||||
return true; | ||||
return false; | ||||
} | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Register Units | // Register Units | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Register units are used to compute register aliasing. Every register has at | // Register units are used to compute register aliasing. Every register has at | |||
// least one register unit, but it can have more. Two registers overlap if and | // least one register unit, but it can have more. Two registers overlap if and | |||
// only if they have a common register unit. | // only if they have a common register unit. | |||
// | // | |||
// A target with a complicated sub-register structure will typically have m any | // A target with a complicated sub-register structure will typically have m any | |||
// fewer register units than actual registers. MCRI::getNumRegUnits() retur ns | // fewer register units than actual registers. MCRI::getNumRegUnits() retur ns | |||
// the number of register units in the target. | // the number of register units in the target. | |||
// MCRegUnitIterator enumerates a list of register units for Reg. The list is | // MCRegUnitIterator enumerates a list of register units for Reg. The list is | |||
// in ascending numerical order. | // in ascending numerical order. | |||
class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator { | class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator { | |||
public: | public: | |||
/// MCRegUnitIterator - Create an iterator that traverses the register un its | /// MCRegUnitIterator - Create an iterator that traverses the register un its | |||
/// in Reg. | /// in Reg. | |||
MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) { | MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) { | |||
assert(Reg && "Null register has no regunits"); | ||||
// Decode the RegUnits MCRegisterDesc field. | // Decode the RegUnits MCRegisterDesc field. | |||
unsigned RU = MCRI->get(Reg).RegUnits; | unsigned RU = MCRI->get(Reg).RegUnits; | |||
unsigned Scale = RU & 15; | unsigned Scale = RU & 15; | |||
unsigned Offset = RU >> 4; | unsigned Offset = RU >> 4; | |||
// Initialize the iterator to Reg * Scale, and the List pointer to | // Initialize the iterator to Reg * Scale, and the List pointer to | |||
// DiffLists + Offset. | // DiffLists + Offset. | |||
init(Reg * Scale, MCRI->DiffLists + Offset); | init(Reg * Scale, MCRI->DiffLists + Offset); | |||
// That may not be a valid unit, we need to advance by one to get the r eal | // That may not be a valid unit, we need to advance by one to get the r eal | |||
skipping to change at line 483 | skipping to change at line 522 | |||
class MCRegUnitRootIterator { | class MCRegUnitRootIterator { | |||
uint16_t Reg0; | uint16_t Reg0; | |||
uint16_t Reg1; | uint16_t Reg1; | |||
public: | public: | |||
MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) { | MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) { | |||
assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit"); | assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit"); | |||
Reg0 = MCRI->RegUnitRoots[RegUnit][0]; | Reg0 = MCRI->RegUnitRoots[RegUnit][0]; | |||
Reg1 = MCRI->RegUnitRoots[RegUnit][1]; | Reg1 = MCRI->RegUnitRoots[RegUnit][1]; | |||
} | } | |||
/// Dereference to get the current root register. | /// \brief Dereference to get the current root register. | |||
unsigned operator*() const { | unsigned operator*() const { | |||
return Reg0; | return Reg0; | |||
} | } | |||
/// isValid - Check if the iterator is at the end of the list. | /// \brief Check if the iterator is at the end of the list. | |||
bool isValid() const { | bool isValid() const { | |||
return Reg0; | return Reg0; | |||
} | } | |||
/// Preincrement to move to the next root register. | /// \brief Preincrement to move to the next root register. | |||
void operator++() { | void operator++() { | |||
assert(isValid() && "Cannot move off the end of the list."); | assert(isValid() && "Cannot move off the end of the list."); | |||
Reg0 = Reg1; | Reg0 = Reg1; | |||
Reg1 = 0; | Reg1 = 0; | |||
} | } | |||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 35 change blocks. | ||||
29 lines changed or deleted | 71 lines changed or added | |||
MCSchedule.h | MCSchedule.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the classes used to describe a subtarget's machine mod el | // This file defines the classes used to describe a subtarget's machine mod el | |||
// for scheduling and other instruction cost heuristics. | // for scheduling and other instruction cost heuristics. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCSCHEDMODEL_H | #ifndef LLVM_MC_MCSCHEDULE_H | |||
#define LLVM_MC_MCSCHEDMODEL_H | #define LLVM_MC_MCSCHEDULE_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
struct InstrItinerary; | struct InstrItinerary; | |||
/// Define a kind of processor resource that will be modeled by the schedul er. | /// Define a kind of processor resource that will be modeled by the schedul er. | |||
struct MCProcResourceDesc { | struct MCProcResourceDesc { | |||
skipping to change at line 158 | skipping to change at line 158 | |||
// | // | |||
// (0) Out-of-order processor, or in-order with bundled dependencies. | // (0) Out-of-order processor, or in-order with bundled dependencies. | |||
// RAW dependencies may be dispatched in the same cycle. | // RAW dependencies may be dispatched in the same cycle. | |||
// Optional InstrItinerary OperandCycles provides expected latency. | // Optional InstrItinerary OperandCycles provides expected latency. | |||
// | // | |||
// (>0) In-order processor with variable latencies. | // (>0) In-order processor with variable latencies. | |||
// Use the greater of this value or the cycle of the last InstrStage . | // Use the greater of this value or the cycle of the last InstrStage . | |||
// Optional InstrItinerary OperandCycles provides expected latency. | // Optional InstrItinerary OperandCycles provides expected latency. | |||
// TODO: can't yet specify both min and expected latency per operand . | // TODO: can't yet specify both min and expected latency per operand . | |||
int MinLatency; | int MinLatency; | |||
static const unsigned DefaultMinLatency = -1; | static const int DefaultMinLatency = -1; | |||
// LoadLatency is the expected latency of load instructions. | // LoadLatency is the expected latency of load instructions. | |||
// | // | |||
// If MinLatency >= 0, this may be overriden for individual load opcodes by | // If MinLatency >= 0, this may be overriden for individual load opcodes by | |||
// InstrItinerary OperandCycles. | // InstrItinerary OperandCycles. | |||
unsigned LoadLatency; | unsigned LoadLatency; | |||
static const unsigned DefaultLoadLatency = 4; | static const unsigned DefaultLoadLatency = 4; | |||
// HighLatency is the expected latency of "very high latency" operations. | // HighLatency is the expected latency of "very high latency" operations. | |||
// See TargetInstrInfo::isHighLatencyDef(). | // See TargetInstrInfo::isHighLatencyDef(). | |||
// By default, this is set to an arbitrarily high number of cycles | // By default, this is set to an arbitrarily high number of cycles | |||
// likely to have some impact on scheduling heuristics. | // likely to have some impact on scheduling heuristics. | |||
// If MinLatency >= 0, this may be overriden by InstrItinData OperandCycl es. | // If MinLatency >= 0, this may be overriden by InstrItinData OperandCycl es. | |||
unsigned HighLatency; | unsigned HighLatency; | |||
static const unsigned DefaultHighLatency = 10; | static const unsigned DefaultHighLatency = 10; | |||
// ILPWindow is the number of cycles that the scheduler effectively ignor | ||||
es | ||||
// before attempting to hide latency. This should be zero for in-order cp | ||||
us to | ||||
// always hide expected latency. For out-of-order cpus, it may be tweaked | ||||
as | ||||
// desired to roughly approximate instruction buffers. The actual thresho | ||||
ld 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 fai | ||||
rly | ||||
// obviously useless and makes register pressure heuristics more effectiv | ||||
e. | ||||
unsigned ILPWindow; | ||||
static const unsigned DefaultILPWindow = 0; | ||||
// MispredictPenalty is the typical number of extra cycles the processor | // MispredictPenalty is the typical number of extra cycles the processor | |||
// takes to recover from a branch misprediction. | // takes to recover from a branch misprediction. | |||
unsigned MispredictPenalty; | unsigned MispredictPenalty; | |||
static const unsigned DefaultMispredictPenalty = 10; | static const unsigned DefaultMispredictPenalty = 10; | |||
private: | private: | |||
unsigned ProcID; | unsigned ProcID; | |||
const MCProcResourceDesc *ProcResourceTable; | const MCProcResourceDesc *ProcResourceTable; | |||
const MCSchedClassDesc *SchedClassTable; | const MCSchedClassDesc *SchedClassTable; | |||
unsigned NumProcResourceKinds; | unsigned NumProcResourceKinds; | |||
skipping to change at line 199 | skipping to change at line 209 | |||
public: | public: | |||
// Default's must be specified as static const literals so that tablegene rated | // Default's must be specified as static const literals so that tablegene rated | |||
// target code can use it in static initializers. The defaults need to be | // target code can use it in static initializers. The defaults need to be | |||
// initialized in this default ctor because some clients directly instant iate | // initialized in this default ctor because some clients directly instant iate | |||
// MCSchedModel instead of using a generated itinerary. | // MCSchedModel instead of using a generated itinerary. | |||
MCSchedModel(): IssueWidth(DefaultIssueWidth), | MCSchedModel(): IssueWidth(DefaultIssueWidth), | |||
MinLatency(DefaultMinLatency), | MinLatency(DefaultMinLatency), | |||
LoadLatency(DefaultLoadLatency), | LoadLatency(DefaultLoadLatency), | |||
HighLatency(DefaultHighLatency), | HighLatency(DefaultHighLatency), | |||
ILPWindow(DefaultILPWindow), | ||||
MispredictPenalty(DefaultMispredictPenalty), | MispredictPenalty(DefaultMispredictPenalty), | |||
ProcID(0), ProcResourceTable(0), SchedClassTable(0), | ProcID(0), ProcResourceTable(0), SchedClassTable(0), | |||
NumProcResourceKinds(0), NumSchedClasses(0), | NumProcResourceKinds(0), NumSchedClasses(0), | |||
InstrItineraries(0) { | InstrItineraries(0) { | |||
(void)NumProcResourceKinds; | (void)NumProcResourceKinds; | |||
(void)NumSchedClasses; | (void)NumSchedClasses; | |||
} | } | |||
// Table-gen driven ctor. | // Table-gen driven ctor. | |||
MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp, | MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned ilp, | |||
unsigned pi, const MCProcResourceDesc *pr, | unsigned mp, unsigned pi, const MCProcResourceDesc *pr, | |||
const MCSchedClassDesc *sc, unsigned npr, unsigned nsc, | const MCSchedClassDesc *sc, unsigned npr, unsigned nsc, | |||
const InstrItinerary *ii): | const InstrItinerary *ii): | |||
IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl), | IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl), | |||
MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr), | ILPWindow(ilp), MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr ), | |||
SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc), | SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc), | |||
InstrItineraries(ii) {} | InstrItineraries(ii) {} | |||
unsigned getProcessorID() const { return ProcID; } | unsigned getProcessorID() const { return ProcID; } | |||
/// Does this machine model include instruction-level scheduling. | /// Does this machine model include instruction-level scheduling. | |||
bool hasInstrSchedModel() const { return SchedClassTable; } | bool hasInstrSchedModel() const { return SchedClassTable; } | |||
unsigned getNumProcResourceKinds() const { | unsigned getNumProcResourceKinds() const { | |||
return NumProcResourceKinds; | return NumProcResourceKinds; | |||
End of changes. 6 change blocks. | ||||
6 lines changed or deleted | 24 lines changed or added | |||
MCSection.h | MCSection.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the MCSection class. | // This file declares the MCSection class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCSECTION_H | #ifndef LLVM_MC_MCSECTION_H | |||
#define LLVM_MC_MCSECTION_H | #define LLVM_MC_MCSECTION_H | |||
#include "llvm/ADT/StringRef.h" | ||||
#include "llvm/MC/SectionKind.h" | #include "llvm/MC/SectionKind.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
namespace llvm { | namespace llvm { | |||
class MCAsmInfo; | class MCAsmInfo; | |||
class MCExpr; | ||||
class raw_ostream; | class raw_ostream; | |||
/// MCSection - Instances of this class represent a uniqued identifier fo r a | /// MCSection - Instances of this class represent a uniqued identifier fo r a | |||
/// section in the current translation unit. The MCContext class uniques and | /// section in the current translation unit. The MCContext class uniques and | |||
/// creates these. | /// creates these. | |||
class MCSection { | class MCSection { | |||
public: | public: | |||
enum SectionVariant { | enum SectionVariant { | |||
SV_COFF = 0, | SV_COFF = 0, | |||
SV_ELF, | SV_ELF, | |||
skipping to change at line 50 | skipping to change at line 52 | |||
SectionVariant Variant; | SectionVariant Variant; | |||
SectionKind Kind; | SectionKind Kind; | |||
public: | public: | |||
virtual ~MCSection(); | virtual ~MCSection(); | |||
SectionKind getKind() const { return Kind; } | SectionKind getKind() const { return Kind; } | |||
SectionVariant getVariant() const { return Variant; } | SectionVariant getVariant() const { return Variant; } | |||
virtual void PrintSwitchToSection(const MCAsmInfo &MAI, | virtual void PrintSwitchToSection(const MCAsmInfo &MAI, | |||
raw_ostream &OS) const = 0; | raw_ostream &OS, | |||
const MCExpr *Subsection) const = 0; | ||||
// Convenience routines to get label names for the beginning/end of a | ||||
// section. | ||||
virtual std::string getLabelBeginName() const = 0; | ||||
virtual std::string getLabelEndName() const = 0; | ||||
/// isBaseAddressKnownZero - Return true if we know that this section w ill | /// isBaseAddressKnownZero - Return true if we know that this section w ill | |||
/// get a base address of zero. In cases where we know that this is tr ue we | /// get a base address of zero. In cases where we know that this is tr ue we | |||
/// can emit section offsets as direct references to avoid a subtractio n | /// can emit section offsets as direct references to avoid a subtractio n | |||
/// from the base of the section, saving a relocation. | /// from the base of the section, saving a relocation. | |||
virtual bool isBaseAddressKnownZero() const { | virtual bool isBaseAddressKnownZero() const { | |||
return false; | return false; | |||
} | } | |||
// UseCodeAlign - Return true if a .align directive should use | // UseCodeAlign - Return true if a .align directive should use | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 9 lines changed or added | |||
MCSectionCOFF.h | MCSectionCOFF.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the MCSectionCOFF class. | // This file declares the MCSectionCOFF class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCSECTIONCOFF_H | #ifndef LLVM_MC_MCSECTIONCOFF_H | |||
#define LLVM_MC_MCSECTIONCOFF_H | #define LLVM_MC_MCSECTIONCOFF_H | |||
#include "llvm/ADT/StringRef.h" | ||||
#include "llvm/MC/MCSection.h" | #include "llvm/MC/MCSection.h" | |||
#include "llvm/Support/COFF.h" | #include "llvm/Support/COFF.h" | |||
#include "llvm/ADT/StringRef.h" | ||||
namespace llvm { | namespace llvm { | |||
/// MCSectionCOFF - This represents a section on Windows | /// MCSectionCOFF - This represents a section on Windows | |||
class MCSectionCOFF : public MCSection { | class MCSectionCOFF : public MCSection { | |||
// The memory for this string is stored in the same MCContext as *this. | // The memory for this string is stored in the same MCContext as *this. | |||
StringRef SectionName; | StringRef SectionName; | |||
/// Characteristics - This is the Characteristics field of a section, | /// Characteristics - This is the Characteristics field of a section, | |||
// drawn from the enums below. | // drawn from the enums below. | |||
skipping to change at line 53 | skipping to change at line 53 | |||
"alignment must not be set upon section creation"); | "alignment must not be set upon section creation"); | |||
} | } | |||
~MCSectionCOFF(); | ~MCSectionCOFF(); | |||
public: | public: | |||
/// ShouldOmitSectionDirective - Decides whether a '.section' directive | /// ShouldOmitSectionDirective - Decides whether a '.section' directive | |||
/// should be printed before the section name | /// should be printed before the section name | |||
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) c onst; | bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) c onst; | |||
StringRef getSectionName() const { return SectionName; } | StringRef getSectionName() const { return SectionName; } | |||
virtual std::string getLabelBeginName() const { | ||||
return SectionName.str() + "_begin"; | ||||
} | ||||
virtual std::string getLabelEndName() const { | ||||
return SectionName.str() + "_end"; | ||||
} | ||||
unsigned getCharacteristics() const { return Characteristics; } | unsigned getCharacteristics() const { return Characteristics; } | |||
int getSelection () const { return Selection; } | int getSelection () const { return Selection; } | |||
virtual void PrintSwitchToSection(const MCAsmInfo &MAI, | virtual void PrintSwitchToSection(const MCAsmInfo &MAI, | |||
raw_ostream &OS) const; | raw_ostream &OS, | |||
const MCExpr *Subsection) const; | ||||
virtual bool UseCodeAlign() const; | virtual bool UseCodeAlign() const; | |||
virtual bool isVirtualSection() const; | virtual bool isVirtualSection() const; | |||
static bool classof(const MCSection *S) { | static bool classof(const MCSection *S) { | |||
return S->getVariant() == SV_COFF; | return S->getVariant() == SV_COFF; | |||
} | } | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
End of changes. 4 change blocks. | ||||
2 lines changed or deleted | 9 lines changed or added | |||
MCSectionELF.h | MCSectionELF.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the MCSectionELF class. | // This file declares the MCSectionELF class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCSECTIONELF_H | #ifndef LLVM_MC_MCSECTIONELF_H | |||
#define LLVM_MC_MCSECTIONELF_H | #define LLVM_MC_MCSECTIONELF_H | |||
#include "llvm/ADT/StringRef.h" | ||||
#include "llvm/MC/MCSection.h" | #include "llvm/MC/MCSection.h" | |||
#include "llvm/Support/Debug.h" | ||||
#include "llvm/Support/ELF.h" | #include "llvm/Support/ELF.h" | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/Support/raw_ostream.h" | |||
namespace llvm { | namespace llvm { | |||
class MCSymbol; | class MCSymbol; | |||
/// MCSectionELF - This represents a section on linux, lots of unix variant s | /// MCSectionELF - This represents a section on linux, lots of unix variant s | |||
/// and some bare metal systems. | /// and some bare metal systems. | |||
class MCSectionELF : public MCSection { | class MCSectionELF : public MCSection { | |||
/// SectionName - This is the name of the section. The referenced memory is | /// SectionName - This is the name of the section. The referenced memory is | |||
/// owned by TargetLoweringObjectFileELF's ELFUniqueMap. | /// owned by TargetLoweringObjectFileELF's ELFUniqueMap. | |||
skipping to change at line 60 | skipping to change at line 62 | |||
: MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags), | : MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags), | |||
EntrySize(entrySize), Group(group) {} | EntrySize(entrySize), Group(group) {} | |||
~MCSectionELF(); | ~MCSectionELF(); | |||
public: | public: | |||
/// ShouldOmitSectionDirective - Decides whether a '.section' directive | /// ShouldOmitSectionDirective - Decides whether a '.section' directive | |||
/// should be printed before the section name | /// should be printed before the section name | |||
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) con st; | bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) con st; | |||
StringRef getSectionName() const { return SectionName; } | StringRef getSectionName() const { return SectionName; } | |||
virtual std::string getLabelBeginName() const { | ||||
return SectionName.str() + "_begin"; } | ||||
virtual std::string getLabelEndName() const { | ||||
return SectionName.str() + "_end"; | ||||
} | ||||
unsigned getType() const { return Type; } | unsigned getType() const { return Type; } | |||
unsigned getFlags() const { return Flags; } | unsigned getFlags() const { return Flags; } | |||
unsigned getEntrySize() const { return EntrySize; } | unsigned getEntrySize() const { return EntrySize; } | |||
const MCSymbol *getGroup() const { return Group; } | const MCSymbol *getGroup() const { return Group; } | |||
void PrintSwitchToSection(const MCAsmInfo &MAI, | void PrintSwitchToSection(const MCAsmInfo &MAI, | |||
raw_ostream &OS) const; | raw_ostream &OS, | |||
const MCExpr *Subsection) const; | ||||
virtual bool UseCodeAlign() const; | virtual bool UseCodeAlign() const; | |||
virtual bool isVirtualSection() const; | virtual bool isVirtualSection() const; | |||
/// isBaseAddressKnownZero - We know that non-allocatable sections (like | /// isBaseAddressKnownZero - We know that non-allocatable sections (like | |||
/// debug info) have a base of zero. | /// debug info) have a base of zero. | |||
virtual bool isBaseAddressKnownZero() const { | virtual bool isBaseAddressKnownZero() const { | |||
return (getFlags() & ELF::SHF_ALLOC) == 0; | return (getFlags() & ELF::SHF_ALLOC) == 0; | |||
} | } | |||
static bool classof(const MCSection *S) { | static bool classof(const MCSection *S) { | |||
End of changes. 5 change blocks. | ||||
2 lines changed or deleted | 10 lines changed or added | |||
MCSectionMachO.h | MCSectionMachO.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the MCSectionMachO class. | // This file declares the MCSectionMachO class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCSECTIONMACHO_H | #ifndef LLVM_MC_MCSECTIONMACHO_H | |||
#define LLVM_MC_MCSECTIONMACHO_H | #define LLVM_MC_MCSECTIONMACHO_H | |||
#include "llvm/MC/MCSection.h" | ||||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/MC/MCSection.h" | ||||
namespace llvm { | namespace llvm { | |||
/// MCSectionMachO - This represents a section on a Mach-O system (used by | /// MCSectionMachO - This represents a section on a Mach-O system (used by | |||
/// Mac OS X). On a Mac system, these are also described in | /// Mac OS X). On a Mac system, these are also described in | |||
/// /usr/include/mach-o/loader.h. | /// /usr/include/mach-o/loader.h. | |||
class MCSectionMachO : public MCSection { | class MCSectionMachO : public MCSection { | |||
char SegmentName[16]; // Not necessarily null terminated! | char SegmentName[16]; // Not necessarily null terminated! | |||
char SectionName[16]; // Not necessarily null terminated! | char SectionName[16]; // Not necessarily null terminated! | |||
skipping to change at line 147 | skipping to change at line 147 | |||
return StringRef(SegmentName, 16); | return StringRef(SegmentName, 16); | |||
return StringRef(SegmentName); | return StringRef(SegmentName); | |||
} | } | |||
StringRef getSectionName() const { | StringRef getSectionName() const { | |||
// SectionName is not necessarily null terminated! | // SectionName is not necessarily null terminated! | |||
if (SectionName[15]) | if (SectionName[15]) | |||
return StringRef(SectionName, 16); | return StringRef(SectionName, 16); | |||
return StringRef(SectionName); | return StringRef(SectionName); | |||
} | } | |||
virtual std::string getLabelBeginName() const { | ||||
return StringRef(getSegmentName().str() + getSectionName().str() + "_be | ||||
gin"); | ||||
} | ||||
virtual std::string getLabelEndName() const { | ||||
return StringRef(getSegmentName().str() + getSectionName().str() + "_en | ||||
d"); | ||||
} | ||||
unsigned getTypeAndAttributes() const { return TypeAndAttributes; } | unsigned getTypeAndAttributes() const { return TypeAndAttributes; } | |||
unsigned getStubSize() const { return Reserved2; } | unsigned getStubSize() const { return Reserved2; } | |||
unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; } | unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; } | |||
bool hasAttribute(unsigned Value) const { | bool hasAttribute(unsigned Value) const { | |||
return (TypeAndAttributes & Value) != 0; | return (TypeAndAttributes & Value) != 0; | |||
} | } | |||
/// ParseSectionSpecifier - Parse the section specifier indicated by "Spe c". | /// ParseSectionSpecifier - Parse the section specifier indicated by "Spe c". | |||
/// This is a string that can appear after a .section directive in a mach -o | /// This is a string that can appear after a .section directive in a mach -o | |||
skipping to change at line 169 | skipping to change at line 177 | |||
/// specifier is present, this returns a string indicating the problem. | /// specifier is present, this returns a string indicating the problem. | |||
/// If no TAA was parsed, TAA is not altered, and TAAWasSet becomes false . | /// If no TAA was parsed, TAA is not altered, and TAAWasSet becomes false . | |||
static std::string ParseSectionSpecifier(StringRef Spec, // In. | static std::string ParseSectionSpecifier(StringRef Spec, // In. | |||
StringRef &Segment, // Out. | StringRef &Segment, // Out. | |||
StringRef &Section, // Out. | StringRef &Section, // Out. | |||
unsigned &TAA, // Out. | unsigned &TAA, // Out. | |||
bool &TAAParsed, // Out. | bool &TAAParsed, // Out. | |||
unsigned &StubSize); // Out. | unsigned &StubSize); // Out. | |||
virtual void PrintSwitchToSection(const MCAsmInfo &MAI, | virtual void PrintSwitchToSection(const MCAsmInfo &MAI, | |||
raw_ostream &OS) const; | raw_ostream &OS, | |||
const MCExpr *Subsection) const; | ||||
virtual bool UseCodeAlign() const; | virtual bool UseCodeAlign() const; | |||
virtual bool isVirtualSection() const; | virtual bool isVirtualSection() const; | |||
static bool classof(const MCSection *S) { | static bool classof(const MCSection *S) { | |||
return S->getVariant() == SV_MachO; | return S->getVariant() == SV_MachO; | |||
} | } | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
End of changes. 4 change blocks. | ||||
2 lines changed or deleted | 13 lines changed or added | |||
MCStreamer.h | MCStreamer.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the MCStreamer class. | // This file declares the MCStreamer class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCSTREAMER_H | #ifndef LLVM_MC_MCSTREAMER_H | |||
#define LLVM_MC_MCSTREAMER_H | #define LLVM_MC_MCSTREAMER_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/MC/MCAssembler.h" | ||||
#include "llvm/MC/MCDirectives.h" | #include "llvm/MC/MCDirectives.h" | |||
#include "llvm/MC/MCDwarf.h" | #include "llvm/MC/MCDwarf.h" | |||
#include "llvm/MC/MCWin64EH.h" | #include "llvm/MC/MCWin64EH.h" | |||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/ADT/SmallVector.h" | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class MCAsmBackend; | class MCAsmBackend; | |||
class MCCodeEmitter; | class MCCodeEmitter; | |||
class MCContext; | class MCContext; | |||
class MCExpr; | class MCExpr; | |||
class MCInst; | class MCInst; | |||
class MCInstPrinter; | class MCInstPrinter; | |||
class MCSection; | class MCSection; | |||
class MCSymbol; | class MCSymbol; | |||
class StringRef; | class StringRef; | |||
class Twine; | class Twine; | |||
class raw_ostream; | class raw_ostream; | |||
class formatted_raw_ostream; | class formatted_raw_ostream; | |||
typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair; | ||||
/// MCStreamer - Streaming machine code generation interface. This inter face | /// MCStreamer - Streaming machine code generation interface. This inter face | |||
/// is intended to provide a programatic interface that is very similar t o the | /// is intended to provide a programatic interface that is very similar t o the | |||
/// level that an assembler .s file provides. It has callbacks to emit b ytes, | /// level that an assembler .s file provides. It has callbacks to emit b ytes, | |||
/// handle directives, etc. The implementation of this interface retains | /// handle directives, etc. The implementation of this interface retains | |||
/// state to know what the current section is etc. | /// state to know what the current section is etc. | |||
/// | /// | |||
/// There are multiple implementations of this interface: one for writing out | /// There are multiple implementations of this interface: one for writing out | |||
/// a .s file, and implementations that write out .o files of various for mats. | /// a .s file, and implementations that write out .o files of various for mats. | |||
/// | /// | |||
class MCStreamer { | class MCStreamer { | |||
public: | ||||
enum StreamerKind { | ||||
SK_AsmStreamer, | ||||
SK_NullStreamer, | ||||
SK_RecordStreamer, | ||||
// MCObjectStreamer subclasses. | ||||
SK_ELFStreamer, | ||||
SK_ARMELFStreamer, | ||||
SK_MachOStreamer, | ||||
SK_PureStreamer, | ||||
SK_MipsELFStreamer, | ||||
SK_WinCOFFStreamer | ||||
}; | ||||
private: | ||||
const StreamerKind Kind; | ||||
MCContext &Context; | MCContext &Context; | |||
MCStreamer(const MCStreamer&) LLVM_DELETED_FUNCTION; | MCStreamer(const MCStreamer&) LLVM_DELETED_FUNCTION; | |||
MCStreamer &operator=(const MCStreamer&) LLVM_DELETED_FUNCTION; | MCStreamer &operator=(const MCStreamer&) LLVM_DELETED_FUNCTION; | |||
bool EmitEHFrame; | bool EmitEHFrame; | |||
bool EmitDebugFrame; | bool EmitDebugFrame; | |||
std::vector<MCDwarfFrameInfo> FrameInfos; | std::vector<MCDwarfFrameInfo> FrameInfos; | |||
MCDwarfFrameInfo *getCurrentFrameInfo(); | MCDwarfFrameInfo *getCurrentFrameInfo(); | |||
MCSymbol *EmitCFICommon(); | ||||
void EnsureValidFrame(); | void EnsureValidFrame(); | |||
std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos; | std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos; | |||
MCWin64EHUnwindInfo *CurrentW64UnwindInfo; | MCWin64EHUnwindInfo *CurrentW64UnwindInfo; | |||
void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame); | void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame); | |||
void EnsureValidW64UnwindInfo(); | void EnsureValidW64UnwindInfo(); | |||
MCSymbol* LastSymbol; | MCSymbol* LastSymbol; | |||
/// SectionStack - This is stack of current and previous section | /// SectionStack - This is stack of current and previous section | |||
/// values saved by PushSection. | /// values saved by PushSection. | |||
SmallVector<std::pair<const MCSection *, | SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionSt | |||
const MCSection *>, 4> SectionStack; | ack; | |||
bool AutoInitSections; | ||||
protected: | protected: | |||
MCStreamer(MCContext &Ctx); | MCStreamer(StreamerKind Kind, MCContext &Ctx); | |||
const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, | const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, | |||
const MCSymbol *B); | const MCSymbol *B); | |||
const MCExpr *ForceExpAbs(const MCExpr* Expr); | const MCExpr *ForceExpAbs(const MCExpr* Expr); | |||
void RecordProcStart(MCDwarfFrameInfo &Frame); | void RecordProcStart(MCDwarfFrameInfo &Frame); | |||
virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); | virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); | |||
void RecordProcEnd(MCDwarfFrameInfo &Frame); | void RecordProcEnd(MCDwarfFrameInfo &Frame); | |||
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame); | virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame); | |||
void EmitFrames(bool usingCFI); | void EmitFrames(bool usingCFI); | |||
MCWin64EHUnwindInfo *getCurrentW64UnwindInfo(){return CurrentW64UnwindI nfo;} | MCWin64EHUnwindInfo *getCurrentW64UnwindInfo(){return CurrentW64UnwindI nfo;} | |||
void EmitW64Tables(); | void EmitW64Tables(); | |||
public: | public: | |||
virtual ~MCStreamer(); | virtual ~MCStreamer(); | |||
StreamerKind getKind() const { return Kind; } | ||||
/// State management | ||||
/// | ||||
virtual void reset(); | ||||
MCContext &getContext() const { return Context; } | MCContext &getContext() const { return Context; } | |||
unsigned getNumFrameInfos() { | unsigned getNumFrameInfos() { | |||
return FrameInfos.size(); | return FrameInfos.size(); | |||
} | } | |||
const MCDwarfFrameInfo &getFrameInfo(unsigned i) { | const MCDwarfFrameInfo &getFrameInfo(unsigned i) { | |||
return FrameInfos[i]; | return FrameInfos[i]; | |||
} | } | |||
skipping to change at line 149 | skipping to change at line 178 | |||
/// AddBlankLine - Emit a blank line to a .s file to pretty it up. | /// AddBlankLine - Emit a blank line to a .s file to pretty it up. | |||
virtual void AddBlankLine() {} | virtual void AddBlankLine() {} | |||
/// @} | /// @} | |||
/// @name Symbol & Section Management | /// @name Symbol & Section Management | |||
/// @{ | /// @{ | |||
/// getCurrentSection - Return the current section that the streamer is | /// getCurrentSection - Return the current section that the streamer is | |||
/// emitting code to. | /// emitting code to. | |||
const MCSection *getCurrentSection() const { | MCSectionSubPair getCurrentSection() const { | |||
if (!SectionStack.empty()) | if (!SectionStack.empty()) | |||
return SectionStack.back().first; | return SectionStack.back().first; | |||
return NULL; | return MCSectionSubPair(); | |||
} | } | |||
/// getPreviousSection - Return the previous section that the streamer is | /// getPreviousSection - Return the previous section that the streamer is | |||
/// emitting code to. | /// emitting code to. | |||
const MCSection *getPreviousSection() const { | MCSectionSubPair getPreviousSection() const { | |||
if (!SectionStack.empty()) | if (!SectionStack.empty()) | |||
return SectionStack.back().second; | return SectionStack.back().second; | |||
return NULL; | return MCSectionSubPair(); | |||
} | } | |||
/// ChangeSection - Update streamer for a new active section. | /// ChangeSection - Update streamer for a new active section. | |||
/// | /// | |||
/// This is called by PopSection and SwitchSection, if the current | /// This is called by PopSection and SwitchSection, if the current | |||
/// section changes. | /// section changes. | |||
virtual void ChangeSection(const MCSection *) = 0; | virtual void ChangeSection(const MCSection *, const MCExpr *) = 0; | |||
/// pushSection - Save the current and previous section on the | /// pushSection - Save the current and previous section on the | |||
/// section stack. | /// section stack. | |||
void PushSection() { | void PushSection() { | |||
SectionStack.push_back(std::make_pair(getCurrentSection(), | SectionStack.push_back(std::make_pair(getCurrentSection(), | |||
getPreviousSection())); | getPreviousSection())); | |||
} | } | |||
/// popSection - Restore the current and previous section from | /// popSection - Restore the current and previous section from | |||
/// the section stack. Calls ChangeSection as needed. | /// the section stack. Calls ChangeSection as needed. | |||
/// | /// | |||
/// Returns false if the stack was empty. | /// Returns false if the stack was empty. | |||
bool PopSection() { | bool PopSection() { | |||
if (SectionStack.size() <= 1) | if (SectionStack.size() <= 1) | |||
return false; | return false; | |||
const MCSection *oldSection = SectionStack.pop_back_val().first; | MCSectionSubPair oldSection = SectionStack.pop_back_val().first; | |||
const MCSection *curSection = SectionStack.back().first; | MCSectionSubPair curSection = SectionStack.back().first; | |||
if (oldSection != curSection) | if (oldSection != curSection) | |||
ChangeSection(curSection); | ChangeSection(curSection.first, curSection.second); | |||
return true; | ||||
} | ||||
bool SubSection(const MCExpr *Subsection) { | ||||
if (SectionStack.empty()) | ||||
return false; | ||||
SwitchSection(SectionStack.back().first.first, Subsection); | ||||
return true; | return true; | |||
} | } | |||
/// SwitchSection - Set the current section where code is being emitted to | /// SwitchSection - Set the current section where code is being emitted to | |||
/// @p Section. This is required to update CurSection. | /// @p Section. This is required to update CurSection. | |||
/// | /// | |||
/// This corresponds to assembler directives like .section, .text, etc. | /// This corresponds to assembler directives like .section, .text, etc. | |||
void SwitchSection(const MCSection *Section) { | void SwitchSection(const MCSection *Section, const MCExpr *Subsection = 0) { | |||
assert(Section && "Cannot switch to a null section!"); | assert(Section && "Cannot switch to a null section!"); | |||
const MCSection *curSection = SectionStack.back().first; | MCSectionSubPair curSection = SectionStack.back().first; | |||
SectionStack.back().second = curSection; | SectionStack.back().second = curSection; | |||
if (Section != curSection) { | if (MCSectionSubPair(Section, Subsection) != curSection) { | |||
SectionStack.back().first = Section; | SectionStack.back().first = MCSectionSubPair(Section, Subsection); | |||
ChangeSection(Section); | ChangeSection(Section, Subsection); | |||
} | } | |||
} | } | |||
/// SwitchSectionNoChange - Set the current section where code is being | /// SwitchSectionNoChange - Set the current section where code is being | |||
/// emitted to @p Section. This is required to update CurSection. This | /// emitted to @p Section. This is required to update CurSection. This | |||
/// version does not call ChangeSection. | /// version does not call ChangeSection. | |||
void SwitchSectionNoChange(const MCSection *Section) { | void SwitchSectionNoChange(const MCSection *Section, | |||
const MCExpr *Subsection = 0) { | ||||
assert(Section && "Cannot switch to a null section!"); | assert(Section && "Cannot switch to a null section!"); | |||
const MCSection *curSection = SectionStack.back().first; | MCSectionSubPair curSection = SectionStack.back().first; | |||
SectionStack.back().second = curSection; | SectionStack.back().second = curSection; | |||
if (Section != curSection) | if (MCSectionSubPair(Section, Subsection) != curSection) | |||
SectionStack.back().first = Section; | SectionStack.back().first = MCSectionSubPair(Section, Subsection); | |||
} | ||||
/// Initialize the streamer. | ||||
void InitStreamer() { | ||||
if (AutoInitSections) | ||||
InitSections(); | ||||
} | ||||
/// Tell this MCStreamer to call InitSections upon initialization. | ||||
void setAutoInitSections(bool AutoInitSections) { | ||||
this->AutoInitSections = AutoInitSections; | ||||
} | } | |||
/// InitSections - Create the default sections and set the initial one. | /// InitSections - Create the default sections and set the initial one. | |||
virtual void InitSections() = 0; | virtual void InitSections() = 0; | |||
/// InitToTextSection - Create a text section and switch the streamer t | ||||
o it. | ||||
virtual void InitToTextSection() = 0; | ||||
/// EmitLabel - Emit a label for @p Symbol into the current section. | /// EmitLabel - Emit a label for @p Symbol into the current section. | |||
/// | /// | |||
/// This corresponds to an assembler statement such as: | /// This corresponds to an assembler statement such as: | |||
/// foo: | /// foo: | |||
/// | /// | |||
/// @param Symbol - The symbol to emit. A given symbol should only be | /// @param Symbol - The symbol to emit. A given symbol should only be | |||
/// emitted as a label once, and symbols emitted as a label should neve r be | /// emitted as a label once, and symbols emitted as a label should neve r be | |||
/// used in an assignment. | /// used in an assignment. | |||
virtual void EmitLabel(MCSymbol *Symbol); | virtual void EmitLabel(MCSymbol *Symbol); | |||
virtual void EmitDebugLabel(MCSymbol *Symbol); | ||||
virtual void EmitEHSymAttributes(const MCSymbol *Symbol, | virtual void EmitEHSymAttributes(const MCSymbol *Symbol, | |||
MCSymbol *EHSymbol); | MCSymbol *EHSymbol); | |||
/// EmitAssemblerFlag - Note in the output the specified @p Flag. | /// EmitAssemblerFlag - Note in the output the specified @p Flag. | |||
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0; | virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0; | |||
/// EmitLinkerOptions - Emit the given list @p Options of strings as li | ||||
nker | ||||
/// options into the output. | ||||
virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {} | ||||
/// EmitDataRegion - Note in the output the specified region @p Kind. | /// EmitDataRegion - Note in the output the specified region @p Kind. | |||
virtual void EmitDataRegion(MCDataRegionType Kind) {} | virtual void EmitDataRegion(MCDataRegionType Kind) {} | |||
/// EmitThumbFunc - Note in the output that the specified @p Func is | /// EmitThumbFunc - Note in the output that the specified @p Func is | |||
/// a Thumb mode function (ARM target only). | /// a Thumb mode function (ARM target only). | |||
virtual void EmitThumbFunc(MCSymbol *Func) = 0; | virtual void EmitThumbFunc(MCSymbol *Func) = 0; | |||
/// getOrCreateSymbolData - Get symbol data for given symbol. | ||||
virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol); | ||||
/// EmitAssignment - Emit an assignment of @p Value to @p Symbol. | /// EmitAssignment - Emit an assignment of @p Value to @p Symbol. | |||
/// | /// | |||
/// This corresponds to an assembler statement such as: | /// This corresponds to an assembler statement such as: | |||
/// symbol = value | /// symbol = value | |||
/// | /// | |||
/// The assignment generates no code, but has the side effect of bindin g the | /// The assignment generates no code, but has the side effect of bindin g the | |||
/// value in the current context. For the assembly streamer, this print s the | /// value in the current context. For the assembly streamer, this print s the | |||
/// binding into the .s file. | /// binding into the .s file. | |||
/// | /// | |||
/// @param Symbol - The symbol being assigned to. | /// @param Symbol - The symbol being assigned to. | |||
skipping to change at line 349 | skipping to change at line 410 | |||
uint64_t Size, unsigned ByteAlignment = 0) = 0; | uint64_t Size, unsigned ByteAlignment = 0) = 0; | |||
/// @} | /// @} | |||
/// @name Generating Data | /// @name Generating Data | |||
/// @{ | /// @{ | |||
/// EmitBytes - Emit the bytes in \p Data into the output. | /// EmitBytes - Emit the bytes in \p Data into the output. | |||
/// | /// | |||
/// This is used to implement assembler directives such as .byte, .asci i, | /// This is used to implement assembler directives such as .byte, .asci i, | |||
/// etc. | /// etc. | |||
virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0; | virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0) = 0; | |||
/// EmitValue - Emit the expression @p Value into the output as a nativ e | /// EmitValue - Emit the expression @p Value into the output as a nativ e | |||
/// integer of the given @p Size bytes. | /// integer of the given @p Size bytes. | |||
/// | /// | |||
/// This is used to implement assembler directives such as .word, .quad , | /// This is used to implement assembler directives such as .word, .quad , | |||
/// etc. | /// etc. | |||
/// | /// | |||
/// @param Value - The value to emit. | /// @param Value - The value to emit. | |||
/// @param Size - The size of the integer (in bytes) to emit. This must | /// @param Size - The size of the integer (in bytes) to emit. This must | |||
/// match a native machine width. | /// match a native machine width. | |||
skipping to change at line 383 | skipping to change at line 444 | |||
/// .long foo | /// .long foo | |||
void EmitAbsValue(const MCExpr *Value, unsigned Size, | void EmitAbsValue(const MCExpr *Value, unsigned Size, | |||
unsigned AddrSpace = 0); | unsigned AddrSpace = 0); | |||
virtual void EmitULEB128Value(const MCExpr *Value) = 0; | virtual void EmitULEB128Value(const MCExpr *Value) = 0; | |||
virtual void EmitSLEB128Value(const MCExpr *Value) = 0; | virtual void EmitSLEB128Value(const MCExpr *Value) = 0; | |||
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the | /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the | |||
/// client having to pass in a MCExpr for constant integers. | /// client having to pass in a MCExpr for constant integers. | |||
void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0, | void EmitULEB128IntValue(uint64_t Value, unsigned Padding = 0, | |||
unsigned Padding = 0); | unsigned AddrSpace = 0); | |||
/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the | /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the | |||
/// client having to pass in a MCExpr for constant integers. | /// client having to pass in a MCExpr for constant integers. | |||
void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0); | void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0); | |||
/// EmitSymbolValue - Special case of EmitValue that avoids the client | /// EmitSymbolValue - Special case of EmitValue that avoids the client | |||
/// having to pass in a MCExpr for MCSymbols. | /// having to pass in a MCExpr for MCSymbols. | |||
void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, | void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, | |||
unsigned AddrSpace = 0); | unsigned AddrSpace = 0); | |||
skipping to change at line 412 | skipping to change at line 473 | |||
/// EmitGPRel32Value - Emit the expression @p Value into the output as a | /// EmitGPRel32Value - Emit the expression @p Value into the output as a | |||
/// gprel32 (32-bit GP relative) value. | /// gprel32 (32-bit GP relative) value. | |||
/// | /// | |||
/// This is used to implement assembler directives such as .gprel32 on | /// This is used to implement assembler directives such as .gprel32 on | |||
/// targets that support them. | /// targets that support them. | |||
virtual void EmitGPRel32Value(const MCExpr *Value); | virtual void EmitGPRel32Value(const MCExpr *Value); | |||
/// EmitFill - Emit NumBytes bytes worth of the value specified by | /// EmitFill - Emit NumBytes bytes worth of the value specified by | |||
/// FillValue. This implements directives such as '.space'. | /// FillValue. This implements directives such as '.space'. | |||
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, | virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, | |||
unsigned AddrSpace); | unsigned AddrSpace = 0); | |||
/// EmitZeros - Emit NumBytes worth of zeros. This is a convenience | /// EmitZeros - Emit NumBytes worth of zeros. This is a convenience | |||
/// function that just wraps EmitFill. | /// function that just wraps EmitFill. | |||
void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) { | void EmitZeros(uint64_t NumBytes, unsigned AddrSpace = 0) { | |||
EmitFill(NumBytes, 0, AddrSpace); | EmitFill(NumBytes, 0, AddrSpace); | |||
} | } | |||
/// EmitValueToAlignment - Emit some number of copies of @p Value until | /// EmitValueToAlignment - Emit some number of copies of @p Value until | |||
/// the byte alignment @p ByteAlignment is reached. | /// the byte alignment @p ByteAlignment is reached. | |||
/// | /// | |||
/// If the number of bytes need to emit for the alignment is not a mult iple | /// If the number of bytes need to emit for the alignment is not a mult iple | |||
/// of @p ValueSize, then the contents of the emitted fill bytes is | /// of @p ValueSize, then the contents of the emitted fill bytes is | |||
/// undefined. | /// undefined. | |||
/// | /// | |||
skipping to change at line 477 | skipping to change at line 538 | |||
/// @} | /// @} | |||
/// EmitFileDirective - Switch to a new logical file. This is used to | /// EmitFileDirective - Switch to a new logical file. This is used to | |||
/// implement the '.file "foo.c"' assembler directive. | /// implement the '.file "foo.c"' assembler directive. | |||
virtual void EmitFileDirective(StringRef Filename) = 0; | virtual void EmitFileDirective(StringRef Filename) = 0; | |||
/// EmitDwarfFileDirective - Associate a filename with a specified logi cal | /// EmitDwarfFileDirective - Associate a filename with a specified logi cal | |||
/// file number. This implements the DWARF2 '.file 4 "foo.c"' assemble r | /// file number. This implements the DWARF2 '.file 4 "foo.c"' assemble r | |||
/// directive. | /// directive. | |||
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Director y, | virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Director y, | |||
StringRef Filename); | StringRef Filename, unsigned CUID = 0); | |||
/// EmitDwarfLocDirective - This implements the DWARF2 | /// EmitDwarfLocDirective - This implements the DWARF2 | |||
// '.loc fileno lineno ...' assembler directive. | // '.loc fileno lineno ...' assembler directive. | |||
virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, | virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, | |||
unsigned Column, unsigned Flags, | unsigned Column, unsigned Flags, | |||
unsigned Isa, | unsigned Isa, | |||
unsigned Discriminator, | unsigned Discriminator, | |||
StringRef FileName); | StringRef FileName); | |||
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, | virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, | |||
skipping to change at line 517 | skipping to change at line 578 | |||
virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) ; | virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) ; | |||
virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); | virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); | |||
virtual void EmitCFIRememberState(); | virtual void EmitCFIRememberState(); | |||
virtual void EmitCFIRestoreState(); | virtual void EmitCFIRestoreState(); | |||
virtual void EmitCFISameValue(int64_t Register); | virtual void EmitCFISameValue(int64_t Register); | |||
virtual void EmitCFIRestore(int64_t Register); | virtual void EmitCFIRestore(int64_t Register); | |||
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); | virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); | |||
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); | virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); | |||
virtual void EmitCFIEscape(StringRef Values); | virtual void EmitCFIEscape(StringRef Values); | |||
virtual void EmitCFISignalFrame(); | virtual void EmitCFISignalFrame(); | |||
virtual void EmitCFIUndefined(int64_t Register); | ||||
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2); | ||||
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); | virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); | |||
virtual void EmitWin64EHEndProc(); | virtual void EmitWin64EHEndProc(); | |||
virtual void EmitWin64EHStartChained(); | virtual void EmitWin64EHStartChained(); | |||
virtual void EmitWin64EHEndChained(); | virtual void EmitWin64EHEndChained(); | |||
virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, | virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, | |||
bool Except); | bool Except); | |||
virtual void EmitWin64EHHandlerData(); | virtual void EmitWin64EHHandlerData(); | |||
virtual void EmitWin64EHPushReg(unsigned Register); | virtual void EmitWin64EHPushReg(unsigned Register); | |||
virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset); | virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset); | |||
virtual void EmitWin64EHAllocStack(unsigned Size); | virtual void EmitWin64EHAllocStack(unsigned Size); | |||
virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset); | virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset); | |||
virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset); | virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset); | |||
virtual void EmitWin64EHPushFrame(bool Code); | virtual void EmitWin64EHPushFrame(bool Code); | |||
virtual void EmitWin64EHEndProlog(); | virtual void EmitWin64EHEndProlog(); | |||
/// EmitInstruction - Emit the given @p Instruction into the current | /// EmitInstruction - Emit the given @p Instruction into the current | |||
/// section. | /// section. | |||
virtual void EmitInstruction(const MCInst &Inst) = 0; | virtual void EmitInstruction(const MCInst &Inst) = 0; | |||
/// \brief Set the bundle alignment mode from now on in the section. | ||||
/// The argument is the power of 2 to which the alignment is set. The | ||||
/// value 0 means turn the bundle alignment off. | ||||
virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0; | ||||
/// \brief The following instructions are a bundle-locked group. | ||||
/// | ||||
/// \param AlignToEnd - If true, the bundle-locked group will be aligne | ||||
d to | ||||
/// the end of a bundle. | ||||
virtual void EmitBundleLock(bool AlignToEnd) = 0; | ||||
/// \brief Ends a bundle-locked group. | ||||
virtual void EmitBundleUnlock() = 0; | ||||
/// EmitRawText - If this file is backed by a assembly streamer, this d umps | /// EmitRawText - If this file is backed by a assembly streamer, this d umps | |||
/// the specified string in the output .s file. This capability is | /// the specified string in the output .s file. This capability is | |||
/// indicated by the hasRawTextSupport() predicate. By default this ab orts. | /// indicated by the hasRawTextSupport() predicate. By default this ab orts. | |||
virtual void EmitRawText(StringRef String); | virtual void EmitRawText(StringRef String); | |||
void EmitRawText(const Twine &String); | void EmitRawText(const Twine &String); | |||
/// ARM-related methods. | /// ARM-related methods. | |||
/// FIXME: Eventually we should have some "target MC streamer" and move | /// FIXME: Eventually we should have some "target MC streamer" and move | |||
/// these methods there. | /// these methods there. | |||
virtual void EmitFnStart(); | virtual void EmitFnStart(); | |||
End of changes. 32 change blocks. | ||||
29 lines changed or deleted | 110 lines changed or added | |||
MCSubtargetInfo.h | MCSubtargetInfo.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file describes the subtarget options of a Target machine. | // This file describes the subtarget options of a Target machine. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCSUBTARGET_H | #ifndef LLVM_MC_MCSUBTARGET_H | |||
#define LLVM_MC_MCSUBTARGET_H | #define LLVM_MC_MCSUBTARGET_H | |||
#include "llvm/MC/SubtargetFeature.h" | ||||
#include "llvm/MC/MCInstrItineraries.h" | #include "llvm/MC/MCInstrItineraries.h" | |||
#include "llvm/MC/SubtargetFeature.h" | ||||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class StringRef; | class StringRef; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// | /// | |||
/// MCSubtargetInfo - Generic base class for all target subtargets. | /// MCSubtargetInfo - Generic base class for all target subtargets. | |||
/// | /// | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
MCTargetAsmParser.h | MCTargetAsmParser.h | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
namespace llvm { | namespace llvm { | |||
class MCStreamer; | class MCStreamer; | |||
class StringRef; | class StringRef; | |||
class SMLoc; | class SMLoc; | |||
class AsmToken; | class AsmToken; | |||
class MCParsedAsmOperand; | class MCParsedAsmOperand; | |||
class MCInst; | class MCInst; | |||
template <typename T> class SmallVectorImpl; | template <typename T> class SmallVectorImpl; | |||
enum AsmRewriteKind { | enum AsmRewriteKind { | |||
AOK_Delete = 0, // Rewrite should be ignored. | ||||
AOK_Align, // Rewrite align as .align. | ||||
AOK_DotOperator, // Rewrite a dot operator expression as an immediate. | AOK_DotOperator, // Rewrite a dot operator expression as an immediate. | |||
// E.g., [eax].foo.bar -> [eax].8 | // E.g., [eax].foo.bar -> [eax].8 | |||
AOK_Emit, // Rewrite _emit as .byte. | AOK_Emit, // Rewrite _emit as .byte. | |||
AOK_Imm, // Rewrite as $$N. | AOK_Imm, // Rewrite as $$N. | |||
AOK_ImmPrefix, // Add $$ before a parsed Imm. | AOK_ImmPrefix, // Add $$ before a parsed Imm. | |||
AOK_Input, // Rewrite in terms of $N. | AOK_Input, // Rewrite in terms of $N. | |||
AOK_Output, // Rewrite in terms of $N. | AOK_Output, // Rewrite in terms of $N. | |||
AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr). | AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr). | |||
AOK_Skip // Skip emission (e.g., offset/type operators). | AOK_Skip // Skip emission (e.g., offset/type operators). | |||
}; | }; | |||
const char AsmRewritePrecedence [] = { | ||||
0, // AOK_Delete | ||||
1, // AOK_Align | ||||
1, // AOK_DotOperator | ||||
1, // AOK_Emit | ||||
3, // AOK_Imm | ||||
3, // AOK_ImmPrefix | ||||
2, // AOK_Input | ||||
2, // AOK_Output | ||||
4, // AOK_SizeDirective | ||||
1 // AOK_Skip | ||||
}; | ||||
struct AsmRewrite { | struct AsmRewrite { | |||
AsmRewriteKind Kind; | AsmRewriteKind Kind; | |||
SMLoc Loc; | SMLoc Loc; | |||
unsigned Len; | unsigned Len; | |||
unsigned Val; | unsigned Val; | |||
public: | public: | |||
AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0) | AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0) | |||
: Kind(kind), Loc(loc), Len(len), Val(val) {} | : Kind(kind), Loc(loc), Len(len), Val(val) {} | |||
}; | }; | |||
skipping to change at line 145 | skipping to change at line 160 | |||
/// This returns false on success and returns true on failure to match. | /// This returns false on success and returns true on failure to match. | |||
/// | /// | |||
/// On failure, the target parser is responsible for emitting a diagnosti c | /// On failure, the target parser is responsible for emitting a diagnosti c | |||
/// explaining the match failure. | /// explaining the match failure. | |||
virtual bool | virtual bool | |||
MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, | MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, | |||
SmallVectorImpl<MCParsedAsmOperand*> &Operands, | SmallVectorImpl<MCParsedAsmOperand*> &Operands, | |||
MCStreamer &Out, unsigned &ErrorInfo, | MCStreamer &Out, unsigned &ErrorInfo, | |||
bool MatchingInlineAsm) = 0; | bool MatchingInlineAsm) = 0; | |||
/// Allow a target to add special case operand matching for things that | ||||
/// tblgen doesn't/can't handle effectively. For example, literal | ||||
/// immediates on ARM. TableGen expects a token operand, but the parser | ||||
/// will recognize them as immediates. | ||||
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, | ||||
unsigned Kind) { | ||||
return Match_InvalidOperand; | ||||
} | ||||
/// checkTargetMatchPredicate - Validate the instruction match against | /// checkTargetMatchPredicate - Validate the instruction match against | |||
/// any complex target predicates not expressible via match classes. | /// any complex target predicates not expressible via match classes. | |||
virtual unsigned checkTargetMatchPredicate(MCInst &Inst) { | virtual unsigned checkTargetMatchPredicate(MCInst &Inst) { | |||
return Match_Success; | return Match_Success; | |||
} | } | |||
virtual void convertToMapAndConstraints(unsigned Kind, | virtual void convertToMapAndConstraints(unsigned Kind, | |||
const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; | const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; | |||
}; | }; | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 24 lines changed or added | |||
MCValue.h | MCValue.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the declaration of the MCValue class. | // This file contains the declaration of the MCValue class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCVALUE_H | #ifndef LLVM_MC_MCVALUE_H | |||
#define LLVM_MC_MCVALUE_H | #define LLVM_MC_MCVALUE_H | |||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/MC/MCSymbol.h" | #include "llvm/MC/MCSymbol.h" | |||
#include "llvm/Support/DataTypes.h" | ||||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
class MCAsmInfo; | class MCAsmInfo; | |||
class MCSymbol; | class MCSymbol; | |||
class MCSymbolRefExpr; | class MCSymbolRefExpr; | |||
class raw_ostream; | class raw_ostream; | |||
/// MCValue - This represents an "assembler immediate". In its most genera l | /// MCValue - This represents an "assembler immediate". In its most genera l | |||
/// form, this can hold "SymbolA - SymbolB + imm64". Not all targets suppo rts | /// form, this can hold "SymbolA - SymbolB + imm64". Not all targets suppo rts | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
MCWinCOFFObjectWriter.h | MCWinCOFFObjectWriter.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MCWINCOFFOBJECTWRITER_H | #ifndef LLVM_MC_MCWINCOFFOBJECTWRITER_H | |||
#define LLVM_MC_MCWINCOFFOBJECTWRITER_H | #define LLVM_MC_MCWINCOFFOBJECTWRITER_H | |||
namespace llvm { | namespace llvm { | |||
class MCFixup; | ||||
class MCObjectWriter; | ||||
class MCValue; | ||||
class raw_ostream; | ||||
class MCWinCOFFObjectTargetWriter { | class MCWinCOFFObjectTargetWriter { | |||
const unsigned Machine; | const unsigned Machine; | |||
protected: | protected: | |||
MCWinCOFFObjectTargetWriter(unsigned Machine_); | MCWinCOFFObjectTargetWriter(unsigned Machine_); | |||
public: | public: | |||
virtual ~MCWinCOFFObjectTargetWriter() {} | virtual ~MCWinCOFFObjectTargetWriter() {} | |||
unsigned getMachine() const { return Machine; } | unsigned getMachine() const { return Machine; } | |||
virtual unsigned getRelocType(unsigned FixupKind) const = 0; | virtual unsigned getRelocType(const MCValue &Target, | |||
const MCFixup &Fixup, | ||||
bool IsCrossSection) const = 0; | ||||
}; | }; | |||
/// \brief Construct a new Win COFF writer instance. | /// \brief Construct a new Win COFF writer instance. | |||
/// | /// | |||
/// \param MOTW - The target specific WinCOFF writer subclass. | /// \param MOTW - The target specific WinCOFF writer subclass. | |||
/// \param OS - The stream to write to. | /// \param OS - The stream to write to. | |||
/// \returns The constructed object writer. | /// \returns The constructed object writer. | |||
MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MO TW, | MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MO TW, | |||
raw_ostream &OS); | raw_ostream &OS); | |||
} // End llvm namespace | } // End llvm namespace | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 8 lines changed or added | |||
MDBuilder.h | MDBuilder.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the MDBuilder class, which is used as a convenient way to | // This file defines the MDBuilder class, which is used as a convenient way to | |||
// create LLVM metadata with a consistent and simplified interface. | // create LLVM metadata with a consistent and simplified interface. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MDBUILDER_H | #ifndef LLVM_IR_MDBUILDER_H | |||
#define LLVM_MDBUILDER_H | #define LLVM_IR_MDBUILDER_H | |||
#include "llvm/Constants.h" | #include "llvm/IR/Constants.h" | |||
#include "llvm/DerivedTypes.h" | #include "llvm/IR/DerivedTypes.h" | |||
#include "llvm/LLVMContext.h" | #include "llvm/IR/Metadata.h" | |||
#include "llvm/Metadata.h" | ||||
#include "llvm/ADT/APInt.h" | ||||
namespace llvm { | namespace llvm { | |||
class MDBuilder { | class APInt; | |||
LLVMContext &Context; | class LLVMContext; | |||
public: | class MDBuilder { | |||
MDBuilder(LLVMContext &context) : Context(context) {} | LLVMContext &Context; | |||
/// \brief Return the given string as metadata. | public: | |||
MDString *createString(StringRef Str) { | MDBuilder(LLVMContext &context) : Context(context) {} | |||
return MDString::get(Context, Str); | ||||
} | ||||
//===------------------------------------------------------------------ | ||||
===// | ||||
// FPMath metadata. | ||||
//===------------------------------------------------------------------ | ||||
===// | ||||
/// \brief Return metadata with the given settings. The special value | ||||
0.0 | ||||
/// for the Accuracy parameter indicates the default (maximal precision | ||||
) | ||||
/// setting. | ||||
MDNode *createFPMath(float Accuracy) { | ||||
if (Accuracy == 0.0) | ||||
return 0; | ||||
assert(Accuracy > 0.0 && "Invalid fpmath accuracy!"); | ||||
Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy); | ||||
return MDNode::get(Context, Op); | ||||
} | ||||
//===------------------------------------------------------------------ | ||||
===// | ||||
// Prof metadata. | ||||
//===------------------------------------------------------------------ | ||||
===// | ||||
/// \brief Return metadata containing two branch weights. | ||||
MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight) | ||||
{ | ||||
uint32_t Weights[] = { TrueWeight, FalseWeight }; | ||||
return createBranchWeights(Weights); | ||||
} | ||||
/// \brief Return metadata containing a number of branch weights. | ||||
MDNode *createBranchWeights(ArrayRef<uint32_t> Weights) { | ||||
assert(Weights.size() >= 2 && "Need at least two branch weights!"); | ||||
SmallVector<Value *, 4> Vals(Weights.size()+1); | ||||
Vals[0] = createString("branch_weights"); | ||||
Type *Int32Ty = Type::getInt32Ty(Context); | ||||
for (unsigned i = 0, e = Weights.size(); i != e; ++i) | ||||
Vals[i+1] = ConstantInt::get(Int32Ty, Weights[i]); | ||||
return MDNode::get(Context, Vals); | ||||
} | ||||
//===------------------------------------------------------------------ | ||||
===// | ||||
// Range metadata. | ||||
//===------------------------------------------------------------------ | ||||
===// | ||||
/// \brief Return metadata describing the range [Lo, Hi). | ||||
MDNode *createRange(const APInt &Lo, const APInt &Hi) { | ||||
assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths! | ||||
"); | ||||
// If the range is everything then it is useless. | ||||
if (Hi == Lo) | ||||
return 0; | ||||
// Return the range [Lo, Hi). | ||||
Type *Ty = IntegerType::get(Context, Lo.getBitWidth()); | ||||
Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi | ||||
) }; | ||||
return MDNode::get(Context, Range); | ||||
} | ||||
//===------------------------------------------------------------------ | ||||
===// | ||||
// TBAA metadata. | ||||
//===------------------------------------------------------------------ | ||||
===// | ||||
/// \brief Return metadata appropriate for a TBAA root node. Each retu | ||||
rned | ||||
/// node is distinct from all other metadata and will never be identifi | ||||
ed | ||||
/// (uniqued) with anything else. | ||||
MDNode *createAnonymousTBAARoot() { | ||||
// To ensure uniqueness the root node is self-referential. | ||||
MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>()); | ||||
MDNode *Root = MDNode::get(Context, Dummy); | ||||
// At this point we have | ||||
// !0 = metadata !{} <- dummy | ||||
// !1 = metadata !{metadata !0} <- root | ||||
// Replace the dummy operand with the root node itself and delete the | ||||
dummy. | ||||
Root->replaceOperandWith(0, Root); | ||||
MDNode::deleteTemporary(Dummy); | ||||
// We now have | ||||
// !1 = metadata !{metadata !1} <- self-referential root | ||||
return Root; | ||||
} | ||||
/// \brief Return metadata appropriate for a TBAA root node with the gi | ||||
ven | ||||
/// name. This may be identified (uniqued) with other roots with the s | ||||
ame | ||||
/// name. | ||||
MDNode *createTBAARoot(StringRef Name) { | ||||
return MDNode::get(Context, createString(Name)); | ||||
} | ||||
/// \brief Return metadata for a non-root TBAA node with the given name | /// \brief Return the given string as metadata. | |||
, | MDString *createString(StringRef Str) { | |||
/// parent in the TBAA tree, and value for 'pointsToConstantMemory'. | return MDString::get(Context, Str); | |||
MDNode *createTBAANode(StringRef Name, MDNode *Parent, | } | |||
bool isConstant = false) { | ||||
if (isConstant) { | //===------------------------------------------------------------------== | |||
Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1); | =// | |||
Value *Ops[3] = { createString(Name), Parent, Flags }; | // FPMath metadata. | |||
return MDNode::get(Context, Ops); | //===------------------------------------------------------------------== | |||
} else { | =// | |||
Value *Ops[2] = { createString(Name), Parent }; | ||||
return MDNode::get(Context, Ops); | /// \brief Return metadata with the given settings. The special value 0. | |||
} | 0 | |||
} | /// for the Accuracy parameter indicates the default (maximal precision) | |||
/// setting. | ||||
MDNode *createFPMath(float Accuracy) { | ||||
if (Accuracy == 0.0) | ||||
return 0; | ||||
assert(Accuracy > 0.0 && "Invalid fpmath accuracy!"); | ||||
Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy); | ||||
return MDNode::get(Context, Op); | ||||
} | ||||
//===------------------------------------------------------------------== | ||||
=// | ||||
// Prof metadata. | ||||
//===------------------------------------------------------------------== | ||||
=// | ||||
/// \brief Return metadata containing two branch weights. | ||||
MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight) { | ||||
uint32_t Weights[] = { TrueWeight, FalseWeight }; | ||||
return createBranchWeights(Weights); | ||||
} | ||||
/// \brief Return metadata containing a number of branch weights. | ||||
MDNode *createBranchWeights(ArrayRef<uint32_t> Weights) { | ||||
assert(Weights.size() >= 2 && "Need at least two branch weights!"); | ||||
SmallVector<Value *, 4> Vals(Weights.size()+1); | ||||
Vals[0] = createString("branch_weights"); | ||||
Type *Int32Ty = Type::getInt32Ty(Context); | ||||
for (unsigned i = 0, e = Weights.size(); i != e; ++i) | ||||
Vals[i+1] = ConstantInt::get(Int32Ty, Weights[i]); | ||||
return MDNode::get(Context, Vals); | ||||
} | ||||
//===------------------------------------------------------------------== | ||||
=// | ||||
// Range metadata. | ||||
//===------------------------------------------------------------------== | ||||
=// | ||||
/// \brief Return metadata describing the range [Lo, Hi). | ||||
MDNode *createRange(const APInt &Lo, const APInt &Hi) { | ||||
assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!") | ||||
; | ||||
// If the range is everything then it is useless. | ||||
if (Hi == Lo) | ||||
return 0; | ||||
// Return the range [Lo, Hi). | ||||
Type *Ty = IntegerType::get(Context, Lo.getBitWidth()); | ||||
Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) | ||||
}; | ||||
return MDNode::get(Context, Range); | ||||
} | ||||
//===------------------------------------------------------------------== | ||||
=// | ||||
// TBAA metadata. | ||||
//===------------------------------------------------------------------== | ||||
=// | ||||
/// \brief Return metadata appropriate for a TBAA root node. Each return | ||||
ed | ||||
/// node is distinct from all other metadata and will never be identified | ||||
/// (uniqued) with anything else. | ||||
MDNode *createAnonymousTBAARoot() { | ||||
// To ensure uniqueness the root node is self-referential. | ||||
MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>()); | ||||
MDNode *Root = MDNode::get(Context, Dummy); | ||||
// At this point we have | ||||
// !0 = metadata !{} <- dummy | ||||
// !1 = metadata !{metadata !0} <- root | ||||
// Replace the dummy operand with the root node itself and delete the d | ||||
ummy. | ||||
Root->replaceOperandWith(0, Root); | ||||
MDNode::deleteTemporary(Dummy); | ||||
// We now have | ||||
// !1 = metadata !{metadata !1} <- self-referential root | ||||
return Root; | ||||
} | ||||
/// \brief Return metadata appropriate for a TBAA root node with the give | ||||
n | ||||
/// name. This may be identified (uniqued) with other roots with the sam | ||||
e | ||||
/// name. | ||||
MDNode *createTBAARoot(StringRef Name) { | ||||
return MDNode::get(Context, createString(Name)); | ||||
} | ||||
/// \brief Return metadata for a non-root TBAA node with the given name, | ||||
/// parent in the TBAA tree, and value for 'pointsToConstantMemory'. | ||||
MDNode *createTBAANode(StringRef Name, MDNode *Parent, | ||||
bool isConstant = false) { | ||||
if (isConstant) { | ||||
Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1); | ||||
Value *Ops[3] = { createString(Name), Parent, Flags }; | ||||
return MDNode::get(Context, Ops); | ||||
} else { | ||||
Value *Ops[2] = { createString(Name), Parent }; | ||||
return MDNode::get(Context, Ops); | ||||
} | ||||
} | ||||
struct TBAAStructField { | ||||
uint64_t Offset; | ||||
uint64_t Size; | ||||
MDNode *TBAA; | ||||
TBAAStructField(uint64_t Offset, uint64_t Size, MDNode *TBAA) : | ||||
Offset(Offset), Size(Size), TBAA(TBAA) {} | ||||
}; | ||||
struct TBAAStructField { | /// \brief Return metadata for a tbaa.struct node with the given | |||
uint64_t Offset; | /// struct field descriptions. | |||
uint64_t Size; | MDNode *createTBAAStructNode(ArrayRef<TBAAStructField> Fields) { | |||
MDNode *TBAA; | SmallVector<Value *, 4> Vals(Fields.size() * 3); | |||
TBAAStructField(uint64_t Offset, uint64_t Size, MDNode *TBAA) : | Type *Int64 = IntegerType::get(Context, 64); | |||
Offset(Offset), Size(Size), TBAA(TBAA) {} | for (unsigned i = 0, e = Fields.size(); i != e; ++i) { | |||
}; | Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset); | |||
Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size); | ||||
/// \brief Return metadata for a tbaa.struct node with the given | Vals[i * 3 + 2] = Fields[i].TBAA; | |||
/// struct field descriptions. | } | |||
MDNode *createTBAAStructNode(ArrayRef<TBAAStructField> Fields) { | return MDNode::get(Context, Vals); | |||
SmallVector<Value *, 4> Vals(Fields.size() * 3); | } | |||
Type *Int64 = IntegerType::get(Context, 64); | ||||
for (unsigned i = 0, e = Fields.size(); i != e; ++i) { | /// \brief Return metadata for a TBAA struct node in the type DAG | |||
Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset); | /// with the given name, a list of pairs (offset, field type in the type | |||
Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size); | DAG). | |||
Vals[i * 3 + 2] = Fields[i].TBAA; | MDNode *createTBAAStructTypeNode(StringRef Name, | |||
} | ArrayRef<std::pair<MDNode*, uint64_t> > Fields) { | |||
return MDNode::get(Context, Vals); | SmallVector<Value *, 4> Ops(Fields.size() * 2 + 1); | |||
} | Type *Int64 = IntegerType::get(Context, 64); | |||
Ops[0] = createString(Name); | ||||
for (unsigned i = 0, e = Fields.size(); i != e; ++i) { | ||||
Ops[i * 2 + 1] = Fields[i].first; | ||||
Ops[i * 2 + 2] = ConstantInt::get(Int64, Fields[i].second); | ||||
} | ||||
return MDNode::get(Context, Ops); | ||||
} | ||||
/// \brief Return metadata for a TBAA scalar type node with the | ||||
/// given name, an offset and a parent in the TBAA type DAG. | ||||
MDNode *createTBAAScalarTypeNode(StringRef Name, MDNode *Parent, | ||||
uint64_t Offset = 0) { | ||||
SmallVector<Value *, 4> Ops(3); | ||||
Type *Int64 = IntegerType::get(Context, 64); | ||||
Ops[0] = createString(Name); | ||||
Ops[1] = Parent; | ||||
Ops[2] = ConstantInt::get(Int64, Offset); | ||||
return MDNode::get(Context, Ops); | ||||
} | ||||
/// \brief Return metadata for a TBAA tag node with the given | ||||
/// base type, access type and offset relative to the base type. | ||||
MDNode *createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType, | ||||
uint64_t Offset) { | ||||
Type *Int64 = IntegerType::get(Context, 64); | ||||
Value *Ops[3] = { BaseType, AccessType, ConstantInt::get(Int64, Offset) | ||||
}; | ||||
return MDNode::get(Context, Ops); | ||||
} | ||||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 8 change blocks. | ||||
153 lines changed or deleted | 187 lines changed or added | |||
MachO.h | MachO.h | |||
---|---|---|---|---|
//===- MachO.h - MachO object file implementation ---------------*- C++ -*- ===// | //===- MachO.h - MachO object file implementation ---------------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the MachOObjectFile class, which binds the MachOObjec | // This file declares the MachOObjectFile class, which implement the Object | |||
t | File | |||
// class to the generic ObjectFile wrapper. | // interface for MachO files. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_OBJECT_MACHO_H | #ifndef LLVM_OBJECT_MACHO_H | |||
#define LLVM_OBJECT_MACHO_H | #define LLVM_OBJECT_MACHO_H | |||
#include "llvm/ADT/ArrayRef.h" | ||||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/Object/MachOFormat.h" | ||||
#include "llvm/Object/ObjectFile.h" | #include "llvm/Object/ObjectFile.h" | |||
#include "llvm/Object/MachOObject.h" | ||||
#include "llvm/Support/MachO.h" | #include "llvm/Support/MachO.h" | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
namespace llvm { | namespace llvm { | |||
namespace object { | namespace object { | |||
typedef MachOObject::LoadCommandInfo LoadCommandInfo; | ||||
class MachOObjectFile : public ObjectFile { | class MachOObjectFile : public ObjectFile { | |||
public: | public: | |||
MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, error_code &ec); | struct LoadCommandInfo { | |||
const char *Ptr; // Where in memory the load command is. | ||||
macho::LoadCommand C; // The command itself. | ||||
}; | ||||
virtual symbol_iterator begin_symbols() const; | MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits, | |||
virtual symbol_iterator end_symbols() const; | error_code &ec); | |||
virtual symbol_iterator begin_dynamic_symbols() const; | ||||
virtual symbol_iterator end_dynamic_symbols() const; | ||||
virtual library_iterator begin_libraries_needed() const; | ||||
virtual library_iterator end_libraries_needed() const; | ||||
virtual section_iterator begin_sections() const; | ||||
virtual section_iterator end_sections() const; | ||||
virtual uint8_t getBytesInAddress() const; | ||||
virtual StringRef getFileFormatName() const; | ||||
virtual unsigned getArch() const; | ||||
virtual StringRef getLoadName() const; | ||||
MachOObject *getObject() { return MachOObj; } | ||||
static inline bool classof(const Binary *v) { | ||||
return v->isMachO(); | ||||
} | ||||
protected: | ||||
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; | virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; | |||
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; | virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; | |||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) c onst; | ||||
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) cons t; | virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) cons t; | |||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) c | ||||
onst; | ||||
virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) co | ||||
nst; | ||||
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; | virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; | |||
virtual error_code getSymbolType(DataRefImpl Symb, | ||||
SymbolRef::Type &Res) const; | ||||
virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const ; | virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const ; | |||
virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; | virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; | |||
virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; | ||||
virtual error_code getSymbolSection(DataRefImpl Symb, | virtual error_code getSymbolSection(DataRefImpl Symb, | |||
section_iterator &Res) const; | section_iterator &Res) const; | |||
virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; | virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; | |||
virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const ; | virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const ; | |||
virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; | virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; | |||
virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) cons t; | virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) cons t; | |||
virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; | virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; | |||
virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) co nst; | virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) co nst; | |||
virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) co nst; | virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) co nst; | |||
virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; | virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; | |||
virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; | virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; | |||
virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; | virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; | |||
virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, | virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, | |||
bool &Res) const; | bool &Res) const; | |||
virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; | virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; | |||
virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; | virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; | |||
virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) cons t; | virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) cons t; | |||
virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S, | virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Sym b, | |||
bool &Result) const; | bool &Result) const; | |||
virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; | virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; | |||
virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; | virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; | |||
virtual error_code getRelocationNext(DataRefImpl Rel, | virtual error_code getRelocationNext(DataRefImpl Rel, | |||
RelocationRef &Res) const; | RelocationRef &Res) const; | |||
virtual error_code getRelocationAddress(DataRefImpl Rel, | virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) c | |||
uint64_t &Res) const; | onst; | |||
virtual error_code getRelocationOffset(DataRefImpl Rel, | virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) co | |||
uint64_t &Res) const; | nst; | |||
virtual error_code getRelocationSymbol(DataRefImpl Rel, | virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) c | |||
SymbolRef &Res) const; | onst; | |||
virtual error_code getRelocationType(DataRefImpl Rel, | virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) cons | |||
uint64_t &Res) const; | t; | |||
virtual error_code getRelocationTypeName(DataRefImpl Rel, | virtual error_code getRelocationTypeName(DataRefImpl Rel, | |||
SmallVectorImpl<char> &Result) c onst; | SmallVectorImpl<char> &Result) c onst; | |||
virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, | virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, | |||
int64_t &Res) const; | int64_t &Res) const; | |||
virtual error_code getRelocationValueString(DataRefImpl Rel, | virtual error_code getRelocationValueString(DataRefImpl Rel, | |||
SmallVectorImpl<char> &Result) c onst; | SmallVectorImpl<char> &Result) c onst; | |||
virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) con st; | virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) con st; | |||
virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) c onst; | virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) c onst; | |||
virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) co nst; | virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) co nst; | |||
private: | // TODO: Would be useful to have an iterator based version | |||
MachOObject *MachOObj; | // of the load command interface too. | |||
mutable uint32_t RegisteredStringTable; | ||||
typedef SmallVector<DataRefImpl, 1> SectionList; | ||||
SectionList Sections; | ||||
void moveToNextSection(DataRefImpl &DRI) const; | virtual symbol_iterator begin_symbols() const; | |||
void getSymbolTableEntry(DataRefImpl DRI, | virtual symbol_iterator end_symbols() const; | |||
InMemoryStruct<macho::SymbolTableEntry> &Res) co | ||||
nst; | virtual symbol_iterator begin_dynamic_symbols() const; | |||
void getSymbol64TableEntry(DataRefImpl DRI, | virtual symbol_iterator end_dynamic_symbols() const; | |||
InMemoryStruct<macho::Symbol64TableEntry> &Res) c | ||||
onst; | virtual section_iterator begin_sections() const; | |||
void moveToNextSymbol(DataRefImpl &DRI) const; | virtual section_iterator end_sections() const; | |||
void getSection(DataRefImpl DRI, InMemoryStruct<macho::Section> &Res) con | ||||
st; | virtual library_iterator begin_libraries_needed() const; | |||
void getSection64(DataRefImpl DRI, | virtual library_iterator end_libraries_needed() const; | |||
InMemoryStruct<macho::Section64> &Res) const; | ||||
void getRelocation(DataRefImpl Rel, | virtual uint8_t getBytesInAddress() const; | |||
InMemoryStruct<macho::RelocationEntry> &Res) const; | ||||
std::size_t getSectionIndex(DataRefImpl Sec) const; | ||||
void printRelocationTargetName(InMemoryStruct<macho::RelocationEntry>& RE | virtual StringRef getFileFormatName() const; | |||
, | virtual unsigned getArch() const; | |||
raw_string_ostream &fmt) const; | ||||
virtual StringRef getLoadName() const; | ||||
relocation_iterator getSectionRelBegin(unsigned Index) const; | ||||
relocation_iterator getSectionRelEnd(unsigned Index) const; | ||||
// In a MachO file, sections have a segment name. This is used in the .o | ||||
// files. They have a single segment, but this field specifies which segm | ||||
ent | ||||
// a section should be put in in the final object. | ||||
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const; | ||||
// Names are stored as 16 bytes. These returns the raw 16 bytes without | ||||
// interpreting them as a C string. | ||||
ArrayRef<char> getSectionRawName(DataRefImpl Sec) const; | ||||
ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const; | ||||
// MachO specific Info about relocations. | ||||
bool isRelocationScattered(const macho::RelocationEntry &RE) const; | ||||
unsigned getPlainRelocationSymbolNum(const macho::RelocationEntry &RE) co | ||||
nst; | ||||
bool getPlainRelocationExternal(const macho::RelocationEntry &RE) const; | ||||
bool getScatteredRelocationScattered(const macho::RelocationEntry &RE) co | ||||
nst; | ||||
uint32_t getScatteredRelocationValue(const macho::RelocationEntry &RE) co | ||||
nst; | ||||
unsigned getAnyRelocationAddress(const macho::RelocationEntry &RE) const; | ||||
unsigned getAnyRelocationPCRel(const macho::RelocationEntry &RE) const; | ||||
unsigned getAnyRelocationLength(const macho::RelocationEntry &RE) const; | ||||
unsigned getAnyRelocationType(const macho::RelocationEntry &RE) const; | ||||
SectionRef getRelocationSection(const macho::RelocationEntry &RE) const; | ||||
// Walk load commands. | ||||
LoadCommandInfo getFirstLoadCommandInfo() const; | ||||
LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const; | ||||
// MachO specific structures. | ||||
macho::Section getSection(DataRefImpl DRI) const; | ||||
macho::Section64 getSection64(DataRefImpl DRI) const; | ||||
macho::Section getSection(const LoadCommandInfo &L, unsigned Index) const | ||||
; | ||||
macho::Section64 getSection64(const LoadCommandInfo &L, unsigned Index) c | ||||
onst; | ||||
macho::SymbolTableEntry getSymbolTableEntry(DataRefImpl DRI) const; | ||||
macho::Symbol64TableEntry getSymbol64TableEntry(DataRefImpl DRI) const; | ||||
macho::LinkeditDataLoadCommand | ||||
getLinkeditDataLoadCommand(const LoadCommandInfo &L) const; | ||||
macho::SegmentLoadCommand | ||||
getSegmentLoadCommand(const LoadCommandInfo &L) const; | ||||
macho::Segment64LoadCommand | ||||
getSegment64LoadCommand(const LoadCommandInfo &L) const; | ||||
macho::LinkerOptionsLoadCommand | ||||
getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const; | ||||
macho::RelocationEntry getRelocation(DataRefImpl Rel) const; | ||||
macho::Header getHeader() const; | ||||
macho::Header64Ext getHeader64Ext() const; | ||||
macho::IndirectSymbolTableEntry | ||||
getIndirectSymbolTableEntry(const macho::DysymtabLoadCommand &DLC, | ||||
unsigned Index) const; | ||||
macho::DataInCodeTableEntry getDataInCodeTableEntry(uint32_t DataOffset, | ||||
unsigned Index) const | ||||
; | ||||
macho::SymtabLoadCommand getSymtabLoadCommand() const; | ||||
macho::DysymtabLoadCommand getDysymtabLoadCommand() const; | ||||
StringRef getStringTableData() const; | ||||
bool is64Bit() const; | ||||
void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const; | ||||
static bool classof(const Binary *v) { | ||||
return v->isMachO(); | ||||
} | ||||
private: | ||||
typedef SmallVector<const char*, 1> SectionList; | ||||
SectionList Sections; | ||||
const char *SymtabLoadCmd; | ||||
const char *DysymtabLoadCmd; | ||||
}; | }; | |||
} | } | |||
} | } | |||
#endif | #endif | |||
End of changes. 17 change blocks. | ||||
62 lines changed or deleted | 124 lines changed or added | |||
MachOFormat.h | MachOFormat.h | |||
---|---|---|---|---|
skipping to change at line 67 | skipping to change at line 67 | |||
/// \brief ARM Machine Subtypes. | /// \brief ARM Machine Subtypes. | |||
enum CPUSubtypeARM { | enum CPUSubtypeARM { | |||
CSARM_ALL = 0, | CSARM_ALL = 0, | |||
CSARM_V4T = 5, | CSARM_V4T = 5, | |||
CSARM_V6 = 6, | CSARM_V6 = 6, | |||
CSARM_V5TEJ = 7, | CSARM_V5TEJ = 7, | |||
CSARM_XSCALE = 8, | CSARM_XSCALE = 8, | |||
CSARM_V7 = 9, | CSARM_V7 = 9, | |||
CSARM_V7F = 10, | CSARM_V7F = 10, | |||
CSARM_V7S = 11, | CSARM_V7S = 11, | |||
CSARM_V7K = 12 | CSARM_V7K = 12, | |||
CSARM_V6M = 14, | ||||
CSARM_V7M = 15, | ||||
CSARM_V7EM = 16 | ||||
}; | }; | |||
/// \brief PowerPC Machine Subtypes. | /// \brief PowerPC Machine Subtypes. | |||
enum CPUSubtypePowerPC { | enum CPUSubtypePowerPC { | |||
CSPPC_ALL = 0 | CSPPC_ALL = 0 | |||
}; | }; | |||
/// \brief SPARC Machine Subtypes. | /// \brief SPARC Machine Subtypes. | |||
enum CPUSubtypeSPARC { | enum CPUSubtypeSPARC { | |||
CSSPARC_ALL = 0 | CSSPARC_ALL = 0 | |||
skipping to change at line 148 | skipping to change at line 151 | |||
enum LoadCommandType { | enum LoadCommandType { | |||
LCT_Segment = 0x1, | LCT_Segment = 0x1, | |||
LCT_Symtab = 0x2, | LCT_Symtab = 0x2, | |||
LCT_Dysymtab = 0xb, | LCT_Dysymtab = 0xb, | |||
LCT_Segment64 = 0x19, | LCT_Segment64 = 0x19, | |||
LCT_UUID = 0x1b, | LCT_UUID = 0x1b, | |||
LCT_CodeSignature = 0x1d, | LCT_CodeSignature = 0x1d, | |||
LCT_SegmentSplitInfo = 0x1e, | LCT_SegmentSplitInfo = 0x1e, | |||
LCT_FunctionStarts = 0x26, | LCT_FunctionStarts = 0x26, | |||
LCT_DataInCode = 0x29 | LCT_DataInCode = 0x29, | |||
LCT_LinkerOptions = 0x2D | ||||
}; | }; | |||
/// \brief Load command structure. | /// \brief Load command structure. | |||
struct LoadCommand { | struct LoadCommand { | |||
uint32_t Type; | uint32_t Type; | |||
uint32_t Size; | uint32_t Size; | |||
}; | }; | |||
/// @name Load Command Structures | /// @name Load Command Structures | |||
/// @{ | /// @{ | |||
skipping to change at line 236 | skipping to change at line 240 | |||
uint32_t NumLocalRelocationTableEntries; | uint32_t NumLocalRelocationTableEntries; | |||
}; | }; | |||
struct LinkeditDataLoadCommand { | struct LinkeditDataLoadCommand { | |||
uint32_t Type; | uint32_t Type; | |||
uint32_t Size; | uint32_t Size; | |||
uint32_t DataOffset; | uint32_t DataOffset; | |||
uint32_t DataSize; | uint32_t DataSize; | |||
}; | }; | |||
struct LinkerOptionsLoadCommand { | ||||
uint32_t Type; | ||||
uint32_t Size; | ||||
uint32_t Count; | ||||
// Load command is followed by Count number of zero-terminated UTF8 str | ||||
ings, | ||||
// and then zero-filled to be 4-byte aligned. | ||||
}; | ||||
/// @} | /// @} | |||
/// @name Section Data | /// @name Section Data | |||
/// @{ | /// @{ | |||
enum SectionFlags { | ||||
SF_PureInstructions = 0x80000000 | ||||
}; | ||||
struct Section { | struct Section { | |||
char Name[16]; | char Name[16]; | |||
char SegmentName[16]; | char SegmentName[16]; | |||
uint32_t Address; | uint32_t Address; | |||
uint32_t Size; | uint32_t Size; | |||
uint32_t Offset; | uint32_t Offset; | |||
uint32_t Align; | uint32_t Align; | |||
uint32_t RelocationTableOffset; | uint32_t RelocationTableOffset; | |||
uint32_t NumRelocationTableEntries; | uint32_t NumRelocationTableEntries; | |||
uint32_t Flags; | uint32_t Flags; | |||
End of changes. 4 change blocks. | ||||
2 lines changed or deleted | 19 lines changed or added | |||
MachORelocation.h | MachORelocation.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the MachORelocation class. | // This file defines the MachORelocation class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHO_RELOCATION_H | #ifndef LLVM_CODEGEN_MACHORELOCATION_H | |||
#define LLVM_CODEGEN_MACHO_RELOCATION_H | #define LLVM_CODEGEN_MACHORELOCATION_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
/// MachORelocation - This struct contains information about each relocat ion | /// MachORelocation - This struct contains information about each relocat ion | |||
/// that needs to be emitted to the file. | /// that needs to be emitted to the file. | |||
/// see <mach-o/reloc.h> | /// see <mach-o/reloc.h> | |||
class MachORelocation { | class MachORelocation { | |||
uint32_t r_address; // offset in the section to what is being reloca ted | uint32_t r_address; // offset in the section to what is being reloca ted | |||
skipping to change at line 55 | skipping to change at line 55 | |||
MachORelocation(uint32_t addr, uint32_t index, bool pcrel, uint8_t len, | MachORelocation(uint32_t addr, uint32_t index, bool pcrel, uint8_t len, | |||
bool ext, uint8_t type, bool scattered = false, | bool ext, uint8_t type, bool scattered = false, | |||
int32_t value = 0) : | int32_t value = 0) : | |||
r_address(addr), r_symbolnum(index), r_pcrel(pcrel), r_length(len), | r_address(addr), r_symbolnum(index), r_pcrel(pcrel), r_length(len), | |||
r_extern(ext), r_type(type), r_scattered(scattered), r_value(value) { } | r_extern(ext), r_type(type), r_scattered(scattered), r_value(value) { } | |||
}; | }; | |||
} // end llvm namespace | } // end llvm namespace | |||
#endif // LLVM_CODEGEN_MACHO_RELOCATION_H | #endif // LLVM_CODEGEN_MACHORELOCATION_H | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
MachineBasicBlock.h | MachineBasicBlock.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// Collect the sequence of machine instructions for a basic block. | // Collect the sequence of machine instructions for a basic block. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H | #ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H | |||
#define LLVM_CODEGEN_MACHINEBASICBLOCK_H | #define LLVM_CODEGEN_MACHINEBASICBLOCK_H | |||
#include "llvm/CodeGen/MachineInstr.h" | ||||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/CodeGen/MachineInstr.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <functional> | #include <functional> | |||
namespace llvm { | namespace llvm { | |||
class Pass; | class Pass; | |||
class BasicBlock; | class BasicBlock; | |||
class MachineFunction; | class MachineFunction; | |||
class MCSymbol; | class MCSymbol; | |||
class SlotIndexes; | class SlotIndexes; | |||
skipping to change at line 98 | skipping to change at line 98 | |||
unsigned Alignment; | unsigned Alignment; | |||
/// IsLandingPad - Indicate that this basic block is entered via an | /// IsLandingPad - Indicate that this basic block is entered via an | |||
/// exception handler. | /// exception handler. | |||
bool IsLandingPad; | bool IsLandingPad; | |||
/// AddressTaken - Indicate that this basic block is potentially the | /// AddressTaken - Indicate that this basic block is potentially the | |||
/// target of an indirect branch. | /// target of an indirect branch. | |||
bool AddressTaken; | bool AddressTaken; | |||
/// \brief since getSymbol is a relatively heavy-weight operation, the sy | ||||
mbol | ||||
/// is only computed once and is cached. | ||||
mutable MCSymbol *CachedMCSymbol; | ||||
// Intrusive list support | // Intrusive list support | |||
MachineBasicBlock() {} | MachineBasicBlock() {} | |||
explicit MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb); | explicit MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb); | |||
~MachineBasicBlock(); | ~MachineBasicBlock(); | |||
// MachineBasicBlocks are allocated and owned by MachineFunction. | // MachineBasicBlocks are allocated and owned by MachineFunction. | |||
friend class MachineFunction; | friend class MachineFunction; | |||
skipping to change at line 147 | skipping to change at line 151 | |||
/// MIs that are inside bundles (i.e. walk top level MIs only). | /// MIs that are inside bundles (i.e. walk top level MIs only). | |||
template<typename Ty, typename IterTy> | template<typename Ty, typename IterTy> | |||
class bundle_iterator | class bundle_iterator | |||
: public std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> { | : public std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> { | |||
IterTy MII; | IterTy MII; | |||
public: | public: | |||
bundle_iterator(IterTy mii) : MII(mii) {} | bundle_iterator(IterTy mii) : MII(mii) {} | |||
bundle_iterator(Ty &mi) : MII(mi) { | bundle_iterator(Ty &mi) : MII(mi) { | |||
assert(!mi.isInsideBundle() && | assert(!mi.isBundledWithPred() && | |||
"It's not legal to initialize bundle_iterator with a bundled M I"); | "It's not legal to initialize bundle_iterator with a bundled M I"); | |||
} | } | |||
bundle_iterator(Ty *mi) : MII(mi) { | bundle_iterator(Ty *mi) : MII(mi) { | |||
assert((!mi || !mi->isInsideBundle()) && | assert((!mi || !mi->isBundledWithPred()) && | |||
"It's not legal to initialize bundle_iterator with a bundled M I"); | "It's not legal to initialize bundle_iterator with a bundled M I"); | |||
} | } | |||
// Template allows conversion from const to nonconst. | // Template allows conversion from const to nonconst. | |||
template<class OtherTy, class OtherIterTy> | template<class OtherTy, class OtherIterTy> | |||
bundle_iterator(const bundle_iterator<OtherTy, OtherIterTy> &I) | bundle_iterator(const bundle_iterator<OtherTy, OtherIterTy> &I) | |||
: MII(I.getInstrIterator()) {} | : MII(I.getInstrIterator()) {} | |||
bundle_iterator() : MII(0) {} | bundle_iterator() : MII(0) {} | |||
Ty &operator*() const { return *MII; } | Ty &operator*() const { return *MII; } | |||
Ty *operator->() const { return &operator*(); } | Ty *operator->() const { return &operator*(); } | |||
skipping to change at line 175 | skipping to change at line 179 | |||
bool operator==(const bundle_iterator &x) const { | bool operator==(const bundle_iterator &x) const { | |||
return MII == x.MII; | return MII == x.MII; | |||
} | } | |||
bool operator!=(const bundle_iterator &x) const { | bool operator!=(const bundle_iterator &x) const { | |||
return !operator==(x); | return !operator==(x); | |||
} | } | |||
// Increment and decrement operators... | // Increment and decrement operators... | |||
bundle_iterator &operator--() { // predecrement - Back up | bundle_iterator &operator--() { // predecrement - Back up | |||
do --MII; | do --MII; | |||
while (MII->isInsideBundle()); | while (MII->isBundledWithPred()); | |||
return *this; | return *this; | |||
} | } | |||
bundle_iterator &operator++() { // preincrement - Advance | bundle_iterator &operator++() { // preincrement - Advance | |||
IterTy E = MII->getParent()->instr_end(); | while (MII->isBundledWithSucc()) | |||
do ++MII; | ++MII; | |||
while (MII != E && MII->isInsideBundle()); | ++MII; | |||
return *this; | return *this; | |||
} | } | |||
bundle_iterator operator--(int) { // postdecrement operators... | bundle_iterator operator--(int) { // postdecrement operators... | |||
bundle_iterator tmp = *this; | bundle_iterator tmp = *this; | |||
--*this; | --*this; | |||
return tmp; | return tmp; | |||
} | } | |||
bundle_iterator operator++(int) { // postincrement operators... | bundle_iterator operator++(int) { // postincrement operators... | |||
bundle_iterator tmp = *this; | bundle_iterator tmp = *this; | |||
++*this; | ++*this; | |||
skipping to change at line 439 | skipping to change at line 443 | |||
/// if splitting is not possible. | /// if splitting is not possible. | |||
/// | /// | |||
/// This function updates LiveVariables, MachineDominatorTree, and | /// This function updates LiveVariables, MachineDominatorTree, and | |||
/// MachineLoopInfo, as applicable. | /// MachineLoopInfo, as applicable. | |||
MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P); | MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P); | |||
void pop_front() { Insts.pop_front(); } | void pop_front() { Insts.pop_front(); } | |||
void pop_back() { Insts.pop_back(); } | void pop_back() { Insts.pop_back(); } | |||
void push_back(MachineInstr *MI) { Insts.push_back(MI); } | void push_back(MachineInstr *MI) { Insts.push_back(MI); } | |||
template<typename IT> | /// Insert MI into the instruction list before I, possibly inside a bundl | |||
void insert(instr_iterator I, IT S, IT E) { | e. | |||
Insts.insert(I, S, E); | /// | |||
} | /// If the insertion point is inside a bundle, MI will be added to the bu | |||
instr_iterator insert(instr_iterator I, MachineInstr *M) { | ndle, | |||
return Insts.insert(I, M); | /// otherwise MI will not be added to any bundle. That means this functio | |||
} | n | |||
instr_iterator insertAfter(instr_iterator I, MachineInstr *M) { | /// alone can't be used to prepend or append instructions to bundles. See | |||
return Insts.insertAfter(I, M); | /// MIBundleBuilder::insert() for a more reliable way of doing that. | |||
} | instr_iterator insert(instr_iterator I, MachineInstr *M); | |||
/// Insert a range of instructions into the instruction list before I. | ||||
template<typename IT> | template<typename IT> | |||
void insert(iterator I, IT S, IT E) { | void insert(iterator I, IT S, IT E) { | |||
Insts.insert(I.getInstrIterator(), S, E); | Insts.insert(I.getInstrIterator(), S, E); | |||
} | } | |||
iterator insert(iterator I, MachineInstr *M) { | ||||
return Insts.insert(I.getInstrIterator(), M); | /// Insert MI into the instruction list before I. | |||
iterator insert(iterator I, MachineInstr *MI) { | ||||
assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() && | ||||
"Cannot insert instruction with bundle flags"); | ||||
return Insts.insert(I.getInstrIterator(), MI); | ||||
} | } | |||
iterator insertAfter(iterator I, MachineInstr *M) { | ||||
return Insts.insertAfter(I.getInstrIterator(), M); | /// Insert MI into the instruction list after I. | |||
iterator insertAfter(iterator I, MachineInstr *MI) { | ||||
assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() && | ||||
"Cannot insert instruction with bundle flags"); | ||||
return Insts.insertAfter(I.getInstrIterator(), MI); | ||||
} | } | |||
/// erase - Remove the specified element or range from the instruction li | /// Remove an instruction from the instruction list and delete it. | |||
st. | ||||
/// These functions delete any instructions removed. | ||||
/// | /// | |||
instr_iterator erase(instr_iterator I) { | /// If the instruction is part of a bundle, the other instructions in the | |||
return Insts.erase(I); | /// bundle will still be bundled after removing the single instruction. | |||
} | instr_iterator erase(instr_iterator I); | |||
instr_iterator erase(instr_iterator I, instr_iterator E) { | ||||
return Insts.erase(I, E); | /// Remove an instruction from the instruction list and delete it. | |||
} | /// | |||
/// If the instruction is part of a bundle, the other instructions in the | ||||
/// bundle will still be bundled after removing the single instruction. | ||||
instr_iterator erase_instr(MachineInstr *I) { | instr_iterator erase_instr(MachineInstr *I) { | |||
instr_iterator MII(I); | return erase(instr_iterator(I)); | |||
return erase(MII); | ||||
} | } | |||
iterator erase(iterator I); | /// Remove a range of instructions from the instruction list and delete t hem. | |||
iterator erase(iterator I, iterator E) { | iterator erase(iterator I, iterator E) { | |||
return Insts.erase(I.getInstrIterator(), E.getInstrIterator()); | return Insts.erase(I.getInstrIterator(), E.getInstrIterator()); | |||
} | } | |||
/// Remove an instruction or bundle from the instruction list and delete | ||||
it. | ||||
/// | ||||
/// If I points to a bundle of instructions, they are all erased. | ||||
iterator erase(iterator I) { | ||||
return erase(I, llvm::next(I)); | ||||
} | ||||
/// Remove an instruction from the instruction list and delete it. | ||||
/// | ||||
/// If I is the head of a bundle of instructions, the whole bundle will b | ||||
e | ||||
/// erased. | ||||
iterator erase(MachineInstr *I) { | iterator erase(MachineInstr *I) { | |||
iterator MII(I); | return erase(iterator(I)); | |||
return erase(MII); | ||||
} | } | |||
/// remove - Remove the instruction from the instruction list. This funct | /// Remove the unbundled instruction from the instruction list without | |||
ion | /// deleting it. | |||
/// does not delete the instruction. WARNING: Note, if the specified | /// | |||
/// instruction is a bundle this function will remove all the bundled | /// This function can not be used to remove bundled instructions, use | |||
/// instructions as well. It is up to the caller to keep a list of the | /// remove_instr to remove individual instructions from a bundle. | |||
/// bundled instructions and re-insert them if desired. This function is | MachineInstr *remove(MachineInstr *I) { | |||
/// *not recommended* for manipulating instructions with bundles. Use | assert(!I->isBundled() && "Cannot remove bundled instructions"); | |||
/// splice instead. | return Insts.remove(I); | |||
MachineInstr *remove(MachineInstr *I); | } | |||
/// Remove the possibly bundled instruction from the instruction list | ||||
/// without deleting it. | ||||
/// | ||||
/// If the instruction is part of a bundle, the other instructions in the | ||||
/// bundle will still be bundled after removing the single instruction. | ||||
MachineInstr *remove_instr(MachineInstr *I); | ||||
void clear() { | void clear() { | |||
Insts.clear(); | Insts.clear(); | |||
} | } | |||
/// splice - Take an instruction from MBB 'Other' at the position From, | /// Take an instruction from MBB 'Other' at the position From, and insert | |||
/// and insert it into this MBB right before 'where'. | it | |||
void splice(instr_iterator where, MachineBasicBlock *Other, | /// into this MBB right before 'Where'. | |||
instr_iterator From) { | /// | |||
Insts.splice(where, Other->Insts, From); | /// If From points to a bundle of instructions, the whole bundle is moved | |||
} | . | |||
void splice(iterator where, MachineBasicBlock *Other, iterator From); | void splice(iterator Where, MachineBasicBlock *Other, iterator From) { | |||
// The range splice() doesn't allow noop moves, but this one does. | ||||
/// splice - Take a block of instructions from MBB 'Other' in the range [ | if (Where != From) | |||
From, | splice(Where, Other, From, llvm::next(From)); | |||
/// To), and insert them into this MBB right before 'where'. | } | |||
void splice(instr_iterator where, MachineBasicBlock *Other, instr_iterato | ||||
r From, | /// Take a block of instructions from MBB 'Other' in the range [From, To) | |||
instr_iterator To) { | , | |||
Insts.splice(where, Other->Insts, From, To); | /// and insert them into this MBB right before 'Where'. | |||
} | /// | |||
void splice(iterator where, MachineBasicBlock *Other, iterator From, | /// The instruction at 'Where' must not be included in the range of | |||
iterator To) { | /// instructions to move. | |||
Insts.splice(where.getInstrIterator(), Other->Insts, | void splice(iterator Where, MachineBasicBlock *Other, | |||
iterator From, iterator To) { | ||||
Insts.splice(Where.getInstrIterator(), Other->Insts, | ||||
From.getInstrIterator(), To.getInstrIterator()); | From.getInstrIterator(), To.getInstrIterator()); | |||
} | } | |||
/// removeFromParent - This method unlinks 'this' from the containing | /// removeFromParent - This method unlinks 'this' from the containing | |||
/// function, and returns it, but does not delete it. | /// function, and returns it, but does not delete it. | |||
MachineBasicBlock *removeFromParent(); | MachineBasicBlock *removeFromParent(); | |||
/// eraseFromParent - This method unlinks 'this' from the containing | /// eraseFromParent - This method unlinks 'this' from the containing | |||
/// function and deletes it. | /// function and deletes it. | |||
void eraseFromParent(); | void eraseFromParent(); | |||
End of changes. 19 change blocks. | ||||
63 lines changed or deleted | 99 lines changed or added | |||
MachineBranchProbabilityInfo.h | MachineBranchProbabilityInfo.h | |||
---|---|---|---|---|
//==- MachineBranchProbabilityInfo.h - Machine Branch Probability Analysis -==// | //==- MachineBranchProbabilityInfo.h - Machine Branch Probability Analysis -==// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This pass is used to evaluate branch probabilties on machine basic block s. | // This pass is used to evaluate branch probabilties on machine basic block s. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H | #ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H | |||
#define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H | #define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/CodeGen/MachineBasicBlock.h" | #include "llvm/CodeGen/MachineBasicBlock.h" | |||
#include "llvm/Pass.h" | ||||
#include "llvm/Support/BranchProbability.h" | #include "llvm/Support/BranchProbability.h" | |||
#include <climits> | #include <climits> | |||
namespace llvm { | namespace llvm { | |||
class MachineBranchProbabilityInfo : public ImmutablePass { | class MachineBranchProbabilityInfo : public ImmutablePass { | |||
virtual void anchor(); | virtual void anchor(); | |||
// Default weight value. Used when we don't have information about the ed ge. | // Default weight value. Used when we don't have information about the ed ge. | |||
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of | // TODO: DEFAULT_WEIGHT makes sense during static predication, when none of | |||
End of changes. 3 change blocks. | ||||
2 lines changed or deleted | 1 lines changed or added | |||
MachineCodeEmitter.h | MachineCodeEmitter.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// be separated from concerns such as resolution of call targets, and where the | // be separated from concerns such as resolution of call targets, and where the | |||
// machine code will be written (memory or disk, f.e.). | // machine code will be written (memory or disk, f.e.). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H | #ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H | |||
#define LLVM_CODEGEN_MACHINECODEEMITTER_H | #define LLVM_CODEGEN_MACHINECODEEMITTER_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/DebugLoc.h" | #include "llvm/Support/DebugLoc.h" | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
class MachineConstantPool; | class MachineConstantPool; | |||
class MachineJumpTableInfo; | class MachineJumpTableInfo; | |||
class MachineFunction; | class MachineFunction; | |||
class MachineModuleInfo; | class MachineModuleInfo; | |||
class MachineRelocation; | class MachineRelocation; | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 0 lines changed or added | |||
MachineCodeInfo.h | MachineCodeInfo.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines MachineCodeInfo, a class used by the JIT ExecutionEngi ne | // This file defines MachineCodeInfo, a class used by the JIT ExecutionEngi ne | |||
// to report information about the generated machine code. | // to report information about the generated machine code. | |||
// | // | |||
// See JIT::runJITOnFunction for usage. | // See JIT::runJITOnFunction for usage. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef EE_MACHINE_CODE_INFO_H | #ifndef LLVM_CODEGEN_MACHINECODEINFO_H | |||
#define EE_MACHINE_CODE_INFO_H | #define LLVM_CODEGEN_MACHINECODEINFO_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
class MachineCodeInfo { | class MachineCodeInfo { | |||
private: | private: | |||
size_t Size; // Number of bytes in memory used | size_t Size; // Number of bytes in memory used | |||
void *Address; // The address of the function in memory | void *Address; // The address of the function in memory | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
MachineDominators.h | MachineDominators.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines classes mirroring those in llvm/Analysis/Dominators.h, | // This file defines classes mirroring those in llvm/Analysis/Dominators.h, | |||
// but for target-specific code rather than target-independent IR. | // but for target-specific code rather than target-independent IR. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H | #ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H | |||
#define LLVM_CODEGEN_MACHINEDOMINATORS_H | #define LLVM_CODEGEN_MACHINEDOMINATORS_H | |||
#include "llvm/Analysis/DominatorInternals.h" | ||||
#include "llvm/Analysis/Dominators.h" | ||||
#include "llvm/CodeGen/MachineBasicBlock.h" | #include "llvm/CodeGen/MachineBasicBlock.h" | |||
#include "llvm/CodeGen/MachineFunction.h" | #include "llvm/CodeGen/MachineFunction.h" | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | #include "llvm/CodeGen/MachineFunctionPass.h" | |||
#include "llvm/Analysis/Dominators.h" | ||||
#include "llvm/Analysis/DominatorInternals.h" | ||||
namespace llvm { | namespace llvm { | |||
template<> | template<> | |||
inline void DominatorTreeBase<MachineBasicBlock>::addRoot(MachineBasicBlock * MBB) { | inline void DominatorTreeBase<MachineBasicBlock>::addRoot(MachineBasicBlock * MBB) { | |||
this->Roots.push_back(MBB); | this->Roots.push_back(MBB); | |||
} | } | |||
EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>); | EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>); | |||
EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<MachineBasicBlock>); | EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<MachineBasicBlock>); | |||
skipping to change at line 71 | skipping to change at line 71 | |||
inline MachineBasicBlock *getRoot() const { | inline MachineBasicBlock *getRoot() const { | |||
return DT->getRoot(); | return DT->getRoot(); | |||
} | } | |||
inline MachineDomTreeNode *getRootNode() const { | inline MachineDomTreeNode *getRootNode() const { | |||
return DT->getRootNode(); | return DT->getRootNode(); | |||
} | } | |||
virtual bool runOnMachineFunction(MachineFunction &F); | virtual bool runOnMachineFunction(MachineFunction &F); | |||
inline bool dominates(MachineDomTreeNode* A, MachineDomTreeNode* B) const | inline bool dominates(const MachineDomTreeNode* A, | |||
{ | const MachineDomTreeNode* B) const { | |||
return DT->dominates(A, B); | return DT->dominates(A, B); | |||
} | } | |||
inline bool dominates(MachineBasicBlock* A, MachineBasicBlock* B) const { | inline bool dominates(const MachineBasicBlock* A, | |||
const MachineBasicBlock* B) const { | ||||
return DT->dominates(A, B); | return DT->dominates(A, B); | |||
} | } | |||
// dominates - Return true if A dominates B. This performs the | // dominates - Return true if A dominates B. This performs the | |||
// special checks necessary if A and B are in the same basic block. | // special checks necessary if A and B are in the same basic block. | |||
bool dominates(MachineInstr *A, MachineInstr *B) const { | bool dominates(const MachineInstr *A, const MachineInstr *B) const { | |||
MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent(); | const MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent(); | |||
if (BBA != BBB) return DT->dominates(BBA, BBB); | if (BBA != BBB) return DT->dominates(BBA, BBB); | |||
// Loop through the basic block until we find A or B. | // Loop through the basic block until we find A or B. | |||
MachineBasicBlock::iterator I = BBA->begin(); | MachineBasicBlock::const_iterator I = BBA->begin(); | |||
for (; &*I != A && &*I != B; ++I) | for (; &*I != A && &*I != B; ++I) | |||
/*empty*/ ; | /*empty*/ ; | |||
//if(!DT.IsPostDominators) { | //if(!DT.IsPostDominators) { | |||
// A dominates B if it is found first in the basic block. | // A dominates B if it is found first in the basic block. | |||
return &*I == A; | return &*I == A; | |||
//} else { | //} else { | |||
// // A post-dominates B if B is found first in the basic block. | // // A post-dominates B if B is found first in the basic block. | |||
// return &*I == B; | // return &*I == B; | |||
//} | //} | |||
} | } | |||
inline bool properlyDominates(const MachineDomTreeNode* A, | inline bool properlyDominates(const MachineDomTreeNode* A, | |||
MachineDomTreeNode* B) const { | const MachineDomTreeNode* B) const { | |||
return DT->properlyDominates(A, B); | return DT->properlyDominates(A, B); | |||
} | } | |||
inline bool properlyDominates(MachineBasicBlock* A, | inline bool properlyDominates(const MachineBasicBlock* A, | |||
MachineBasicBlock* B) const { | const MachineBasicBlock* B) const { | |||
return DT->properlyDominates(A, B); | return DT->properlyDominates(A, B); | |||
} | } | |||
/// findNearestCommonDominator - Find nearest common dominator basic bloc k | /// findNearestCommonDominator - Find nearest common dominator basic bloc k | |||
/// for basic block A and B. If there is no such block then return NULL. | /// for basic block A and B. If there is no such block then return NULL. | |||
inline MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A , | inline MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A , | |||
MachineBasicBlock *B ) { | MachineBasicBlock *B ) { | |||
return DT->findNearestCommonDominator(A, B); | return DT->findNearestCommonDominator(A, B); | |||
} | } | |||
skipping to change at line 163 | skipping to change at line 165 | |||
} | } | |||
/// splitBlock - BB is split and now it has one successor. Update dominat or | /// splitBlock - BB is split and now it has one successor. Update dominat or | |||
/// tree to reflect this change. | /// tree to reflect this change. | |||
inline void splitBlock(MachineBasicBlock* NewBB) { | inline void splitBlock(MachineBasicBlock* NewBB) { | |||
DT->splitBlock(NewBB); | DT->splitBlock(NewBB); | |||
} | } | |||
/// isReachableFromEntry - Return true if A is dominated by the entry | /// isReachableFromEntry - Return true if A is dominated by the entry | |||
/// block of the function containing it. | /// block of the function containing it. | |||
bool isReachableFromEntry(MachineBasicBlock *A) { | bool isReachableFromEntry(const MachineBasicBlock *A) { | |||
return DT->isReachableFromEntry(A); | return DT->isReachableFromEntry(A); | |||
} | } | |||
virtual void releaseMemory(); | virtual void releaseMemory(); | |||
virtual void print(raw_ostream &OS, const Module*) const; | virtual void print(raw_ostream &OS, const Module*) const; | |||
}; | }; | |||
//===------------------------------------- | //===------------------------------------- | |||
/// DominatorTree GraphTraits specialization so the DominatorTree can be | /// DominatorTree GraphTraits specialization so the DominatorTree can be | |||
End of changes. 9 change blocks. | ||||
12 lines changed or deleted | 13 lines changed or added | |||
MachineFrameInfo.h | MachineFrameInfo.h | |||
---|---|---|---|---|
skipping to change at line 224 | skipping to change at line 224 | |||
/// Required alignment of the local object blob, which is the strictest | /// Required alignment of the local object blob, which is the strictest | |||
/// alignment of any object in it. | /// alignment of any object in it. | |||
unsigned LocalFrameMaxAlign; | unsigned LocalFrameMaxAlign; | |||
/// Whether the local object blob needs to be allocated together. If not, | /// Whether the local object blob needs to be allocated together. If not, | |||
/// PEI should ignore the isPreAllocated flags on the stack objects and | /// PEI should ignore the isPreAllocated flags on the stack objects and | |||
/// just allocate them normally. | /// just allocate them normally. | |||
bool UseLocalStackAllocationBlock; | bool UseLocalStackAllocationBlock; | |||
/// Whether the "realign-stack" option is on. | ||||
bool RealignOption; | ||||
public: | public: | |||
explicit MachineFrameInfo(const TargetFrameLowering &tfi) : TFI(tfi) { | explicit MachineFrameInfo(const TargetFrameLowering &tfi, bool RealignO | |||
pt) | ||||
: TFI(tfi), RealignOption(RealignOpt) { | ||||
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0; | StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0; | |||
HasVarSizedObjects = false; | HasVarSizedObjects = false; | |||
FrameAddressTaken = false; | FrameAddressTaken = false; | |||
ReturnAddressTaken = false; | ReturnAddressTaken = false; | |||
AdjustsStack = false; | AdjustsStack = false; | |||
HasCalls = false; | HasCalls = false; | |||
StackProtectorIdx = -1; | StackProtectorIdx = -1; | |||
FunctionContextIdx = -1; | FunctionContextIdx = -1; | |||
MaxCallFrameSize = 0; | MaxCallFrameSize = 0; | |||
CSIValid = false; | CSIValid = false; | |||
skipping to change at line 419 | skipping to change at line 422 | |||
/// getStackSize - Return the number of bytes that must be allocated to h old | /// getStackSize - Return the number of bytes that must be allocated to h old | |||
/// all of the fixed size frame objects. This is only valid after | /// all of the fixed size frame objects. This is only valid after | |||
/// Prolog/Epilog code insertion has finalized the stack frame layout. | /// Prolog/Epilog code insertion has finalized the stack frame layout. | |||
/// | /// | |||
uint64_t getStackSize() const { return StackSize; } | uint64_t getStackSize() const { return StackSize; } | |||
/// setStackSize - Set the size of the stack... | /// setStackSize - Set the size of the stack... | |||
/// | /// | |||
void setStackSize(uint64_t Size) { StackSize = Size; } | void setStackSize(uint64_t Size) { StackSize = Size; } | |||
/// Estimate and return the size of the stack frame. | ||||
unsigned estimateStackSize(const MachineFunction &MF) const; | ||||
/// getOffsetAdjustment - Return the correction for frame offsets. | /// getOffsetAdjustment - Return the correction for frame offsets. | |||
/// | /// | |||
int getOffsetAdjustment() const { return OffsetAdjustment; } | int getOffsetAdjustment() const { return OffsetAdjustment; } | |||
/// setOffsetAdjustment - Set the correction for frame offsets. | /// setOffsetAdjustment - Set the correction for frame offsets. | |||
/// | /// | |||
void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; } | void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; } | |||
/// getMaxAlignment - Return the alignment in bytes that this function mu st be | /// getMaxAlignment - Return the alignment in bytes that this function mu st be | |||
/// aligned to, which is greater than the default stack alignment provide d by | /// aligned to, which is greater than the default stack alignment provide d by | |||
/// the target. | /// the target. | |||
/// | /// | |||
unsigned getMaxAlignment() const { return MaxAlignment; } | unsigned getMaxAlignment() const { return MaxAlignment; } | |||
/// ensureMaxAlignment - Make sure the function is at least Align bytes | /// ensureMaxAlignment - Make sure the function is at least Align bytes | |||
/// aligned. | /// aligned. | |||
void ensureMaxAlignment(unsigned Align) { | void ensureMaxAlignment(unsigned Align); | |||
if (MaxAlignment < Align) MaxAlignment = Align; | ||||
} | ||||
/// AdjustsStack - Return true if this function adjusts the stack -- e.g. , | /// AdjustsStack - Return true if this function adjusts the stack -- e.g. , | |||
/// when calling another function. This is only valid during and after | /// when calling another function. This is only valid during and after | |||
/// prolog/epilog code insertion. | /// prolog/epilog code insertion. | |||
bool adjustsStack() const { return AdjustsStack; } | bool adjustsStack() const { return AdjustsStack; } | |||
void setAdjustsStack(bool V) { AdjustsStack = V; } | void setAdjustsStack(bool V) { AdjustsStack = V; } | |||
/// hasCalls - Return true if the current function has any function calls . | /// hasCalls - Return true if the current function has any function calls . | |||
bool hasCalls() const { return HasCalls; } | bool hasCalls() const { return HasCalls; } | |||
void setHasCalls(bool V) { HasCalls = V; } | void setHasCalls(bool V) { HasCalls = V; } | |||
skipping to change at line 498 | skipping to change at line 502 | |||
bool isDeadObjectIndex(int ObjectIdx) const { | bool isDeadObjectIndex(int ObjectIdx) const { | |||
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && | assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && | |||
"Invalid Object Idx!"); | "Invalid Object Idx!"); | |||
return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL; | return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL; | |||
} | } | |||
/// CreateStackObject - Create a new statically sized stack object, retur ning | /// CreateStackObject - Create a new statically sized stack object, retur ning | |||
/// a nonnegative identifier to represent it. | /// a nonnegative identifier to represent it. | |||
/// | /// | |||
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, | int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, | |||
bool MayNeedSP = false, const AllocaInst *Alloca = | bool MayNeedSP = false, const AllocaInst *Alloca = | |||
0) { | 0); | |||
assert(Size != 0 && "Cannot allocate zero size stack objects!"); | ||||
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedS | ||||
P, | ||||
Alloca)); | ||||
int Index = (int)Objects.size() - NumFixedObjects - 1; | ||||
assert(Index >= 0 && "Bad frame index!"); | ||||
ensureMaxAlignment(Alignment); | ||||
return Index; | ||||
} | ||||
/// CreateSpillStackObject - Create a new statically sized stack object t hat | /// CreateSpillStackObject - Create a new statically sized stack object t hat | |||
/// represents a spill slot, returning a nonnegative identifier to repres ent | /// represents a spill slot, returning a nonnegative identifier to repres ent | |||
/// it. | /// it. | |||
/// | /// | |||
int CreateSpillStackObject(uint64_t Size, unsigned Alignment) { | int CreateSpillStackObject(uint64_t Size, unsigned Alignment); | |||
CreateStackObject(Size, Alignment, true, false); | ||||
int Index = (int)Objects.size() - NumFixedObjects - 1; | ||||
ensureMaxAlignment(Alignment); | ||||
return Index; | ||||
} | ||||
/// RemoveStackObject - Remove or mark dead a statically sized stack obje ct. | /// RemoveStackObject - Remove or mark dead a statically sized stack obje ct. | |||
/// | /// | |||
void RemoveStackObject(int ObjectIdx) { | void RemoveStackObject(int ObjectIdx) { | |||
// Mark it dead. | // Mark it dead. | |||
Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL; | Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL; | |||
} | } | |||
/// CreateVariableSizedObject - Notify the MachineFrameInfo object that a | /// CreateVariableSizedObject - Notify the MachineFrameInfo object that a | |||
/// variable sized object has been created. This must be created wheneve r a | /// variable sized object has been created. This must be created wheneve r a | |||
/// variable sized object is created, whether or not the index returned i s | /// variable sized object is created, whether or not the index returned i s | |||
/// actually used. | /// actually used. | |||
/// | /// | |||
int CreateVariableSizedObject(unsigned Alignment) { | int CreateVariableSizedObject(unsigned Alignment); | |||
HasVarSizedObjects = true; | ||||
Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0)); | ||||
ensureMaxAlignment(Alignment); | ||||
return (int)Objects.size()-NumFixedObjects-1; | ||||
} | ||||
/// getCalleeSavedInfo - Returns a reference to call saved info vector fo r the | /// getCalleeSavedInfo - Returns a reference to call saved info vector fo r the | |||
/// current function. | /// current function. | |||
const std::vector<CalleeSavedInfo> &getCalleeSavedInfo() const { | const std::vector<CalleeSavedInfo> &getCalleeSavedInfo() const { | |||
return CSInfo; | return CSInfo; | |||
} | } | |||
/// setCalleeSavedInfo - Used by prolog/epilog inserter to set the functi on's | /// setCalleeSavedInfo - Used by prolog/epilog inserter to set the functi on's | |||
/// callee saved information. | /// callee saved information. | |||
void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) { | void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) { | |||
End of changes. 7 change blocks. | ||||
27 lines changed or deleted | 13 lines changed or added | |||
MachineFunction.h | MachineFunction.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// MachineBasicBlock instances that make up the current compiled function. | // MachineBasicBlock instances that make up the current compiled function. | |||
// | // | |||
// This class also contains pointers to various classes which hold | // This class also contains pointers to various classes which hold | |||
// target-specific information about the generated code. | // target-specific information about the generated code. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINEFUNCTION_H | #ifndef LLVM_CODEGEN_MACHINEFUNCTION_H | |||
#define LLVM_CODEGEN_MACHINEFUNCTION_H | #define LLVM_CODEGEN_MACHINEFUNCTION_H | |||
#include "llvm/CodeGen/MachineBasicBlock.h" | ||||
#include "llvm/ADT/ilist.h" | #include "llvm/ADT/ilist.h" | |||
#include "llvm/Support/DebugLoc.h" | #include "llvm/CodeGen/MachineBasicBlock.h" | |||
#include "llvm/Support/Allocator.h" | #include "llvm/Support/Allocator.h" | |||
#include "llvm/Support/ArrayRecycler.h" | ||||
#include "llvm/Support/DebugLoc.h" | ||||
#include "llvm/Support/Recycler.h" | #include "llvm/Support/Recycler.h" | |||
namespace llvm { | namespace llvm { | |||
class Value; | class Value; | |||
class Function; | class Function; | |||
class GCModuleInfo; | class GCModuleInfo; | |||
class MachineRegisterInfo; | class MachineRegisterInfo; | |||
class MachineFrameInfo; | class MachineFrameInfo; | |||
class MachineConstantPool; | class MachineConstantPool; | |||
skipping to change at line 108 | skipping to change at line 109 | |||
// MachineBasicBlock is inserted into a MachineFunction is it automatical ly | // MachineBasicBlock is inserted into a MachineFunction is it automatical ly | |||
// numbered and this vector keeps track of the mapping from ID's to MBB's . | // numbered and this vector keeps track of the mapping from ID's to MBB's . | |||
std::vector<MachineBasicBlock*> MBBNumbering; | std::vector<MachineBasicBlock*> MBBNumbering; | |||
// Pool-allocate MachineFunction-lifetime and IR objects. | // Pool-allocate MachineFunction-lifetime and IR objects. | |||
BumpPtrAllocator Allocator; | BumpPtrAllocator Allocator; | |||
// Allocation management for instructions in function. | // Allocation management for instructions in function. | |||
Recycler<MachineInstr> InstructionRecycler; | Recycler<MachineInstr> InstructionRecycler; | |||
// Allocation management for operand arrays on instructions. | ||||
ArrayRecycler<MachineOperand> OperandRecycler; | ||||
// Allocation management for basic blocks in function. | // Allocation management for basic blocks in function. | |||
Recycler<MachineBasicBlock> BasicBlockRecycler; | Recycler<MachineBasicBlock> BasicBlockRecycler; | |||
// List of machine basic blocks in function | // List of machine basic blocks in function | |||
typedef ilist<MachineBasicBlock> BasicBlockListType; | typedef ilist<MachineBasicBlock> BasicBlockListType; | |||
BasicBlockListType BasicBlocks; | BasicBlockListType BasicBlocks; | |||
/// FunctionNumber - This provides a unique ID for each function emitted in | /// FunctionNumber - This provides a unique ID for each function emitted in | |||
/// this translation unit. | /// this translation unit. | |||
/// | /// | |||
skipping to change at line 130 | skipping to change at line 134 | |||
/// Alignment - The alignment of the function. | /// Alignment - The alignment of the function. | |||
unsigned Alignment; | unsigned Alignment; | |||
/// ExposesReturnsTwice - True if the function calls setjmp or related | /// ExposesReturnsTwice - True if the function calls setjmp or related | |||
/// functions with attribute "returns twice", but doesn't have | /// functions with attribute "returns twice", but doesn't have | |||
/// the attribute itself. | /// the attribute itself. | |||
/// This is used to limit optimizations which cannot reason | /// This is used to limit optimizations which cannot reason | |||
/// about the control flow of such functions. | /// about the control flow of such functions. | |||
bool ExposesReturnsTwice; | bool ExposesReturnsTwice; | |||
/// True if the function includes MS-style inline assembly. | ||||
bool HasMSInlineAsm; | ||||
MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION; | MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION; | |||
void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION; | void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
MachineFunction(const Function *Fn, const TargetMachine &TM, | MachineFunction(const Function *Fn, const TargetMachine &TM, | |||
unsigned FunctionNum, MachineModuleInfo &MMI, | unsigned FunctionNum, MachineModuleInfo &MMI, | |||
GCModuleInfo* GMI); | GCModuleInfo* GMI); | |||
~MachineFunction(); | ~MachineFunction(); | |||
MachineModuleInfo &getMMI() const { return MMI; } | MachineModuleInfo &getMMI() const { return MMI; } | |||
GCModuleInfo *getGMI() const { return GMI; } | GCModuleInfo *getGMI() const { return GMI; } | |||
skipping to change at line 213 | skipping to change at line 220 | |||
bool exposesReturnsTwice() const { | bool exposesReturnsTwice() const { | |||
return ExposesReturnsTwice; | return ExposesReturnsTwice; | |||
} | } | |||
/// setCallsSetJmp - Set a flag that indicates if there's a call to | /// setCallsSetJmp - Set a flag that indicates if there's a call to | |||
/// a "returns twice" function. | /// a "returns twice" function. | |||
void setExposesReturnsTwice(bool B) { | void setExposesReturnsTwice(bool B) { | |||
ExposesReturnsTwice = B; | ExposesReturnsTwice = B; | |||
} | } | |||
/// Returns true if the function contains any MS-style inline assembly. | ||||
bool hasMSInlineAsm() const { | ||||
return HasMSInlineAsm; | ||||
} | ||||
/// Set a flag that indicates that the function contains MS-style inline | ||||
/// assembly. | ||||
void setHasMSInlineAsm(bool B) { | ||||
HasMSInlineAsm = B; | ||||
} | ||||
/// getInfo - Keep track of various per-function pieces of information fo r | /// getInfo - Keep track of various per-function pieces of information fo r | |||
/// backends that would like to do so. | /// backends that would like to do so. | |||
/// | /// | |||
template<typename Ty> | template<typename Ty> | |||
Ty *getInfo() { | Ty *getInfo() { | |||
if (!MFInfo) { | if (!MFInfo) { | |||
// This should be just `new (Allocator.Allocate<Ty>()) Ty(*this)', but | // This should be just `new (Allocator.Allocate<Ty>()) Ty(*this)', but | |||
// that apparently breaks GCC 3.3. | // that apparently breaks GCC 3.3. | |||
Ty *Loc = static_cast<Ty*>(Allocator.Allocate(sizeof(Ty), | Ty *Loc = static_cast<Ty*>(Allocator.Allocate(sizeof(Ty), | |||
AlignOf<Ty>::Alignmen t)); | AlignOf<Ty>::Alignmen t)); | |||
skipping to change at line 336 | skipping to change at line 354 | |||
BasicBlocks.remove(MBBI); | BasicBlocks.remove(MBBI); | |||
} | } | |||
void erase(iterator MBBI) { | void erase(iterator MBBI) { | |||
BasicBlocks.erase(MBBI); | BasicBlocks.erase(MBBI); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Internal functions used to automatically number MachineBasicBlocks | // Internal functions used to automatically number MachineBasicBlocks | |||
// | // | |||
/// getNextMBBNumber - Returns the next unique number to be assigned | /// \brief Adds the MBB to the internal numbering. Returns the unique num | |||
/// to a MachineBasicBlock in this MachineFunction. | ber | |||
/// assigned to the MBB. | ||||
/// | /// | |||
unsigned addToMBBNumbering(MachineBasicBlock *MBB) { | unsigned addToMBBNumbering(MachineBasicBlock *MBB) { | |||
MBBNumbering.push_back(MBB); | MBBNumbering.push_back(MBB); | |||
return (unsigned)MBBNumbering.size()-1; | return (unsigned)MBBNumbering.size()-1; | |||
} | } | |||
/// removeFromMBBNumbering - Remove the specific machine basic block from our | /// removeFromMBBNumbering - Remove the specific machine basic block from our | |||
/// tracker, this is only really to be used by the MachineBasicBlock | /// tracker, this is only really to be used by the MachineBasicBlock | |||
/// implementation. | /// implementation. | |||
void removeFromMBBNumbering(unsigned N) { | void removeFromMBBNumbering(unsigned N) { | |||
skipping to change at line 396 | skipping to change at line 414 | |||
const MDNode *TBAAInfo = 0, | const MDNode *TBAAInfo = 0, | |||
const MDNode *Ranges = 0); | const MDNode *Ranges = 0); | |||
/// getMachineMemOperand - Allocate a new MachineMemOperand by copying | /// getMachineMemOperand - Allocate a new MachineMemOperand by copying | |||
/// an existing one, adjusting by an offset and using the given size. | /// an existing one, adjusting by an offset and using the given size. | |||
/// MachineMemOperands are owned by the MachineFunction and need not be | /// MachineMemOperands are owned by the MachineFunction and need not be | |||
/// explicitly deallocated. | /// explicitly deallocated. | |||
MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO, | MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO, | |||
int64_t Offset, uint64_t Size); | int64_t Offset, uint64_t Size); | |||
typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity; | ||||
/// Allocate an array of MachineOperands. This is only intended for use b | ||||
y | ||||
/// internal MachineInstr functions. | ||||
MachineOperand *allocateOperandArray(OperandCapacity Cap) { | ||||
return OperandRecycler.allocate(Cap, Allocator); | ||||
} | ||||
/// Dellocate an array of MachineOperands and recycle the memory. This is | ||||
/// only intended for use by internal MachineInstr functions. | ||||
/// Cap must be the same capacity that was used to allocate the array. | ||||
void deallocateOperandArray(OperandCapacity Cap, MachineOperand *Array) { | ||||
OperandRecycler.deallocate(Cap, Array); | ||||
} | ||||
/// allocateMemRefsArray - Allocate an array to hold MachineMemOperand | /// allocateMemRefsArray - Allocate an array to hold MachineMemOperand | |||
/// pointers. This array is owned by the MachineFunction. | /// pointers. This array is owned by the MachineFunction. | |||
MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num); | MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num); | |||
/// extractLoadMemRefs - Allocate an array and populate it with just the | /// extractLoadMemRefs - Allocate an array and populate it with just the | |||
/// load information from the given MachineMemOperand sequence. | /// load information from the given MachineMemOperand sequence. | |||
std::pair<MachineInstr::mmo_iterator, | std::pair<MachineInstr::mmo_iterator, | |||
MachineInstr::mmo_iterator> | MachineInstr::mmo_iterator> | |||
extractLoadMemRefs(MachineInstr::mmo_iterator Begin, | extractLoadMemRefs(MachineInstr::mmo_iterator Begin, | |||
MachineInstr::mmo_iterator End); | MachineInstr::mmo_iterator End); | |||
End of changes. 8 change blocks. | ||||
4 lines changed or deleted | 39 lines changed or added | |||
MachineFunctionAnalysis.h | MachineFunctionAnalysis.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the MachineFunctionAnalysis class. | // This file declares the MachineFunctionAnalysis class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_ANALYSIS_H | #ifndef LLVM_CODEGEN_MACHINEFUNCTIONANALYSIS_H | |||
#define LLVM_CODEGEN_MACHINE_FUNCTION_ANALYSIS_H | #define LLVM_CODEGEN_MACHINEFUNCTIONANALYSIS_H | |||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
#include "llvm/Target/TargetMachine.h" | ||||
namespace llvm { | namespace llvm { | |||
class MachineFunction; | class MachineFunction; | |||
class TargetMachine; | ||||
/// MachineFunctionAnalysis - This class is a Pass that manages a | /// MachineFunctionAnalysis - This class is a Pass that manages a | |||
/// MachineFunction object. | /// MachineFunction object. | |||
struct MachineFunctionAnalysis : public FunctionPass { | struct MachineFunctionAnalysis : public FunctionPass { | |||
private: | private: | |||
const TargetMachine &TM; | const TargetMachine &TM; | |||
MachineFunction *MF; | MachineFunction *MF; | |||
unsigned NextFnNum; | unsigned NextFnNum; | |||
public: | public: | |||
static char ID; | static char ID; | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
MachineFunctionPass.h | MachineFunctionPass.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file defines the MachineFunctionPass class. MachineFunctionPass's are | // This file defines the MachineFunctionPass class. MachineFunctionPass's are | |||
// just FunctionPass's, except they operate on machine code as part of a co de | // just FunctionPass's, except they operate on machine code as part of a co de | |||
// generator. Because they operate on machine code, not the LLVM | // generator. Because they operate on machine code, not the LLVM | |||
// representation, MachineFunctionPass's are not allowed to modify the LLVM | // representation, MachineFunctionPass's are not allowed to modify the LLVM | |||
// representation. Due to this limitation, the MachineFunctionPass class t akes | // representation. Due to this limitation, the MachineFunctionPass class t akes | |||
// care of declaring that no LLVM passes are invalidated. | // care of declaring that no LLVM passes are invalidated. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H | #ifndef LLVM_CODEGEN_MACHINEFUNCTIONPASS_H | |||
#define LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H | #define LLVM_CODEGEN_MACHINEFUNCTIONPASS_H | |||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
namespace llvm { | namespace llvm { | |||
class MachineFunction; | class MachineFunction; | |||
/// MachineFunctionPass - This class adapts the FunctionPass interface to | /// MachineFunctionPass - This class adapts the FunctionPass interface to | |||
/// allow convenient creation of passes that operate on the MachineFunction | /// allow convenient creation of passes that operate on the MachineFunction | |||
/// representation. Instead of overriding runOnFunction, subclasses | /// representation. Instead of overriding runOnFunction, subclasses | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
MachineInstr.h | MachineInstr.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file contains the declaration of the MachineInstr class, which is t he | // This file contains the declaration of the MachineInstr class, which is t he | |||
// basic representation for all target dependent machine instructions used by | // basic representation for all target dependent machine instructions used by | |||
// the back end. | // the back end. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINEINSTR_H | #ifndef LLVM_CODEGEN_MACHINEINSTR_H | |||
#define LLVM_CODEGEN_MACHINEINSTR_H | #define LLVM_CODEGEN_MACHINEINSTR_H | |||
#include "llvm/CodeGen/MachineOperand.h" | ||||
#include "llvm/MC/MCInstrDesc.h" | ||||
#include "llvm/Target/TargetOpcodes.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/ilist.h" | #include "llvm/ADT/DenseMapInfo.h" | |||
#include "llvm/ADT/ilist_node.h" | ||||
#include "llvm/ADT/STLExtras.h" | #include "llvm/ADT/STLExtras.h" | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/ADT/DenseMapInfo.h" | #include "llvm/ADT/ilist.h" | |||
#include "llvm/InlineAsm.h" | #include "llvm/ADT/ilist_node.h" | |||
#include "llvm/CodeGen/MachineOperand.h" | ||||
#include "llvm/IR/InlineAsm.h" | ||||
#include "llvm/MC/MCInstrDesc.h" | ||||
#include "llvm/Support/ArrayRecycler.h" | ||||
#include "llvm/Support/DebugLoc.h" | #include "llvm/Support/DebugLoc.h" | |||
#include "llvm/Target/TargetOpcodes.h" | ||||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
template <typename T> class SmallVectorImpl; | template <typename T> class SmallVectorImpl; | |||
class AliasAnalysis; | class AliasAnalysis; | |||
class TargetInstrInfo; | class TargetInstrInfo; | |||
class TargetRegisterClass; | class TargetRegisterClass; | |||
class TargetRegisterInfo; | class TargetRegisterInfo; | |||
class MachineFunction; | class MachineFunction; | |||
class MachineMemOperand; | class MachineMemOperand; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// MachineInstr - Representation of each machine instruction. | /// MachineInstr - Representation of each machine instruction. | |||
/// | /// | |||
/// This class isn't a POD type, but it must have a trivial destructor. Whe | ||||
n a | ||||
/// MachineFunction is deleted, all the contained MachineInstrs are dealloc | ||||
ated | ||||
/// without having their destructor called. | ||||
/// | ||||
class MachineInstr : public ilist_node<MachineInstr> { | class MachineInstr : public ilist_node<MachineInstr> { | |||
public: | public: | |||
typedef MachineMemOperand **mmo_iterator; | typedef MachineMemOperand **mmo_iterator; | |||
/// Flags to specify different kinds of comments to output in | /// Flags to specify different kinds of comments to output in | |||
/// assembly code. These flags carry semantic information not | /// assembly code. These flags carry semantic information not | |||
/// otherwise easily derivable from the IR text. | /// otherwise easily derivable from the IR text. | |||
/// | /// | |||
enum CommentFlag { | enum CommentFlag { | |||
ReloadReuse = 0x1 | ReloadReuse = 0x1 | |||
}; | }; | |||
enum MIFlag { | enum MIFlag { | |||
NoFlags = 0, | NoFlags = 0, | |||
FrameSetup = 1 << 0, // Instruction is used as a part of | FrameSetup = 1 << 0, // Instruction is used as a part of | |||
// function frame setup code. | // function frame setup code. | |||
InsideBundle = 1 << 1 // Instruction is inside a bundle ( | BundledPred = 1 << 1, // Instruction has bundled predeces | |||
not | sors. | |||
// the first MI in a bundle) | BundledSucc = 1 << 2 // Instruction has bundled successo | |||
rs. | ||||
}; | }; | |||
private: | private: | |||
const MCInstrDesc *MCID; // Instruction descriptor. | const MCInstrDesc *MCID; // Instruction descriptor. | |||
MachineBasicBlock *Parent; // Pointer to the owning basic bloc | ||||
k. | ||||
// Operands are allocated by an ArrayRecycler. | ||||
MachineOperand *Operands; // Pointer to the first operand. | ||||
unsigned NumOperands; // Number of operands on instructio | ||||
n. | ||||
typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity; | ||||
OperandCapacity CapOperands; // Capacity of the Operands array. | ||||
uint8_t Flags; // Various bits of additional | uint8_t Flags; // Various bits of additional | |||
// information about machine | // information about machine | |||
// instruction. | // instruction. | |||
uint8_t AsmPrinterFlags; // Various bits of information used by | uint8_t AsmPrinterFlags; // Various bits of information used by | |||
// the AsmPrinter to emit helpful | // the AsmPrinter to emit helpful | |||
// comments. This is *not* semanti c | // comments. This is *not* semanti c | |||
// information. Do not use this fo r | // information. Do not use this fo r | |||
// anything other than to convey co mment | // anything other than to convey co mment | |||
// information to AsmPrinter. | // information to AsmPrinter. | |||
uint16_t NumMemRefs; // information on memory references | uint8_t NumMemRefs; // Information on memory references . | |||
mmo_iterator MemRefs; | mmo_iterator MemRefs; | |||
std::vector<MachineOperand> Operands; // the operands | ||||
MachineBasicBlock *Parent; // Pointer to the owning basic bloc | ||||
k. | ||||
DebugLoc debugLoc; // Source line information. | DebugLoc debugLoc; // Source line information. | |||
MachineInstr(const MachineInstr&) LLVM_DELETED_FUNCTION; | MachineInstr(const MachineInstr&) LLVM_DELETED_FUNCTION; | |||
void operator=(const MachineInstr&) LLVM_DELETED_FUNCTION; | void operator=(const MachineInstr&) LLVM_DELETED_FUNCTION; | |||
// Use MachineFunction::DeleteMachineInstr() instead. | ||||
~MachineInstr() LLVM_DELETED_FUNCTION; | ||||
// Intrusive list support | // Intrusive list support | |||
friend struct ilist_traits<MachineInstr>; | friend struct ilist_traits<MachineInstr>; | |||
friend struct ilist_traits<MachineBasicBlock>; | friend struct ilist_traits<MachineBasicBlock>; | |||
void setParent(MachineBasicBlock *P) { Parent = P; } | void setParent(MachineBasicBlock *P) { Parent = P; } | |||
/// MachineInstr ctor - This constructor creates a copy of the given | /// MachineInstr ctor - This constructor creates a copy of the given | |||
/// MachineInstr in the given MachineFunction. | /// MachineInstr in the given MachineFunction. | |||
MachineInstr(MachineFunction &, const MachineInstr &); | MachineInstr(MachineFunction &, const MachineInstr &); | |||
/// MachineInstr ctor - This constructor creates a dummy MachineInstr wit | ||||
h | ||||
/// MCID NULL and no operands. | ||||
MachineInstr(); | ||||
/// MachineInstr ctor - This constructor create a MachineInstr and add th e | /// MachineInstr ctor - This constructor create a MachineInstr and add th e | |||
/// implicit operands. It reserves space for number of operands specifie d by | /// implicit operands. It reserves space for number of operands specifie d by | |||
/// MCInstrDesc. An explicit DebugLoc is supplied. | /// MCInstrDesc. An explicit DebugLoc is supplied. | |||
MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl, bool NoImp = fal | MachineInstr(MachineFunction&, const MCInstrDesc &MCID, | |||
se); | const DebugLoc dl, bool NoImp = false); | |||
/// MachineInstr ctor - Work exactly the same as the ctor above, except t | ||||
hat | ||||
/// the MachineInstr is created and added to the end of the specified bas | ||||
ic | ||||
/// block. | ||||
MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, | ||||
const MCInstrDesc &MCID); | ||||
~MachineInstr(); | ||||
// MachineInstrs are pool-allocated and owned by MachineFunction. | // MachineInstrs are pool-allocated and owned by MachineFunction. | |||
friend class MachineFunction; | friend class MachineFunction; | |||
public: | public: | |||
const MachineBasicBlock* getParent() const { return Parent; } | const MachineBasicBlock* getParent() const { return Parent; } | |||
MachineBasicBlock* getParent() { return Parent; } | MachineBasicBlock* getParent() { return Parent; } | |||
/// getAsmPrinterFlags - Return the asm printer flags bitvector. | /// getAsmPrinterFlags - Return the asm printer flags bitvector. | |||
/// | /// | |||
skipping to change at line 163 | skipping to change at line 164 | |||
bool getFlag(MIFlag Flag) const { | bool getFlag(MIFlag Flag) const { | |||
return Flags & Flag; | return Flags & Flag; | |||
} | } | |||
/// setFlag - Set a MI flag. | /// setFlag - Set a MI flag. | |||
void setFlag(MIFlag Flag) { | void setFlag(MIFlag Flag) { | |||
Flags |= (uint8_t)Flag; | Flags |= (uint8_t)Flag; | |||
} | } | |||
void setFlags(unsigned flags) { | void setFlags(unsigned flags) { | |||
Flags = flags; | // Filter out the automatically maintained flags. | |||
unsigned Mask = BundledPred | BundledSucc; | ||||
Flags = (Flags & Mask) | (flags & ~Mask); | ||||
} | } | |||
/// clearFlag - Clear a MI flag. | /// clearFlag - Clear a MI flag. | |||
void clearFlag(MIFlag Flag) { | void clearFlag(MIFlag Flag) { | |||
Flags &= ~((uint8_t)Flag); | Flags &= ~((uint8_t)Flag); | |||
} | } | |||
/// isInsideBundle - Return true if MI is in a bundle (but not the first MI | /// isInsideBundle - Return true if MI is in a bundle (but not the first MI | |||
/// in a bundle). | /// in a bundle). | |||
/// | /// | |||
skipping to change at line 208 | skipping to change at line 211 | |||
/// ---------------- | /// ---------------- | |||
/// | MI * | | /// | MI * | | |||
/// ---------------- | /// ---------------- | |||
/// | | /// | | |||
/// ---------------- | /// ---------------- | |||
/// | MI * | | /// | MI * | | |||
/// ---------------- | /// ---------------- | |||
/// The first instruction has the special opcode "BUNDLE". It's not "insi de" | /// The first instruction has the special opcode "BUNDLE". It's not "insi de" | |||
/// a bundle, but the next three MIs are. | /// a bundle, but the next three MIs are. | |||
bool isInsideBundle() const { | bool isInsideBundle() const { | |||
return getFlag(InsideBundle); | return getFlag(BundledPred); | |||
} | ||||
/// setIsInsideBundle - Set InsideBundle bit. | ||||
/// | ||||
void setIsInsideBundle(bool Val = true) { | ||||
if (Val) | ||||
setFlag(InsideBundle); | ||||
else | ||||
clearFlag(InsideBundle); | ||||
} | } | |||
/// isBundled - Return true if this instruction part of a bundle. This is true | /// isBundled - Return true if this instruction part of a bundle. This is true | |||
/// if either itself or its following instruction is marked "InsideBundle ". | /// if either itself or its following instruction is marked "InsideBundle ". | |||
bool isBundled() const; | bool isBundled() const { | |||
return isBundledWithPred() || isBundledWithSucc(); | ||||
} | ||||
/// Return true if this instruction is part of a bundle, and it is not th | ||||
e | ||||
/// first instruction in the bundle. | ||||
bool isBundledWithPred() const { return getFlag(BundledPred); } | ||||
/// Return true if this instruction is part of a bundle, and it is not th | ||||
e | ||||
/// last instruction in the bundle. | ||||
bool isBundledWithSucc() const { return getFlag(BundledSucc); } | ||||
/// Bundle this instruction with its predecessor. This can be an unbundle | ||||
d | ||||
/// instruction, or it can be the first instruction in a bundle. | ||||
void bundleWithPred(); | ||||
/// Bundle this instruction with its successor. This can be an unbundled | ||||
/// instruction, or it can be the last instruction in a bundle. | ||||
void bundleWithSucc(); | ||||
/// Break bundle above this instruction. | ||||
void unbundleFromPred(); | ||||
/// Break bundle below this instruction. | ||||
void unbundleFromSucc(); | ||||
/// getDebugLoc - Returns the debug location id of this MachineInstr. | /// getDebugLoc - Returns the debug location id of this MachineInstr. | |||
/// | /// | |||
DebugLoc getDebugLoc() const { return debugLoc; } | DebugLoc getDebugLoc() const { return debugLoc; } | |||
/// emitError - Emit an error referring to the source location of this | /// emitError - Emit an error referring to the source location of this | |||
/// instruction. This should only be used for inline assembly that is som ehow | /// instruction. This should only be used for inline assembly that is som ehow | |||
/// impossible to compile. Other errors should have been handled much | /// impossible to compile. Other errors should have been handled much | |||
/// earlier. | /// earlier. | |||
/// | /// | |||
skipping to change at line 247 | skipping to change at line 265 | |||
/// getDesc - Returns the target instruction descriptor of this | /// getDesc - Returns the target instruction descriptor of this | |||
/// MachineInstr. | /// MachineInstr. | |||
const MCInstrDesc &getDesc() const { return *MCID; } | const MCInstrDesc &getDesc() const { return *MCID; } | |||
/// getOpcode - Returns the opcode of this MachineInstr. | /// getOpcode - Returns the opcode of this MachineInstr. | |||
/// | /// | |||
int getOpcode() const { return MCID->Opcode; } | int getOpcode() const { return MCID->Opcode; } | |||
/// Access to explicit operands of the instruction. | /// Access to explicit operands of the instruction. | |||
/// | /// | |||
unsigned getNumOperands() const { return (unsigned)Operands.size(); } | unsigned getNumOperands() const { return NumOperands; } | |||
const MachineOperand& getOperand(unsigned i) const { | const MachineOperand& getOperand(unsigned i) const { | |||
assert(i < getNumOperands() && "getOperand() out of range!"); | assert(i < getNumOperands() && "getOperand() out of range!"); | |||
return Operands[i]; | return Operands[i]; | |||
} | } | |||
MachineOperand& getOperand(unsigned i) { | MachineOperand& getOperand(unsigned i) { | |||
assert(i < getNumOperands() && "getOperand() out of range!"); | assert(i < getNumOperands() && "getOperand() out of range!"); | |||
return Operands[i]; | return Operands[i]; | |||
} | } | |||
/// getNumExplicitOperands - Returns the number of non-implicit operands. | /// getNumExplicitOperands - Returns the number of non-implicit operands. | |||
/// | /// | |||
unsigned getNumExplicitOperands() const; | unsigned getNumExplicitOperands() const; | |||
/// iterator/begin/end - Iterate over all operands of a machine instructi on. | /// iterator/begin/end - Iterate over all operands of a machine instructi on. | |||
typedef std::vector<MachineOperand>::iterator mop_iterator; | typedef MachineOperand *mop_iterator; | |||
typedef std::vector<MachineOperand>::const_iterator const_mop_iterator; | typedef const MachineOperand *const_mop_iterator; | |||
mop_iterator operands_begin() { return Operands.begin(); } | mop_iterator operands_begin() { return Operands; } | |||
mop_iterator operands_end() { return Operands.end(); } | mop_iterator operands_end() { return Operands + NumOperands; } | |||
const_mop_iterator operands_begin() const { return Operands.begin(); } | const_mop_iterator operands_begin() const { return Operands; } | |||
const_mop_iterator operands_end() const { return Operands.end(); } | const_mop_iterator operands_end() const { return Operands + NumOperands; | |||
} | ||||
/// Access to memory operands of the instruction | /// Access to memory operands of the instruction | |||
mmo_iterator memoperands_begin() const { return MemRefs; } | mmo_iterator memoperands_begin() const { return MemRefs; } | |||
mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; } | mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; } | |||
bool memoperands_empty() const { return NumMemRefs == 0; } | bool memoperands_empty() const { return NumMemRefs == 0; } | |||
/// hasOneMemOperand - Return true if this instruction has exactly one | /// hasOneMemOperand - Return true if this instruction has exactly one | |||
/// MachineMemOperand. | /// MachineMemOperand. | |||
bool hasOneMemOperand() const { | bool hasOneMemOperand() const { | |||
return NumMemRefs == 1; | return NumMemRefs == 1; | |||
skipping to change at line 298 | skipping to change at line 316 | |||
AnyInBundle, // Return true if any instruction in bundle has proper ty | AnyInBundle, // Return true if any instruction in bundle has proper ty | |||
AllInBundle // Return true if all instructions in bundle have prop erty | AllInBundle // Return true if all instructions in bundle have prop erty | |||
}; | }; | |||
/// hasProperty - Return true if the instruction (or in the case of a bun dle, | /// hasProperty - Return true if the instruction (or in the case of a bun dle, | |||
/// the instructions inside the bundle) has the specified property. | /// the instructions inside the bundle) has the specified property. | |||
/// The first argument is the property being queried. | /// The first argument is the property being queried. | |||
/// The second argument indicates whether the query should look inside | /// The second argument indicates whether the query should look inside | |||
/// instruction bundles. | /// instruction bundles. | |||
bool hasProperty(unsigned MCFlag, QueryType Type = AnyInBundle) const { | bool hasProperty(unsigned MCFlag, QueryType Type = AnyInBundle) const { | |||
// Inline the fast path. | // Inline the fast path for unbundled or bundle-internal instructions. | |||
if (Type == IgnoreBundle || !isBundle()) | if (Type == IgnoreBundle || !isBundled() || isBundledWithPred()) | |||
return getDesc().getFlags() & (1 << MCFlag); | return getDesc().getFlags() & (1 << MCFlag); | |||
// If we have a bundle, take the slow path. | // If this is the first instruction in a bundle, take the slow path. | |||
return hasPropertyInBundle(1 << MCFlag, Type); | return hasPropertyInBundle(1 << MCFlag, Type); | |||
} | } | |||
/// isVariadic - Return true if this instruction can have a variable numb er of | /// isVariadic - Return true if this instruction can have a variable numb er of | |||
/// operands. In this case, the variable operands will be after the norm al | /// operands. In this case, the variable operands will be after the norm al | |||
/// operands but before the implicit definitions and uses (if any are | /// operands but before the implicit definitions and uses (if any are | |||
/// present). | /// present). | |||
bool isVariadic(QueryType Type = IgnoreBundle) const { | bool isVariadic(QueryType Type = IgnoreBundle) const { | |||
return hasProperty(MCID::Variadic, Type); | return hasProperty(MCID::Variadic, Type); | |||
} | } | |||
skipping to change at line 579 | skipping to change at line 597 | |||
CheckKillDead, // Check all operands including kill / dead markers | CheckKillDead, // Check all operands including kill / dead markers | |||
IgnoreDefs, // Ignore all definitions | IgnoreDefs, // Ignore all definitions | |||
IgnoreVRegDefs // Ignore virtual register definitions | IgnoreVRegDefs // Ignore virtual register definitions | |||
}; | }; | |||
/// isIdenticalTo - Return true if this instruction is identical to (same | /// isIdenticalTo - Return true if this instruction is identical to (same | |||
/// opcode and same operands as) the specified instruction. | /// opcode and same operands as) the specified instruction. | |||
bool isIdenticalTo(const MachineInstr *Other, | bool isIdenticalTo(const MachineInstr *Other, | |||
MICheckType Check = CheckDefs) const; | MICheckType Check = CheckDefs) const; | |||
/// removeFromParent - This method unlinks 'this' from the containing bas | /// Unlink 'this' from the containing basic block, and return it without | |||
ic | /// deleting it. | |||
/// block, and returns it, but does not delete it. | /// | |||
/// This function can not be used on bundled instructions, use | ||||
/// removeFromBundle() to remove individual instructions from a bundle. | ||||
MachineInstr *removeFromParent(); | MachineInstr *removeFromParent(); | |||
/// eraseFromParent - This method unlinks 'this' from the containing basi | /// Unlink this instruction from its basic block and return it without | |||
c | /// deleting it. | |||
/// block and deletes it. | /// | |||
/// If the instruction is part of a bundle, the other instructions in the | ||||
/// bundle remain bundled. | ||||
MachineInstr *removeFromBundle(); | ||||
/// Unlink 'this' from the containing basic block and delete it. | ||||
/// | ||||
/// If this instruction is the header of a bundle, the whole bundle is er | ||||
ased. | ||||
/// This function can not be used for instructions inside a bundle, use | ||||
/// eraseFromBundle() to erase individual bundled instructions. | ||||
void eraseFromParent(); | void eraseFromParent(); | |||
/// Unlink 'this' form its basic block and delete it. | ||||
/// | ||||
/// If the instruction is part of a bundle, the other instructions in the | ||||
/// bundle remain bundled. | ||||
void eraseFromBundle(); | ||||
/// isLabel - Returns true if the MachineInstr represents a label. | /// isLabel - Returns true if the MachineInstr represents a label. | |||
/// | /// | |||
bool isLabel() const { | bool isLabel() const { | |||
return getOpcode() == TargetOpcode::PROLOG_LABEL || | return getOpcode() == TargetOpcode::PROLOG_LABEL || | |||
getOpcode() == TargetOpcode::EH_LABEL || | getOpcode() == TargetOpcode::EH_LABEL || | |||
getOpcode() == TargetOpcode::GC_LABEL; | getOpcode() == TargetOpcode::GC_LABEL; | |||
} | } | |||
bool isPrologLabel() const { | bool isPrologLabel() const { | |||
return getOpcode() == TargetOpcode::PROLOG_LABEL; | return getOpcode() == TargetOpcode::PROLOG_LABEL; | |||
} | } | |||
bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } | bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } | |||
bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } | bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } | |||
bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE ; } | bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE ; } | |||
bool isPHI() const { return getOpcode() == TargetOpcode::PHI; } | bool isPHI() const { return getOpcode() == TargetOpcode::PHI; } | |||
bool isKill() const { return getOpcode() == TargetOpcode::KILL; } | bool isKill() const { return getOpcode() == TargetOpcode::KILL; } | |||
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_D EF; } | bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_D EF; } | |||
bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; } | bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; } | |||
bool isMSInlineAsm() const { | ||||
return getOpcode() == TargetOpcode::INLINEASM && getInlineAsmDialect(); | ||||
} | ||||
bool isStackAligningInlineAsm() const; | bool isStackAligningInlineAsm() const; | |||
InlineAsm::AsmDialect getInlineAsmDialect() const; | InlineAsm::AsmDialect getInlineAsmDialect() const; | |||
bool isInsertSubreg() const { | bool isInsertSubreg() const { | |||
return getOpcode() == TargetOpcode::INSERT_SUBREG; | return getOpcode() == TargetOpcode::INSERT_SUBREG; | |||
} | } | |||
bool isSubregToReg() const { | bool isSubregToReg() const { | |||
return getOpcode() == TargetOpcode::SUBREG_TO_REG; | return getOpcode() == TargetOpcode::SUBREG_TO_REG; | |||
} | } | |||
bool isRegSequence() const { | bool isRegSequence() const { | |||
return getOpcode() == TargetOpcode::REG_SEQUENCE; | return getOpcode() == TargetOpcode::REG_SEQUENCE; | |||
skipping to change at line 663 | skipping to change at line 703 | |||
case TargetOpcode::IMPLICIT_DEF: | case TargetOpcode::IMPLICIT_DEF: | |||
case TargetOpcode::KILL: | case TargetOpcode::KILL: | |||
case TargetOpcode::PROLOG_LABEL: | case TargetOpcode::PROLOG_LABEL: | |||
case TargetOpcode::EH_LABEL: | case TargetOpcode::EH_LABEL: | |||
case TargetOpcode::GC_LABEL: | case TargetOpcode::GC_LABEL: | |||
case TargetOpcode::DBG_VALUE: | case TargetOpcode::DBG_VALUE: | |||
return true; | return true; | |||
} | } | |||
} | } | |||
/// getBundleSize - Return the number of instructions inside the MI bundl | /// Return the number of instructions inside the MI bundle, excluding the | |||
e. | /// bundle header. | |||
/// | ||||
/// This is the number of instructions that MachineBasicBlock::iterator | ||||
/// skips, 0 for unbundled instructions. | ||||
unsigned getBundleSize() const; | unsigned getBundleSize() const; | |||
/// readsRegister - Return true if the MachineInstr reads the specified | /// readsRegister - Return true if the MachineInstr reads the specified | |||
/// register. If TargetRegisterInfo is passed, then it also checks if the re | /// register. If TargetRegisterInfo is passed, then it also checks if the re | |||
/// is a read of a super-register. | /// is a read of a super-register. | |||
/// This does not count partial redefines of virtual registers as reads: | /// This does not count partial redefines of virtual registers as reads: | |||
/// %reg1024:6 = OP. | /// %reg1024:6 = OP. | |||
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI = NULL) co nst { | bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI = NULL) co nst { | |||
return findRegisterUseOperandIdx(Reg, false, TRI) != -1; | return findRegisterUseOperandIdx(Reg, false, TRI) != -1; | |||
} | } | |||
skipping to change at line 822 | skipping to change at line 866 | |||
return false; | return false; | |||
if (DefOpIdx) | if (DefOpIdx) | |||
*DefOpIdx = findTiedOperandIdx(UseOpIdx); | *DefOpIdx = findTiedOperandIdx(UseOpIdx); | |||
return true; | return true; | |||
} | } | |||
/// clearKillInfo - Clears kill flags on all operands. | /// clearKillInfo - Clears kill flags on all operands. | |||
/// | /// | |||
void clearKillInfo(); | void clearKillInfo(); | |||
/// copyKillDeadInfo - Copies kill / dead operand properties from MI. | ||||
/// | ||||
void copyKillDeadInfo(const MachineInstr *MI); | ||||
/// copyPredicates - Copies predicate operand(s) from MI. | ||||
void copyPredicates(const MachineInstr *MI); | ||||
/// substituteRegister - Replace all occurrences of FromReg with ToReg:Su bIdx, | /// substituteRegister - Replace all occurrences of FromReg with ToReg:Su bIdx, | |||
/// properly composing subreg indices where necessary. | /// properly composing subreg indices where necessary. | |||
void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx , | void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx , | |||
const TargetRegisterInfo &RegInfo); | const TargetRegisterInfo &RegInfo); | |||
/// addRegisterKilled - We have determined MI kills a register. Look for the | /// addRegisterKilled - We have determined MI kills a register. Look for the | |||
/// operand that uses it and mark it as IsKill. If AddIfNotFound is true, | /// operand that uses it and mark it as IsKill. If AddIfNotFound is true, | |||
/// add a implicit operand if it's not found. Returns true if the operand | /// add a implicit operand if it's not found. Returns true if the operand | |||
/// exists / is added. | /// exists / is added. | |||
bool addRegisterKilled(unsigned IncomingReg, | bool addRegisterKilled(unsigned IncomingReg, | |||
skipping to change at line 910 | skipping to change at line 947 | |||
/// in one of its operands (see InlineAsm::Extra_HasSideEffect). | /// in one of its operands (see InlineAsm::Extra_HasSideEffect). | |||
/// | /// | |||
bool hasUnmodeledSideEffects() const; | bool hasUnmodeledSideEffects() const; | |||
/// allDefsAreDead - Return true if all the defs of this instruction are dead. | /// allDefsAreDead - Return true if all the defs of this instruction are dead. | |||
/// | /// | |||
bool allDefsAreDead() const; | bool allDefsAreDead() const; | |||
/// copyImplicitOps - Copy implicit register operands from specified | /// copyImplicitOps - Copy implicit register operands from specified | |||
/// instruction to this instruction. | /// instruction to this instruction. | |||
void copyImplicitOps(const MachineInstr *MI); | void copyImplicitOps(MachineFunction &MF, const MachineInstr *MI); | |||
// | // | |||
// Debugging support | // Debugging support | |||
// | // | |||
void print(raw_ostream &OS, const TargetMachine *TM = 0) const; | void print(raw_ostream &OS, const TargetMachine *TM = 0, | |||
bool SkipOpers = false) const; | ||||
void dump() const; | void dump() const; | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Accessors used to build up machine instructions. | // Accessors used to build up machine instructions. | |||
/// addOperand - Add the specified operand to the instruction. If it is | /// Add the specified operand to the instruction. If it is an implicit | |||
an | /// operand, it is added to the end of the operand list. If it is an | |||
/// implicit operand, it is added to the end of the operand list. If it | /// explicit operand it is added at the end of the explicit operand list | |||
is | ||||
/// an explicit operand it is added at the end of the explicit operand li | ||||
st | ||||
/// (before the first implicit operand). | /// (before the first implicit operand). | |||
/// | ||||
/// MF must be the machine function that was used to allocate this | ||||
/// instruction. | ||||
/// | ||||
/// MachineInstrBuilder provides a more convenient interface for creating | ||||
/// instructions and adding operands. | ||||
void addOperand(MachineFunction &MF, const MachineOperand &Op); | ||||
/// Add an operand without providing an MF reference. This only works for | ||||
/// instructions that are inserted in a basic block. | ||||
/// | ||||
/// MachineInstrBuilder and the two-argument addOperand(MF, MO) should be | ||||
/// preferred. | ||||
void addOperand(const MachineOperand &Op); | void addOperand(const MachineOperand &Op); | |||
/// setDesc - Replace the instruction descriptor (thus opcode) of | /// setDesc - Replace the instruction descriptor (thus opcode) of | |||
/// the current instruction with a new one. | /// the current instruction with a new one. | |||
/// | /// | |||
void setDesc(const MCInstrDesc &tid) { MCID = &tid; } | void setDesc(const MCInstrDesc &tid) { MCID = &tid; } | |||
/// setDebugLoc - Replace current source information with new such. | /// setDebugLoc - Replace current source information with new such. | |||
/// Avoid using this, the constructor argument is preferable. | /// Avoid using this, the constructor argument is preferable. | |||
/// | /// | |||
skipping to change at line 951 | skipping to change at line 1002 | |||
/// addMemOperand - Add a MachineMemOperand to the machine instruction. | /// addMemOperand - Add a MachineMemOperand to the machine instruction. | |||
/// This function should be used only occasionally. The setMemRefs functi on | /// This function should be used only occasionally. The setMemRefs functi on | |||
/// is the primary method for setting up a MachineInstr's MemRefs list. | /// is the primary method for setting up a MachineInstr's MemRefs list. | |||
void addMemOperand(MachineFunction &MF, MachineMemOperand *MO); | void addMemOperand(MachineFunction &MF, MachineMemOperand *MO); | |||
/// setMemRefs - Assign this MachineInstr's memory reference descriptor | /// setMemRefs - Assign this MachineInstr's memory reference descriptor | |||
/// list. This does not transfer ownership. | /// list. This does not transfer ownership. | |||
void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) { | void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) { | |||
MemRefs = NewMemRefs; | MemRefs = NewMemRefs; | |||
NumMemRefs = NewMemRefsEnd - NewMemRefs; | NumMemRefs = uint8_t(NewMemRefsEnd - NewMemRefs); | |||
assert(NumMemRefs == NewMemRefsEnd - NewMemRefs && "Too many memrefs"); | ||||
} | } | |||
private: | private: | |||
/// getRegInfo - If this instruction is embedded into a MachineFunction, | /// getRegInfo - If this instruction is embedded into a MachineFunction, | |||
/// return the MachineRegisterInfo object for the current function, other wise | /// return the MachineRegisterInfo object for the current function, other wise | |||
/// return null. | /// return null. | |||
MachineRegisterInfo *getRegInfo(); | MachineRegisterInfo *getRegInfo(); | |||
/// untieRegOperand - Break any tie involving OpIdx. | /// untieRegOperand - Break any tie involving OpIdx. | |||
void untieRegOperand(unsigned OpIdx) { | void untieRegOperand(unsigned OpIdx) { | |||
MachineOperand &MO = getOperand(OpIdx); | MachineOperand &MO = getOperand(OpIdx); | |||
if (MO.isReg() && MO.isTied()) { | if (MO.isReg() && MO.isTied()) { | |||
getOperand(findTiedOperandIdx(OpIdx)).TiedTo = 0; | getOperand(findTiedOperandIdx(OpIdx)).TiedTo = 0; | |||
MO.TiedTo = 0; | MO.TiedTo = 0; | |||
} | } | |||
} | } | |||
/// addImplicitDefUseOperands - Add all implicit def and use operands to | /// addImplicitDefUseOperands - Add all implicit def and use operands to | |||
/// this instruction. | /// this instruction. | |||
void addImplicitDefUseOperands(); | void addImplicitDefUseOperands(MachineFunction &MF); | |||
/// RemoveRegOperandsFromUseLists - Unlink all of the register operands i n | /// RemoveRegOperandsFromUseLists - Unlink all of the register operands i n | |||
/// this instruction from their respective use lists. This requires that the | /// this instruction from their respective use lists. This requires that the | |||
/// operands already be on their use lists. | /// operands already be on their use lists. | |||
void RemoveRegOperandsFromUseLists(MachineRegisterInfo&); | void RemoveRegOperandsFromUseLists(MachineRegisterInfo&); | |||
/// AddRegOperandsToUseLists - Add all of the register operands in | /// AddRegOperandsToUseLists - Add all of the register operands in | |||
/// this instruction from their respective use lists. This requires that the | /// this instruction from their respective use lists. This requires that the | |||
/// operands not be on their use lists yet. | /// operands not be on their use lists yet. | |||
void AddRegOperandsToUseLists(MachineRegisterInfo&); | void AddRegOperandsToUseLists(MachineRegisterInfo&); | |||
End of changes. 33 change blocks. | ||||
78 lines changed or deleted | 129 lines changed or added | |||
MachineInstrBuilder.h | MachineInstrBuilder.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// simplifying how MachineInstr's are created. It allows use of code like this: | // simplifying how MachineInstr's are created. It allows use of code like this: | |||
// | // | |||
// M = BuildMI(X86::ADDrr8, 2).addReg(argVal1).addReg(argVal2); | // M = BuildMI(X86::ADDrr8, 2).addReg(argVal1).addReg(argVal2); | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINEINSTRBUILDER_H | #ifndef LLVM_CODEGEN_MACHINEINSTRBUILDER_H | |||
#define LLVM_CODEGEN_MACHINEINSTRBUILDER_H | #define LLVM_CODEGEN_MACHINEINSTRBUILDER_H | |||
#include "llvm/CodeGen/MachineFunction.h" | #include "llvm/CodeGen/MachineFunction.h" | |||
#include "llvm/CodeGen/MachineInstrBundle.h" | ||||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
namespace llvm { | namespace llvm { | |||
class MCInstrDesc; | class MCInstrDesc; | |||
class MDNode; | class MDNode; | |||
namespace RegState { | namespace RegState { | |||
enum { | enum { | |||
Define = 0x2, | Define = 0x2, | |||
skipping to change at line 45 | skipping to change at line 46 | |||
EarlyClobber = 0x40, | EarlyClobber = 0x40, | |||
Debug = 0x80, | Debug = 0x80, | |||
InternalRead = 0x100, | InternalRead = 0x100, | |||
DefineNoRead = Define | Undef, | DefineNoRead = Define | Undef, | |||
ImplicitDefine = Implicit | Define, | ImplicitDefine = Implicit | Define, | |||
ImplicitKill = Implicit | Kill | ImplicitKill = Implicit | Kill | |||
}; | }; | |||
} | } | |||
class MachineInstrBuilder { | class MachineInstrBuilder { | |||
MachineFunction *MF; | ||||
MachineInstr *MI; | MachineInstr *MI; | |||
public: | public: | |||
MachineInstrBuilder() : MI(0) {} | MachineInstrBuilder() : MF(0), MI(0) {} | |||
explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {} | ||||
/// Create a MachineInstrBuilder for manipulating an existing instruction | ||||
. | ||||
/// F must be the machine function that was used to allocate I. | ||||
MachineInstrBuilder(MachineFunction &F, MachineInstr *I) : MF(&F), MI(I) | ||||
{} | ||||
/// Allow automatic conversion to the machine instruction we are working on. | /// Allow automatic conversion to the machine instruction we are working on. | |||
/// | /// | |||
operator MachineInstr*() const { return MI; } | operator MachineInstr*() const { return MI; } | |||
MachineInstr *operator->() const { return MI; } | MachineInstr *operator->() const { return MI; } | |||
operator MachineBasicBlock::iterator() const { return MI; } | operator MachineBasicBlock::iterator() const { return MI; } | |||
/// addReg - Add a new virtual register operand... | /// addReg - Add a new virtual register operand... | |||
/// | /// | |||
const | const | |||
MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0, | MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0, | |||
unsigned SubReg = 0) const { | unsigned SubReg = 0) const { | |||
assert((flags & 0x1) == 0 && | assert((flags & 0x1) == 0 && | |||
"Passing in 'true' to addReg is forbidden! Use enums instead."); | "Passing in 'true' to addReg is forbidden! Use enums instead."); | |||
MI->addOperand(MachineOperand::CreateReg(RegNo, | MI->addOperand(*MF, MachineOperand::CreateReg(RegNo, | |||
flags & RegState::Define, | flags & RegState::Define, | |||
flags & RegState::Implicit, | flags & RegState::Implicit, | |||
flags & RegState::Kill, | flags & RegState::Kill, | |||
flags & RegState::Dead, | flags & RegState::Dead, | |||
flags & RegState::Undef, | flags & RegState::Undef, | |||
flags & RegState::EarlyClobber | flags & RegState::EarlyClobb | |||
, | er, | |||
SubReg, | SubReg, | |||
flags & RegState::Debug, | flags & RegState::Debug, | |||
flags & RegState::InternalRead | flags & RegState::InternalRe | |||
)); | ad)); | |||
return *this; | return *this; | |||
} | } | |||
/// addImm - Add a new immediate operand. | /// addImm - Add a new immediate operand. | |||
/// | /// | |||
const MachineInstrBuilder &addImm(int64_t Val) const { | const MachineInstrBuilder &addImm(int64_t Val) const { | |||
MI->addOperand(MachineOperand::CreateImm(Val)); | MI->addOperand(*MF, MachineOperand::CreateImm(Val)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addCImm(const ConstantInt *Val) const { | const MachineInstrBuilder &addCImm(const ConstantInt *Val) const { | |||
MI->addOperand(MachineOperand::CreateCImm(Val)); | MI->addOperand(*MF, MachineOperand::CreateCImm(Val)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const { | const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const { | |||
MI->addOperand(MachineOperand::CreateFPImm(Val)); | MI->addOperand(*MF, MachineOperand::CreateFPImm(Val)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB, | const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB, | |||
unsigned char TargetFlags = 0) const { | unsigned char TargetFlags = 0) const { | |||
MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags)); | MI->addOperand(*MF, MachineOperand::CreateMBB(MBB, TargetFlags)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addFrameIndex(int Idx) const { | const MachineInstrBuilder &addFrameIndex(int Idx) const { | |||
MI->addOperand(MachineOperand::CreateFI(Idx)); | MI->addOperand(*MF, MachineOperand::CreateFI(Idx)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx, | const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx, | |||
int Offset = 0, | int Offset = 0, | |||
unsigned char TargetFlags = 0) co nst { | unsigned char TargetFlags = 0) co nst { | |||
MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags)); | MI->addOperand(*MF, MachineOperand::CreateCPI(Idx, Offset, TargetFlags) ); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addTargetIndex(unsigned Idx, int64_t Offset = 0, | const MachineInstrBuilder &addTargetIndex(unsigned Idx, int64_t Offset = 0, | |||
unsigned char TargetFlags = 0) co nst { | unsigned char TargetFlags = 0) co nst { | |||
MI->addOperand(MachineOperand::CreateTargetIndex(Idx, Offset, TargetFla | MI->addOperand(*MF, MachineOperand::CreateTargetIndex(Idx, Offset, | |||
gs)); | TargetFlags)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addJumpTableIndex(unsigned Idx, | const MachineInstrBuilder &addJumpTableIndex(unsigned Idx, | |||
unsigned char TargetFlags = 0) co nst { | unsigned char TargetFlags = 0) co nst { | |||
MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags)); | MI->addOperand(*MF, MachineOperand::CreateJTI(Idx, TargetFlags)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV, | const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV, | |||
int64_t Offset = 0, | int64_t Offset = 0, | |||
unsigned char TargetFlags = 0) co nst { | unsigned char TargetFlags = 0) co nst { | |||
MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags)); | MI->addOperand(*MF, MachineOperand::CreateGA(GV, Offset, TargetFlags)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addExternalSymbol(const char *FnName, | const MachineInstrBuilder &addExternalSymbol(const char *FnName, | |||
unsigned char TargetFlags = 0) co nst { | unsigned char TargetFlags = 0) co nst { | |||
MI->addOperand(MachineOperand::CreateES(FnName, TargetFlags)); | MI->addOperand(*MF, MachineOperand::CreateES(FnName, TargetFlags)); | |||
return *this; | ||||
} | ||||
const MachineInstrBuilder &addBlockAddress(const BlockAddress *BA, | ||||
int64_t Offset = 0, | ||||
unsigned char TargetFlags = 0) co | ||||
nst { | ||||
MI->addOperand(*MF, MachineOperand::CreateBA(BA, Offset, TargetFlags)); | ||||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const { | const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const { | |||
MI->addOperand(MachineOperand::CreateRegMask(Mask)); | MI->addOperand(*MF, MachineOperand::CreateRegMask(Mask)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const { | const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const { | |||
MI->addMemOperand(*MI->getParent()->getParent(), MMO); | MI->addMemOperand(*MF, MMO); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &setMemRefs(MachineInstr::mmo_iterator b, | const MachineInstrBuilder &setMemRefs(MachineInstr::mmo_iterator b, | |||
MachineInstr::mmo_iterator e) const { | MachineInstr::mmo_iterator e) const { | |||
MI->setMemRefs(b, e); | MI->setMemRefs(b, e); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addOperand(const MachineOperand &MO) const { | const MachineInstrBuilder &addOperand(const MachineOperand &MO) const { | |||
MI->addOperand(MO); | MI->addOperand(*MF, MO); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addMetadata(const MDNode *MD) const { | const MachineInstrBuilder &addMetadata(const MDNode *MD) const { | |||
MI->addOperand(MachineOperand::CreateMetadata(MD)); | MI->addOperand(*MF, MachineOperand::CreateMetadata(MD)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &addSym(MCSymbol *Sym) const { | const MachineInstrBuilder &addSym(MCSymbol *Sym) const { | |||
MI->addOperand(MachineOperand::CreateMCSymbol(Sym)); | MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym)); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &setMIFlags(unsigned Flags) const { | const MachineInstrBuilder &setMIFlags(unsigned Flags) const { | |||
MI->setFlags(Flags); | MI->setFlags(Flags); | |||
return *this; | return *this; | |||
} | } | |||
const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const { | const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const { | |||
MI->setFlag(Flag); | MI->setFlag(Flag); | |||
skipping to change at line 198 | skipping to change at line 211 | |||
// MachineOperand. This means if the caller wants to clear the | // MachineOperand. This means if the caller wants to clear the | |||
// target flags it needs to do so explicitly. | // target flags it needs to do so explicitly. | |||
if (TargetFlags) | if (TargetFlags) | |||
return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off, | return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off, | |||
TargetFlags); | TargetFlags); | |||
return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off, | return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off, | |||
Disp.getTargetFlags()); | Disp.getTargetFlags()); | |||
} | } | |||
} | } | |||
} | } | |||
/// Copy all the implicit operands from OtherMI onto this one. | ||||
const MachineInstrBuilder ©ImplicitOps(const MachineInstr *OtherMI) { | ||||
MI->copyImplicitOps(*MF, OtherMI); | ||||
return *this; | ||||
} | ||||
}; | }; | |||
/// BuildMI - Builder interface. Specify how to create the initial instruc tion | /// BuildMI - Builder interface. Specify how to create the initial instruc tion | |||
/// itself. | /// itself. | |||
/// | /// | |||
inline MachineInstrBuilder BuildMI(MachineFunction &MF, | inline MachineInstrBuilder BuildMI(MachineFunction &MF, | |||
DebugLoc DL, | DebugLoc DL, | |||
const MCInstrDesc &MCID) { | const MCInstrDesc &MCID) { | |||
return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL)); | return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL)); | |||
} | } | |||
/// BuildMI - This version of the builder sets up the first operand as a | /// BuildMI - This version of the builder sets up the first operand as a | |||
/// destination virtual register. | /// destination virtual register. | |||
/// | /// | |||
inline MachineInstrBuilder BuildMI(MachineFunction &MF, | inline MachineInstrBuilder BuildMI(MachineFunction &MF, | |||
DebugLoc DL, | DebugLoc DL, | |||
const MCInstrDesc &MCID, | const MCInstrDesc &MCID, | |||
unsigned DestReg) { | unsigned DestReg) { | |||
return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL)) | return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL)) | |||
.addReg(DestReg, RegState::Define); | .addReg(DestReg, RegState::Define); | |||
} | } | |||
/// BuildMI - This version of the builder inserts the newly-built | /// BuildMI - This version of the builder inserts the newly-built | |||
/// instruction before the given position in the given MachineBasicBlock, a nd | /// instruction before the given position in the given MachineBasicBlock, a nd | |||
/// sets up the first operand as a destination virtual register. | /// sets up the first operand as a destination virtual register. | |||
/// | /// | |||
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | |||
MachineBasicBlock::iterator I, | MachineBasicBlock::iterator I, | |||
DebugLoc DL, | DebugLoc DL, | |||
const MCInstrDesc &MCID, | const MCInstrDesc &MCID, | |||
unsigned DestReg) { | unsigned DestReg) { | |||
MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL); | MachineFunction &MF = *BB.getParent(); | |||
MachineInstr *MI = MF.CreateMachineInstr(MCID, DL); | ||||
BB.insert(I, MI); | BB.insert(I, MI); | |||
return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define); | return MachineInstrBuilder(MF, MI).addReg(DestReg, RegState::Define); | |||
} | } | |||
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | |||
MachineBasicBlock::instr_iterator I, | MachineBasicBlock::instr_iterator I, | |||
DebugLoc DL, | DebugLoc DL, | |||
const MCInstrDesc &MCID, | const MCInstrDesc &MCID, | |||
unsigned DestReg) { | unsigned DestReg) { | |||
MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL); | MachineFunction &MF = *BB.getParent(); | |||
MachineInstr *MI = MF.CreateMachineInstr(MCID, DL); | ||||
BB.insert(I, MI); | BB.insert(I, MI); | |||
return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define); | return MachineInstrBuilder(MF, MI).addReg(DestReg, RegState::Define); | |||
} | } | |||
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | |||
MachineInstr *I, | MachineInstr *I, | |||
DebugLoc DL, | DebugLoc DL, | |||
const MCInstrDesc &MCID, | const MCInstrDesc &MCID, | |||
unsigned DestReg) { | unsigned DestReg) { | |||
if (I->isInsideBundle()) { | if (I->isInsideBundle()) { | |||
MachineBasicBlock::instr_iterator MII = I; | MachineBasicBlock::instr_iterator MII = I; | |||
return BuildMI(BB, MII, DL, MCID, DestReg); | return BuildMI(BB, MII, DL, MCID, DestReg); | |||
skipping to change at line 266 | skipping to change at line 287 | |||
} | } | |||
/// BuildMI - This version of the builder inserts the newly-built | /// BuildMI - This version of the builder inserts the newly-built | |||
/// instruction before the given position in the given MachineBasicBlock, a nd | /// instruction before the given position in the given MachineBasicBlock, a nd | |||
/// does NOT take a destination register. | /// does NOT take a destination register. | |||
/// | /// | |||
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | |||
MachineBasicBlock::iterator I, | MachineBasicBlock::iterator I, | |||
DebugLoc DL, | DebugLoc DL, | |||
const MCInstrDesc &MCID) { | const MCInstrDesc &MCID) { | |||
MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL); | MachineFunction &MF = *BB.getParent(); | |||
MachineInstr *MI = MF.CreateMachineInstr(MCID, DL); | ||||
BB.insert(I, MI); | BB.insert(I, MI); | |||
return MachineInstrBuilder(MI); | return MachineInstrBuilder(MF, MI); | |||
} | } | |||
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | |||
MachineBasicBlock::instr_iterator I, | MachineBasicBlock::instr_iterator I, | |||
DebugLoc DL, | DebugLoc DL, | |||
const MCInstrDesc &MCID) { | const MCInstrDesc &MCID) { | |||
MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL); | MachineFunction &MF = *BB.getParent(); | |||
MachineInstr *MI = MF.CreateMachineInstr(MCID, DL); | ||||
BB.insert(I, MI); | BB.insert(I, MI); | |||
return MachineInstrBuilder(MI); | return MachineInstrBuilder(MF, MI); | |||
} | } | |||
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, | |||
MachineInstr *I, | MachineInstr *I, | |||
DebugLoc DL, | DebugLoc DL, | |||
const MCInstrDesc &MCID) { | const MCInstrDesc &MCID) { | |||
if (I->isInsideBundle()) { | if (I->isInsideBundle()) { | |||
MachineBasicBlock::instr_iterator MII = I; | MachineBasicBlock::instr_iterator MII = I; | |||
return BuildMI(BB, MII, DL, MCID); | return BuildMI(BB, MII, DL, MCID); | |||
} | } | |||
skipping to change at line 332 | skipping to change at line 355 | |||
} | } | |||
inline unsigned getDeadRegState(bool B) { | inline unsigned getDeadRegState(bool B) { | |||
return B ? RegState::Dead : 0; | return B ? RegState::Dead : 0; | |||
} | } | |||
inline unsigned getUndefRegState(bool B) { | inline unsigned getUndefRegState(bool B) { | |||
return B ? RegState::Undef : 0; | return B ? RegState::Undef : 0; | |||
} | } | |||
inline unsigned getInternalReadRegState(bool B) { | inline unsigned getInternalReadRegState(bool B) { | |||
return B ? RegState::InternalRead : 0; | return B ? RegState::InternalRead : 0; | |||
} | } | |||
inline unsigned getDebugRegState(bool B) { | ||||
return B ? RegState::Debug : 0; | ||||
} | ||||
/// Helper class for constructing bundles of MachineInstrs. | ||||
/// | ||||
/// MIBundleBuilder can create a bundle from scratch by inserting new | ||||
/// MachineInstrs one at a time, or it can create a bundle from a sequence | ||||
of | ||||
/// existing MachineInstrs in a basic block. | ||||
class MIBundleBuilder { | ||||
MachineBasicBlock &MBB; | ||||
MachineBasicBlock::instr_iterator Begin; | ||||
MachineBasicBlock::instr_iterator End; | ||||
public: | ||||
/// Create an MIBundleBuilder that inserts instructions into a new bundle | ||||
in | ||||
/// BB above the bundle or instruction at Pos. | ||||
MIBundleBuilder(MachineBasicBlock &BB, | ||||
MachineBasicBlock::iterator Pos) | ||||
: MBB(BB), Begin(Pos.getInstrIterator()), End(Begin) {} | ||||
/// Create a bundle from the sequence of instructions between B and E. | ||||
MIBundleBuilder(MachineBasicBlock &BB, | ||||
MachineBasicBlock::iterator B, | ||||
MachineBasicBlock::iterator E) | ||||
: MBB(BB), Begin(B.getInstrIterator()), End(E.getInstrIterator()) { | ||||
assert(B != E && "No instructions to bundle"); | ||||
++B; | ||||
while (B != E) { | ||||
MachineInstr *MI = B; | ||||
++B; | ||||
MI->bundleWithPred(); | ||||
} | ||||
} | ||||
/// Create an MIBundleBuilder representing an existing instruction or bun | ||||
dle | ||||
/// that has MI as its head. | ||||
explicit MIBundleBuilder(MachineInstr *MI) | ||||
: MBB(*MI->getParent()), Begin(MI), End(getBundleEnd(MI)) {} | ||||
/// Return a reference to the basic block containing this bundle. | ||||
MachineBasicBlock &getMBB() const { return MBB; } | ||||
/// Return true if no instructions have been inserted in this bundle yet. | ||||
/// Empty bundles aren't representable in a MachineBasicBlock. | ||||
bool empty() const { return Begin == End; } | ||||
/// Return an iterator to the first bundled instruction. | ||||
MachineBasicBlock::instr_iterator begin() const { return Begin; } | ||||
/// Return an iterator beyond the last bundled instruction. | ||||
MachineBasicBlock::instr_iterator end() const { return End; } | ||||
/// Insert MI into this bundle before I which must point to an instructio | ||||
n in | ||||
/// the bundle, or end(). | ||||
MIBundleBuilder &insert(MachineBasicBlock::instr_iterator I, | ||||
MachineInstr *MI) { | ||||
MBB.insert(I, MI); | ||||
if (I == Begin) { | ||||
if (!empty()) | ||||
MI->bundleWithSucc(); | ||||
Begin = MI; | ||||
return *this; | ||||
} | ||||
if (I == End) { | ||||
MI->bundleWithPred(); | ||||
return *this; | ||||
} | ||||
// MI was inserted in the middle of the bundle, so its neighbors' flags | ||||
are | ||||
// already fine. Update MI's bundle flags manually. | ||||
MI->setFlag(MachineInstr::BundledPred); | ||||
MI->setFlag(MachineInstr::BundledSucc); | ||||
return *this; | ||||
} | ||||
/// Insert MI into MBB by prepending it to the instructions in the bundle | ||||
. | ||||
/// MI will become the first instruction in the bundle. | ||||
MIBundleBuilder &prepend(MachineInstr *MI) { | ||||
return insert(begin(), MI); | ||||
} | ||||
/// Insert MI into MBB by appending it to the instructions in the bundle. | ||||
/// MI will become the last instruction in the bundle. | ||||
MIBundleBuilder &append(MachineInstr *MI) { | ||||
return insert(end(), MI); | ||||
} | ||||
}; | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 31 change blocks. | ||||
40 lines changed or deleted | 158 lines changed or added | |||
MachineInstrBundle.h | MachineInstrBundle.h | |||
---|---|---|---|---|
skipping to change at line 48 | skipping to change at line 48 | |||
MachineBasicBlock::instr_iterator FirstMI); | MachineBasicBlock::instr_iterator FirstMI); | |||
/// finalizeBundles - Finalize instruction bundles in the specified | /// finalizeBundles - Finalize instruction bundles in the specified | |||
/// MachineFunction. Return true if any bundles are finalized. | /// MachineFunction. Return true if any bundles are finalized. | |||
bool finalizeBundles(MachineFunction &MF); | bool finalizeBundles(MachineFunction &MF); | |||
/// getBundleStart - Returns the first instruction in the bundle containing MI. | /// getBundleStart - Returns the first instruction in the bundle containing MI. | |||
/// | /// | |||
inline MachineInstr *getBundleStart(MachineInstr *MI) { | inline MachineInstr *getBundleStart(MachineInstr *MI) { | |||
MachineBasicBlock::instr_iterator I = MI; | MachineBasicBlock::instr_iterator I = MI; | |||
while (I->isInsideBundle()) | while (I->isBundledWithPred()) | |||
--I; | --I; | |||
return I; | return I; | |||
} | } | |||
inline const MachineInstr *getBundleStart(const MachineInstr *MI) { | inline const MachineInstr *getBundleStart(const MachineInstr *MI) { | |||
MachineBasicBlock::const_instr_iterator I = MI; | MachineBasicBlock::const_instr_iterator I = MI; | |||
while (I->isInsideBundle()) | while (I->isBundledWithPred()) | |||
--I; | --I; | |||
return I; | return I; | |||
} | } | |||
/// Return an iterator pointing beyond the bundle containing MI. | ||||
inline MachineBasicBlock::instr_iterator | ||||
getBundleEnd(MachineInstr *MI) { | ||||
MachineBasicBlock::instr_iterator I = MI; | ||||
while (I->isBundledWithSucc()) | ||||
++I; | ||||
return ++I; | ||||
} | ||||
/// Return an iterator pointing beyond the bundle containing MI. | ||||
inline MachineBasicBlock::const_instr_iterator | ||||
getBundleEnd(const MachineInstr *MI) { | ||||
MachineBasicBlock::const_instr_iterator I = MI; | ||||
while (I->isBundledWithSucc()) | ||||
++I; | ||||
return ++I; | ||||
} | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// MachineOperand iterator | // MachineOperand iterator | |||
// | // | |||
/// MachineOperandIteratorBase - Iterator that can visit all operands on a | /// MachineOperandIteratorBase - Iterator that can visit all operands on a | |||
/// MachineInstr, or all operands on a bundle of MachineInstrs. This class is | /// MachineInstr, or all operands on a bundle of MachineInstrs. This class is | |||
/// not intended to be used directly, use one of the sub-classes instead. | /// not intended to be used directly, use one of the sub-classes instead. | |||
/// | /// | |||
/// Intended use: | /// Intended use: | |||
/// | /// | |||
skipping to change at line 159 | skipping to change at line 177 | |||
/// PhysRegInfo - Information about a physical register used by a set of | /// PhysRegInfo - Information about a physical register used by a set of | |||
/// operands. | /// operands. | |||
struct PhysRegInfo { | struct PhysRegInfo { | |||
/// Clobbers - Reg or an overlapping register is defined, or a regmask | /// Clobbers - Reg or an overlapping register is defined, or a regmask | |||
/// clobbers Reg. | /// clobbers Reg. | |||
bool Clobbers; | bool Clobbers; | |||
/// Defines - Reg or a super-register is defined. | /// Defines - Reg or a super-register is defined. | |||
bool Defines; | bool Defines; | |||
/// DefinesOverlap - Reg or an overlapping register is defined. | ||||
bool DefinesOverlap; | ||||
/// Reads - Read or a super-register is read. | /// Reads - Read or a super-register is read. | |||
bool Reads; | bool Reads; | |||
/// ReadsOverlap - Reg or an overlapping register is read. | /// ReadsOverlap - Reg or an overlapping register is read. | |||
bool ReadsOverlap; | bool ReadsOverlap; | |||
/// DefinesDead - All defs of a Reg or a super-register are dead. | /// DefinesDead - All defs of a Reg or a super-register are dead. | |||
bool DefinesDead; | bool DefinesDead; | |||
/// There is a kill of Reg or a super-register. | /// There is a kill of Reg or a super-register. | |||
End of changes. 4 change blocks. | ||||
5 lines changed or deleted | 20 lines changed or added | |||
MachineJumpTableInfo.h | MachineJumpTableInfo.h | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// Instructions reference the address of these jump tables through the use of | // Instructions reference the address of these jump tables through the use of | |||
// MO_JumpTableIndex values. When emitting assembly or machine code, these | // MO_JumpTableIndex values. When emitting assembly or machine code, these | |||
// virtual address references are converted to refer to the address of the | // virtual address references are converted to refer to the address of the | |||
// function jump tables. | // function jump tables. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H | #ifndef LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H | |||
#define LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H | #define LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H | |||
#include <vector> | ||||
#include <cassert> | #include <cassert> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
class DataLayout; | class DataLayout; | |||
class raw_ostream; | class raw_ostream; | |||
/// MachineJumpTableEntry - One jump table in the jump table info. | /// MachineJumpTableEntry - One jump table in the jump table info. | |||
/// | /// | |||
struct MachineJumpTableEntry { | struct MachineJumpTableEntry { | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
MachineLocation.h | MachineLocation.h | |||
---|---|---|---|---|
skipping to change at line 12 | skipping to change at line 12 | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// The MachineLocation class is used to represent a simple location in a ma chine | // The MachineLocation class is used to represent a simple location in a ma chine | |||
// frame. Locations will be one of two forms; a register or an address for med | // frame. Locations will be one of two forms; a register or an address for med | |||
// from a base address plus an offset. Register indirection can be specifi ed by | // from a base address plus an offset. Register indirection can be specifi ed by | |||
// using an offset of zero. | // explicitly passing an offset to the constructor. | |||
// | // | |||
// The MachineMove class is used to represent abstract move operations in t he | // The MachineMove class is used to represent abstract move operations in t he | |||
// prolog/epilog of a compiled function. A collection of these objects can be | // prolog/epilog of a compiled function. A collection of these objects can be | |||
// used by a debug consumer to track the location of values when unwinding stack | // used by a debug consumer to track the location of values when unwinding stack | |||
// frames. | // frames. | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_MACHINELOCATION_H | #ifndef LLVM_MC_MACHINELOCATION_H | |||
#define LLVM_MC_MACHINELOCATION_H | #define LLVM_MC_MACHINELOCATION_H | |||
skipping to change at line 39 | skipping to change at line 39 | |||
unsigned Register; // gcc/gdb register number. | unsigned Register; // gcc/gdb register number. | |||
int Offset; // Displacement if not register. | int Offset; // Displacement if not register. | |||
public: | public: | |||
enum { | enum { | |||
// The target register number for an abstract frame pointer. The value is | // The target register number for an abstract frame pointer. The value is | |||
// an arbitrary value that doesn't collide with any real target registe r. | // an arbitrary value that doesn't collide with any real target registe r. | |||
VirtualFP = ~0U | VirtualFP = ~0U | |||
}; | }; | |||
MachineLocation() | MachineLocation() | |||
: IsRegister(false), Register(0), Offset(0) {} | : IsRegister(false), Register(0), Offset(0) {} | |||
/// Create a direct register location. | ||||
explicit MachineLocation(unsigned R) | explicit MachineLocation(unsigned R) | |||
: IsRegister(true), Register(R), Offset(0) {} | : IsRegister(true), Register(R), Offset(0) {} | |||
/// Create a register-indirect location with an offset. | ||||
MachineLocation(unsigned R, int O) | MachineLocation(unsigned R, int O) | |||
: IsRegister(false), Register(R), Offset(O) {} | : IsRegister(false), Register(R), Offset(O) {} | |||
bool operator==(const MachineLocation &Other) const { | bool operator==(const MachineLocation &Other) const { | |||
return IsRegister == Other.IsRegister && Register == Other.Register & & | return IsRegister == Other.IsRegister && Register == Other.Register & & | |||
Offset == Other.Offset; | Offset == Other.Offset; | |||
} | } | |||
// Accessors | // Accessors | |||
bool isIndirect() const { return !IsRegister; } | ||||
bool isReg() const { return IsRegister; } | bool isReg() const { return IsRegister; } | |||
unsigned getReg() const { return Register; } | unsigned getReg() const { return Register; } | |||
int getOffset() const { return Offset; } | int getOffset() const { return Offset; } | |||
void setIsRegister(bool Is) { IsRegister = Is; } | void setIsRegister(bool Is) { IsRegister = Is; } | |||
void setRegister(unsigned R) { Register = R; } | void setRegister(unsigned R) { Register = R; } | |||
void setOffset(int O) { Offset = O; } | void setOffset(int O) { Offset = O; } | |||
/// Make this location a direct register location. | ||||
void set(unsigned R) { | void set(unsigned R) { | |||
IsRegister = true; | IsRegister = true; | |||
Register = R; | Register = R; | |||
Offset = 0; | Offset = 0; | |||
} | } | |||
/// Make this location a register-indirect+offset location. | ||||
void set(unsigned R, int O) { | void set(unsigned R, int O) { | |||
IsRegister = false; | IsRegister = false; | |||
Register = R; | Register = R; | |||
Offset = O; | Offset = O; | |||
} | } | |||
#ifndef NDEBUG | #ifndef NDEBUG | |||
void dump(); | void dump(); | |||
#endif | #endif | |||
}; | }; | |||
End of changes. 6 change blocks. | ||||
1 lines changed or deleted | 6 lines changed or added | |||
MachineLoopInfo.h | MachineLoopInfo.h | |||
---|---|---|---|---|
skipping to change at line 30 | skipping to change at line 30 | |||
// * whether there is a preheader for the loop | // * whether there is a preheader for the loop | |||
// * the number of back edges to the header | // * the number of back edges to the header | |||
// * whether or not a particular block branches out of the loop | // * whether or not a particular block branches out of the loop | |||
// * the successor blocks of the loop | // * the successor blocks of the loop | |||
// * the loop depth | // * the loop depth | |||
// * the trip count | // * the trip count | |||
// * etc... | // * etc... | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINE_LOOP_INFO_H | #ifndef LLVM_CODEGEN_MACHINELOOPINFO_H | |||
#define LLVM_CODEGEN_MACHINE_LOOP_INFO_H | #define LLVM_CODEGEN_MACHINELOOPINFO_H | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | ||||
#include "llvm/Analysis/LoopInfo.h" | #include "llvm/Analysis/LoopInfo.h" | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | ||||
namespace llvm { | namespace llvm { | |||
// Implementation in LoopInfoImpl.h | // Implementation in LoopInfoImpl.h | |||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
class MachineLoop; | class MachineLoop; | |||
__extension__ extern template class LoopBase<MachineBasicBlock, MachineLoop >; | __extension__ extern template class LoopBase<MachineBasicBlock, MachineLoop >; | |||
#endif | #endif | |||
class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> { | class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> { | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
MachineMemOperand.h | MachineMemOperand.h | |||
---|---|---|---|---|
skipping to change at line 101 | skipping to change at line 101 | |||
/// The memory access reads data. | /// The memory access reads data. | |||
MOLoad = 1, | MOLoad = 1, | |||
/// The memory access writes data. | /// The memory access writes data. | |||
MOStore = 2, | MOStore = 2, | |||
/// The memory access is volatile. | /// The memory access is volatile. | |||
MOVolatile = 4, | MOVolatile = 4, | |||
/// The memory access is non-temporal. | /// The memory access is non-temporal. | |||
MONonTemporal = 8, | MONonTemporal = 8, | |||
/// The memory access is invariant. | /// The memory access is invariant. | |||
MOInvariant = 16, | MOInvariant = 16, | |||
// Target hints allow target passes to annotate memory operations. | ||||
MOTargetStartBit = 5, | ||||
MOTargetNumBits = 3, | ||||
// This is the number of bits we need to represent flags. | // This is the number of bits we need to represent flags. | |||
MOMaxBits = 5 | MOMaxBits = 8 | |||
}; | }; | |||
/// MachineMemOperand - Construct an MachineMemOperand object with the | /// MachineMemOperand - Construct an MachineMemOperand object with the | |||
/// specified PtrInfo, flags, size, and base alignment. | /// specified PtrInfo, flags, size, and base alignment. | |||
MachineMemOperand(MachinePointerInfo PtrInfo, unsigned flags, uint64_t s, | MachineMemOperand(MachinePointerInfo PtrInfo, unsigned flags, uint64_t s, | |||
unsigned base_alignment, const MDNode *TBAAInfo = 0, | unsigned base_alignment, const MDNode *TBAAInfo = 0, | |||
const MDNode *Ranges = 0); | const MDNode *Ranges = 0); | |||
const MachinePointerInfo &getPointerInfo() const { return PtrInfo; } | const MachinePointerInfo &getPointerInfo() const { return PtrInfo; } | |||
skipping to change at line 125 | skipping to change at line 128 | |||
/// Special values are those obtained via | /// Special values are those obtained via | |||
/// PseudoSourceValue::getFixedStack(int), PseudoSourceValue::getStack, a nd | /// PseudoSourceValue::getFixedStack(int), PseudoSourceValue::getStack, a nd | |||
/// other PseudoSourceValue member functions which return objects which s tand | /// other PseudoSourceValue member functions which return objects which s tand | |||
/// for frame/stack pointer relative references and other special referen ces | /// for frame/stack pointer relative references and other special referen ces | |||
/// which are not representable in the high-level IR. | /// which are not representable in the high-level IR. | |||
const Value *getValue() const { return PtrInfo.V; } | const Value *getValue() const { return PtrInfo.V; } | |||
/// getFlags - Return the raw flags of the source value, \see MemOperandF lags. | /// getFlags - Return the raw flags of the source value, \see MemOperandF lags. | |||
unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); } | unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); } | |||
/// Bitwise OR the current flags with the given flags. | ||||
void setFlags(unsigned f) { Flags |= (f & ((1 << MOMaxBits) - 1)); } | ||||
/// getOffset - For normal values, this is a byte offset added to the bas e | /// getOffset - For normal values, this is a byte offset added to the bas e | |||
/// address. For PseudoSourceValue::FPRel values, this is the FrameIndex | /// address. For PseudoSourceValue::FPRel values, this is the FrameIndex | |||
/// number. | /// number. | |||
int64_t getOffset() const { return PtrInfo.Offset; } | int64_t getOffset() const { return PtrInfo.Offset; } | |||
/// getSize - Return the size in bytes of the memory reference. | /// getSize - Return the size in bytes of the memory reference. | |||
uint64_t getSize() const { return Size; } | uint64_t getSize() const { return Size; } | |||
/// getAlignment - Return the minimum known alignment in bytes of the | /// getAlignment - Return the minimum known alignment in bytes of the | |||
/// actual memory reference. | /// actual memory reference. | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 7 lines changed or added | |||
MachineModuleInfo.h | MachineModuleInfo.h | |||
---|---|---|---|---|
skipping to change at line 34 | skipping to change at line 34 | |||
// -- Source line correspondence - A vector of file ID, line#, column# tri ples. | // -- Source line correspondence - A vector of file ID, line#, column# tri ples. | |||
// A DEBUG_LOCATION instruction is generated by the DAG Legalizer | // A DEBUG_LOCATION instruction is generated by the DAG Legalizer | |||
// corresponding to each entry in the source line list. This allows a debug | // corresponding to each entry in the source line list. This allows a debug | |||
// emitter to generate labels referenced by debug information tables. | // emitter to generate labels referenced by debug information tables. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H | #ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H | |||
#define LLVM_CODEGEN_MACHINEMODULEINFO_H | #define LLVM_CODEGEN_MACHINEMODULEINFO_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/GlobalValue.h" | ||||
#include "llvm/Metadata.h" | ||||
#include "llvm/MC/MachineLocation.h" | ||||
#include "llvm/MC/MCContext.h" | ||||
#include "llvm/Support/Dwarf.h" | ||||
#include "llvm/Support/DebugLoc.h" | ||||
#include "llvm/Support/ValueHandle.h" | ||||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/IR/Metadata.h" | ||||
#include "llvm/MC/MCContext.h" | ||||
#include "llvm/MC/MachineLocation.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/Support/DebugLoc.h" | ||||
#include "llvm/Support/Dwarf.h" | ||||
#include "llvm/Support/ValueHandle.h" | ||||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Forward declarations. | // Forward declarations. | |||
class Constant; | class Constant; | |||
class GlobalVariable; | class GlobalVariable; | |||
class MDNode; | class MDNode; | |||
class MMIAddrLabelMap; | class MMIAddrLabelMap; | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
skipping to change at line 183 | skipping to change at line 182 | |||
typedef SmallVector<std::pair<TrackingVH<MDNode>, UnsignedDebugLocPair>, 4> | typedef SmallVector<std::pair<TrackingVH<MDNode>, UnsignedDebugLocPair>, 4> | |||
VariableDbgInfoMapTy; | VariableDbgInfoMapTy; | |||
VariableDbgInfoMapTy VariableDbgInfo; | VariableDbgInfoMapTy VariableDbgInfo; | |||
MachineModuleInfo(); // DUMMY CONSTRUCTOR, DO NOT CALL. | MachineModuleInfo(); // DUMMY CONSTRUCTOR, DO NOT CALL. | |||
// Real constructor. | // Real constructor. | |||
MachineModuleInfo(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, | MachineModuleInfo(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, | |||
const MCObjectFileInfo *MOFI); | const MCObjectFileInfo *MOFI); | |||
~MachineModuleInfo(); | ~MachineModuleInfo(); | |||
bool doInitialization(); | // Initialization and Finalization | |||
bool doFinalization(); | virtual bool doInitialization(Module &); | |||
virtual bool doFinalization(Module &); | ||||
/// EndFunction - Discard function meta information. | /// EndFunction - Discard function meta information. | |||
/// | /// | |||
void EndFunction(); | void EndFunction(); | |||
const MCContext &getContext() const { return Context; } | const MCContext &getContext() const { return Context; } | |||
MCContext &getContext() { return Context; } | MCContext &getContext() { return Context; } | |||
void setModule(const Module *M) { TheModule = M; } | void setModule(const Module *M) { TheModule = M; } | |||
const Module *getModule() const { return TheModule; } | const Module *getModule() const { return TheModule; } | |||
skipping to change at line 297 | skipping to change at line 297 | |||
unsigned getPersonalityIndex() const; | unsigned getPersonalityIndex() const; | |||
/// getPersonalities - Return array of personality functions ever seen. | /// getPersonalities - Return array of personality functions ever seen. | |||
const std::vector<const Function *>& getPersonalities() const { | const std::vector<const Function *>& getPersonalities() const { | |||
return Personalities; | return Personalities; | |||
} | } | |||
/// isUsedFunction - Return true if the functions in the llvm.used list. This | /// isUsedFunction - Return true if the functions in the llvm.used list. This | |||
/// does not return true for things in llvm.compiler.used unless they are also | /// does not return true for things in llvm.compiler.used unless they are also | |||
/// in llvm.used. | /// in llvm.used. | |||
bool isUsedFunction(const Function *F) { | bool isUsedFunction(const Function *F) const { | |||
return UsedFunctions.count(F); | return UsedFunctions.count(F); | |||
} | } | |||
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. | /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. | |||
/// | /// | |||
void addCatchTypeInfo(MachineBasicBlock *LandingPad, | void addCatchTypeInfo(MachineBasicBlock *LandingPad, | |||
ArrayRef<const GlobalVariable *> TyInfo); | ArrayRef<const GlobalVariable *> TyInfo); | |||
/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad. | /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad. | |||
/// | /// | |||
skipping to change at line 374 | skipping to change at line 374 | |||
/// number associated with it. | /// number associated with it. | |||
bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) { | bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) { | |||
return CallSiteMap[BeginLabel] != 0; | return CallSiteMap[BeginLabel] != 0; | |||
} | } | |||
/// setCurrentCallSite - Set the call site currently being processed. | /// setCurrentCallSite - Set the call site currently being processed. | |||
void setCurrentCallSite(unsigned Site) { CurCallSite = Site; } | void setCurrentCallSite(unsigned Site) { CurCallSite = Site; } | |||
/// getCurrentCallSite - Get the call site currently being processed, if any. | /// getCurrentCallSite - Get the call site currently being processed, if any. | |||
/// return zero if none. | /// return zero if none. | |||
unsigned getCurrentCallSite(void) { return CurCallSite; } | unsigned getCurrentCallSite() { return CurCallSite; } | |||
/// getTypeInfos - Return a reference to the C++ typeinfo for the current | /// getTypeInfos - Return a reference to the C++ typeinfo for the current | |||
/// function. | /// function. | |||
const std::vector<const GlobalVariable *> &getTypeInfos() const { | const std::vector<const GlobalVariable *> &getTypeInfos() const { | |||
return TypeInfos; | return TypeInfos; | |||
} | } | |||
/// getFilterIds - Return a reference to the typeids encoding filters use d in | /// getFilterIds - Return a reference to the typeids encoding filters use d in | |||
/// the current function. | /// the current function. | |||
const std::vector<unsigned> &getFilterIds() const { | const std::vector<unsigned> &getFilterIds() const { | |||
End of changes. 5 change blocks. | ||||
13 lines changed or deleted | 13 lines changed or added | |||
MachineOperand.h | MachineOperand.h | |||
---|---|---|---|---|
skipping to change at line 38 | skipping to change at line 38 | |||
class MachineRegisterInfo; | class MachineRegisterInfo; | |||
class MDNode; | class MDNode; | |||
class TargetMachine; | class TargetMachine; | |||
class TargetRegisterInfo; | class TargetRegisterInfo; | |||
class hash_code; | class hash_code; | |||
class raw_ostream; | class raw_ostream; | |||
class MCSymbol; | class MCSymbol; | |||
/// MachineOperand class - Representation of each machine instruction opera nd. | /// MachineOperand class - Representation of each machine instruction opera nd. | |||
/// | /// | |||
/// This class isn't a POD type because it has a private constructor, but i | ||||
ts | ||||
/// destructor must be trivial. Functions like MachineInstr::addOperand(), | ||||
/// MachineRegisterInfo::moveOperands(), and MF::DeleteMachineInstr() depen | ||||
d on | ||||
/// not having to call the MachineOperand destructor. | ||||
/// | ||||
class MachineOperand { | class MachineOperand { | |||
public: | public: | |||
enum MachineOperandType { | enum MachineOperandType { | |||
MO_Register, ///< Register operand. | MO_Register, ///< Register operand. | |||
MO_Immediate, ///< Immediate operand | MO_Immediate, ///< Immediate operand | |||
MO_CImmediate, ///< Immediate >64bit operand | MO_CImmediate, ///< Immediate >64bit operand | |||
MO_FPImmediate, ///< Floating-point immediate operand | MO_FPImmediate, ///< Floating-point immediate operand | |||
MO_MachineBasicBlock, ///< MachineBasicBlock reference | MO_MachineBasicBlock, ///< MachineBasicBlock reference | |||
MO_FrameIndex, ///< Abstract Stack Frame Index | MO_FrameIndex, ///< Abstract Stack Frame Index | |||
MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool | MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool | |||
skipping to change at line 63 | skipping to change at line 68 | |||
MO_RegisterMask, ///< Mask of preserved registers. | MO_RegisterMask, ///< Mask of preserved registers. | |||
MO_Metadata, ///< Metadata reference (for debug info) | MO_Metadata, ///< Metadata reference (for debug info) | |||
MO_MCSymbol ///< MCSymbol reference (for debug/eh info) | MO_MCSymbol ///< MCSymbol reference (for debug/eh info) | |||
}; | }; | |||
private: | private: | |||
/// OpKind - Specify what kind of operand this is. This discriminates th e | /// OpKind - Specify what kind of operand this is. This discriminates th e | |||
/// union. | /// union. | |||
unsigned char OpKind; // MachineOperandType | unsigned char OpKind; // MachineOperandType | |||
// This union is discriminated by OpKind. | /// Subregister number for MO_Register. A value of 0 indicates the | |||
union { | /// MO_Register has no subReg. | |||
/// SubReg - Subregister number, only valid for MO_Register. A value o | /// | |||
f 0 | /// For all other kinds of operands, this field holds target-specific fla | |||
/// indicates the MO_Register has no subReg. | gs. | |||
unsigned char SubReg; | unsigned SubReg_TargetFlags : 12; | |||
/// TargetFlags - This is a set of target-specific operand flags. | ||||
unsigned char TargetFlags; | ||||
}; | ||||
/// TiedTo - Non-zero when this register operand is tied to another regis ter | /// TiedTo - Non-zero when this register operand is tied to another regis ter | |||
/// operand. The encoding of this field is described in the block comment | /// operand. The encoding of this field is described in the block comment | |||
/// before MachineInstr::tieOperands(). | /// before MachineInstr::tieOperands(). | |||
unsigned char TiedTo : 4; | unsigned char TiedTo : 4; | |||
/// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Registe r | /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Registe r | |||
/// operands. | /// operands. | |||
/// IsDef - True if this is a def, false if this is a use of the register . | /// IsDef - True if this is a def, false if this is a use of the register . | |||
skipping to change at line 179 | skipping to change at line 180 | |||
int Index; // For MO_*Index - The index itself. | int Index; // For MO_*Index - The index itself. | |||
const char *SymbolName; // For MO_ExternalSymbol. | const char *SymbolName; // For MO_ExternalSymbol. | |||
const GlobalValue *GV; // For MO_GlobalAddress. | const GlobalValue *GV; // For MO_GlobalAddress. | |||
const BlockAddress *BA; // For MO_BlockAddress. | const BlockAddress *BA; // For MO_BlockAddress. | |||
} Val; | } Val; | |||
// Low bits of offset are in SmallContents.OffsetLo. | // Low bits of offset are in SmallContents.OffsetLo. | |||
int OffsetHi; // An offset from the object, high 32 bit s. | int OffsetHi; // An offset from the object, high 32 bit s. | |||
} OffsetedInfo; | } OffsetedInfo; | |||
} Contents; | } Contents; | |||
explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) { | explicit MachineOperand(MachineOperandType K) | |||
TargetFlags = 0; | : OpKind(K), SubReg_TargetFlags(0), ParentMI(0) {} | |||
} | ||||
public: | public: | |||
/// getType - Returns the MachineOperandType for this operand. | /// getType - Returns the MachineOperandType for this operand. | |||
/// | /// | |||
MachineOperandType getType() const { return (MachineOperandType)OpKind; } | MachineOperandType getType() const { return (MachineOperandType)OpKind; } | |||
unsigned char getTargetFlags() const { | unsigned getTargetFlags() const { | |||
return isReg() ? 0 : TargetFlags; | return isReg() ? 0 : SubReg_TargetFlags; | |||
} | } | |||
void setTargetFlags(unsigned char F) { | void setTargetFlags(unsigned F) { | |||
assert(!isReg() && "Register operands can't have target flags"); | assert(!isReg() && "Register operands can't have target flags"); | |||
TargetFlags = F; | SubReg_TargetFlags = F; | |||
assert(SubReg_TargetFlags == F && "Target flags out of range"); | ||||
} | } | |||
void addTargetFlag(unsigned char F) { | void addTargetFlag(unsigned F) { | |||
assert(!isReg() && "Register operands can't have target flags"); | assert(!isReg() && "Register operands can't have target flags"); | |||
TargetFlags |= F; | SubReg_TargetFlags |= F; | |||
assert((SubReg_TargetFlags & F) && "Target flags out of range"); | ||||
} | } | |||
/// getParent - Return the instruction that this operand belongs to. | /// getParent - Return the instruction that this operand belongs to. | |||
/// | /// | |||
MachineInstr *getParent() { return ParentMI; } | MachineInstr *getParent() { return ParentMI; } | |||
const MachineInstr *getParent() const { return ParentMI; } | const MachineInstr *getParent() const { return ParentMI; } | |||
/// clearParent - Reset the parent pointer. | /// clearParent - Reset the parent pointer. | |||
/// | /// | |||
/// The MachineOperand copy constructor also copies ParentMI, expecting t he | /// The MachineOperand copy constructor also copies ParentMI, expecting t he | |||
skipping to change at line 262 | skipping to change at line 264 | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// getReg - Returns the register number. | /// getReg - Returns the register number. | |||
unsigned getReg() const { | unsigned getReg() const { | |||
assert(isReg() && "This is not a register operand!"); | assert(isReg() && "This is not a register operand!"); | |||
return SmallContents.RegNo; | return SmallContents.RegNo; | |||
} | } | |||
unsigned getSubReg() const { | unsigned getSubReg() const { | |||
assert(isReg() && "Wrong MachineOperand accessor"); | assert(isReg() && "Wrong MachineOperand accessor"); | |||
return (unsigned)SubReg; | return SubReg_TargetFlags; | |||
} | } | |||
bool isUse() const { | bool isUse() const { | |||
assert(isReg() && "Wrong MachineOperand accessor"); | assert(isReg() && "Wrong MachineOperand accessor"); | |||
return !IsDef; | return !IsDef; | |||
} | } | |||
bool isDef() const { | bool isDef() const { | |||
assert(isReg() && "Wrong MachineOperand accessor"); | assert(isReg() && "Wrong MachineOperand accessor"); | |||
return IsDef; | return IsDef; | |||
skipping to change at line 337 | skipping to change at line 339 | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Mutators for Register Operands | // Mutators for Register Operands | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// Change the register this operand corresponds to. | /// Change the register this operand corresponds to. | |||
/// | /// | |||
void setReg(unsigned Reg); | void setReg(unsigned Reg); | |||
void setSubReg(unsigned subReg) { | void setSubReg(unsigned subReg) { | |||
assert(isReg() && "Wrong MachineOperand accessor"); | assert(isReg() && "Wrong MachineOperand accessor"); | |||
SubReg = (unsigned char)subReg; | SubReg_TargetFlags = subReg; | |||
assert(SubReg_TargetFlags == subReg && "SubReg out of range"); | ||||
} | } | |||
/// substVirtReg - Substitute the current register with the virtual | /// substVirtReg - Substitute the current register with the virtual | |||
/// subregister Reg:SubReg. Take any existing SubReg index into account, | /// subregister Reg:SubReg. Take any existing SubReg index into account, | |||
/// using TargetRegisterInfo to compose the subreg indices if necessary. | /// using TargetRegisterInfo to compose the subreg indices if necessary. | |||
/// Reg must be a virtual register, SubIdx can be 0. | /// Reg must be a virtual register, SubIdx can be 0. | |||
/// | /// | |||
void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo &); | void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo &); | |||
/// substPhysReg - Substitute the current register with the physical regi ster | /// substPhysReg - Substitute the current register with the physical regi ster | |||
skipping to change at line 575 | skipping to change at line 578 | |||
Op.IsKill = isKill; | Op.IsKill = isKill; | |||
Op.IsDead = isDead; | Op.IsDead = isDead; | |||
Op.IsUndef = isUndef; | Op.IsUndef = isUndef; | |||
Op.IsInternalRead = isInternalRead; | Op.IsInternalRead = isInternalRead; | |||
Op.IsEarlyClobber = isEarlyClobber; | Op.IsEarlyClobber = isEarlyClobber; | |||
Op.TiedTo = 0; | Op.TiedTo = 0; | |||
Op.IsDebug = isDebug; | Op.IsDebug = isDebug; | |||
Op.SmallContents.RegNo = Reg; | Op.SmallContents.RegNo = Reg; | |||
Op.Contents.Reg.Prev = 0; | Op.Contents.Reg.Prev = 0; | |||
Op.Contents.Reg.Next = 0; | Op.Contents.Reg.Next = 0; | |||
Op.SubReg = SubReg; | Op.setSubReg(SubReg); | |||
return Op; | return Op; | |||
} | } | |||
static MachineOperand CreateMBB(MachineBasicBlock *MBB, | static MachineOperand CreateMBB(MachineBasicBlock *MBB, | |||
unsigned char TargetFlags = 0) { | unsigned char TargetFlags = 0) { | |||
MachineOperand Op(MachineOperand::MO_MachineBasicBlock); | MachineOperand Op(MachineOperand::MO_MachineBasicBlock); | |||
Op.setMBB(MBB); | Op.setMBB(MBB); | |||
Op.setTargetFlags(TargetFlags); | Op.setTargetFlags(TargetFlags); | |||
return Op; | return Op; | |||
} | } | |||
static MachineOperand CreateFI(int Idx) { | static MachineOperand CreateFI(int Idx) { | |||
End of changes. 11 change blocks. | ||||
22 lines changed or deleted | 27 lines changed or added | |||
MachinePostDominators.h | MachinePostDominators.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file exposes interfaces to post dominance information for | // This file exposes interfaces to post dominance information for | |||
// target-specific code. | // target-specific code. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H | #ifndef LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H | |||
#define LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H | #define LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | ||||
#include "llvm/CodeGen/MachineDominators.h" | ||||
#include "llvm/Analysis/Dominators.h" | #include "llvm/Analysis/Dominators.h" | |||
#include "llvm/Analysis/DominatorInternals.h" | #include "llvm/CodeGen/MachineDominators.h" | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | ||||
namespace llvm { | namespace llvm { | |||
/// | /// | |||
/// PostDominatorTree Class - Concrete subclass of DominatorTree that is us ed | /// PostDominatorTree Class - Concrete subclass of DominatorTree that is us ed | |||
/// to compute the a post-dominator tree. | /// to compute the a post-dominator tree. | |||
/// | /// | |||
struct MachinePostDominatorTree : public MachineFunctionPass { | struct MachinePostDominatorTree : public MachineFunctionPass { | |||
private: | private: | |||
DominatorTreeBase<MachineBasicBlock> *DT; | DominatorTreeBase<MachineBasicBlock> *DT; | |||
skipping to change at line 58 | skipping to change at line 57 | |||
} | } | |||
MachineDomTreeNode *operator[](MachineBasicBlock *BB) const { | MachineDomTreeNode *operator[](MachineBasicBlock *BB) const { | |||
return DT->getNode(BB); | return DT->getNode(BB); | |||
} | } | |||
MachineDomTreeNode *getNode(MachineBasicBlock *BB) const { | MachineDomTreeNode *getNode(MachineBasicBlock *BB) const { | |||
return DT->getNode(BB); | return DT->getNode(BB); | |||
} | } | |||
bool dominates(MachineDomTreeNode *A, MachineDomTreeNode *B) const { | bool dominates(const MachineDomTreeNode *A, | |||
const MachineDomTreeNode *B) const { | ||||
return DT->dominates(A, B); | return DT->dominates(A, B); | |||
} | } | |||
bool dominates(MachineBasicBlock *A, MachineBasicBlock *B) const { | bool dominates(const MachineBasicBlock *A, const MachineBasicBlock *B) co nst { | |||
return DT->dominates(A, B); | return DT->dominates(A, B); | |||
} | } | |||
bool | bool properlyDominates(const MachineDomTreeNode *A, | |||
properlyDominates(const MachineDomTreeNode *A, MachineDomTreeNode *B) con | const MachineDomTreeNode *B) const { | |||
st { | ||||
return DT->properlyDominates(A, B); | return DT->properlyDominates(A, B); | |||
} | } | |||
bool | bool properlyDominates(const MachineBasicBlock *A, | |||
properlyDominates(MachineBasicBlock *A, MachineBasicBlock *B) const { | const MachineBasicBlock *B) const { | |||
return DT->properlyDominates(A, B); | return DT->properlyDominates(A, B); | |||
} | } | |||
MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A, | MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A, | |||
MachineBasicBlock *B ) { | MachineBasicBlock *B) { | |||
return DT->findNearestCommonDominator(A, B); | return DT->findNearestCommonDominator(A, B); | |||
} | } | |||
virtual bool runOnMachineFunction(MachineFunction &MF); | virtual bool runOnMachineFunction(MachineFunction &MF); | |||
virtual void getAnalysisUsage(AnalysisUsage &AU) const; | virtual void getAnalysisUsage(AnalysisUsage &AU) const; | |||
virtual void print(llvm::raw_ostream &OS, const Module *M = 0) const; | virtual void print(llvm::raw_ostream &OS, const Module *M = 0) const; | |||
}; | }; | |||
} //end of namespace llvm | } //end of namespace llvm | |||
#endif | #endif | |||
End of changes. 7 change blocks. | ||||
11 lines changed or deleted | 10 lines changed or added | |||
MachineRegisterInfo.h | MachineRegisterInfo.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the MachineRegisterInfo class. | // This file defines the MachineRegisterInfo class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_MACHINEREGISTERINFO_H | #ifndef LLVM_CODEGEN_MACHINEREGISTERINFO_H | |||
#define LLVM_CODEGEN_MACHINEREGISTERINFO_H | #define LLVM_CODEGEN_MACHINEREGISTERINFO_H | |||
#include "llvm/Target/TargetRegisterInfo.h" | ||||
#include "llvm/CodeGen/MachineInstrBundle.h" | ||||
#include "llvm/ADT/BitVector.h" | #include "llvm/ADT/BitVector.h" | |||
#include "llvm/ADT/IndexedMap.h" | #include "llvm/ADT/IndexedMap.h" | |||
#include "llvm/CodeGen/MachineInstrBundle.h" | ||||
#include "llvm/Target/TargetRegisterInfo.h" | ||||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
/// MachineRegisterInfo - Keep track of information for virtual and physica l | /// MachineRegisterInfo - Keep track of information for virtual and physica l | |||
/// registers, including vreg register classes, use/def chains for register s, | /// registers, including vreg register classes, use/def chains for register s, | |||
/// etc. | /// etc. | |||
class MachineRegisterInfo { | class MachineRegisterInfo { | |||
const TargetRegisterInfo *const TRI; | const TargetRegisterInfo *const TRI; | |||
skipping to change at line 102 | skipping to change at line 102 | |||
/// It can model things that UsedRegUnits can't, such as function calls t hat | /// It can model things that UsedRegUnits can't, such as function calls t hat | |||
/// clobber ymm7 but preserve the low half in xmm7. | /// clobber ymm7 but preserve the low half in xmm7. | |||
BitVector UsedPhysRegMask; | BitVector UsedPhysRegMask; | |||
/// ReservedRegs - This is a bit vector of reserved registers. The targe t | /// ReservedRegs - This is a bit vector of reserved registers. The targe t | |||
/// may change its mind about which registers should be reserved. This | /// may change its mind about which registers should be reserved. This | |||
/// vector is the frozen set of reserved registers when register allocati on | /// vector is the frozen set of reserved registers when register allocati on | |||
/// started. | /// started. | |||
BitVector ReservedRegs; | BitVector ReservedRegs; | |||
/// LiveIns/LiveOuts - Keep track of the physical registers that are | /// Keep track of the physical registers that are live in to the function | |||
/// livein/liveout of the function. Live in values are typically argumen | . | |||
ts in | /// Live in values are typically arguments in registers. LiveIn values a | |||
/// registers, live out values are typically return values in registers. | re | |||
/// LiveIn values are allowed to have virtual registers associated with t | /// allowed to have virtual registers associated with them, stored in the | |||
hem, | /// second element. | |||
/// stored in the second element. | ||||
std::vector<std::pair<unsigned, unsigned> > LiveIns; | std::vector<std::pair<unsigned, unsigned> > LiveIns; | |||
std::vector<unsigned> LiveOuts; | ||||
MachineRegisterInfo(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION; | MachineRegisterInfo(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION; | |||
void operator=(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION; | void operator=(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
explicit MachineRegisterInfo(const TargetRegisterInfo &TRI); | explicit MachineRegisterInfo(const TargetRegisterInfo &TRI); | |||
~MachineRegisterInfo(); | ~MachineRegisterInfo(); | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Function State | // Function State | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
skipping to change at line 159 | skipping to change at line 157 | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Register Info | // Register Info | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Strictly for use by MachineInstr.cpp. | // Strictly for use by MachineInstr.cpp. | |||
void addRegOperandToUseList(MachineOperand *MO); | void addRegOperandToUseList(MachineOperand *MO); | |||
// Strictly for use by MachineInstr.cpp. | // Strictly for use by MachineInstr.cpp. | |||
void removeRegOperandFromUseList(MachineOperand *MO); | void removeRegOperandFromUseList(MachineOperand *MO); | |||
// Strictly for use by MachineInstr.cpp. | ||||
void moveOperands(MachineOperand *Dst, MachineOperand *Src, unsigned NumO | ||||
ps); | ||||
/// Verify the sanity of the use list for Reg. | ||||
void verifyUseList(unsigned Reg) const; | ||||
/// Verify the use list of all registers. | ||||
void verifyUseLists() const; | ||||
/// reg_begin/reg_end - Provide iteration support to walk over all defini tions | /// reg_begin/reg_end - Provide iteration support to walk over all defini tions | |||
/// and uses of a register within the MachineFunction that corresponds to this | /// and uses of a register within the MachineFunction that corresponds to this | |||
/// MachineRegisterInfo object. | /// MachineRegisterInfo object. | |||
template<bool Uses, bool Defs, bool SkipDebug> | template<bool Uses, bool Defs, bool SkipDebug> | |||
class defusechain_iterator; | class defusechain_iterator; | |||
// Make it a friend so it can access getNextOperandForReg(). | // Make it a friend so it can access getNextOperandForReg(). | |||
template<bool, bool, bool> friend class defusechain_iterator; | template<bool, bool, bool> friend class defusechain_iterator; | |||
/// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specif ied | /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specif ied | |||
skipping to change at line 378 | skipping to change at line 385 | |||
/// spilling. | /// spilling. | |||
bool isPhysRegUsed(unsigned Reg) const { | bool isPhysRegUsed(unsigned Reg) const { | |||
if (UsedPhysRegMask.test(Reg)) | if (UsedPhysRegMask.test(Reg)) | |||
return true; | return true; | |||
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) | for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) | |||
if (UsedRegUnits.test(*Units)) | if (UsedRegUnits.test(*Units)) | |||
return true; | return true; | |||
return false; | return false; | |||
} | } | |||
/// Mark the specified register unit as used in this function. | ||||
/// This should only be called during and after register allocation. | ||||
void setRegUnitUsed(unsigned RegUnit) { | ||||
UsedRegUnits.set(RegUnit); | ||||
} | ||||
/// setPhysRegUsed - Mark the specified register used in this function. | /// setPhysRegUsed - Mark the specified register used in this function. | |||
/// This should only be called during and after register allocation. | /// This should only be called during and after register allocation. | |||
void setPhysRegUsed(unsigned Reg) { | void setPhysRegUsed(unsigned Reg) { | |||
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) | for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) | |||
UsedRegUnits.set(*Units); | UsedRegUnits.set(*Units); | |||
} | } | |||
/// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as use d. | /// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as use d. | |||
/// This corresponds to the bit mask attached to register mask operands. | /// This corresponds to the bit mask attached to register mask operands. | |||
void addPhysRegsUsedFromRegMask(const uint32_t *RegMask) { | void addPhysRegsUsedFromRegMask(const uint32_t *RegMask) { | |||
skipping to change at line 458 | skipping to change at line 471 | |||
/// register class and it hasn't been reserved. | /// register class and it hasn't been reserved. | |||
/// | /// | |||
/// Allocatable registers may show up in the allocation order of some vir tual | /// Allocatable registers may show up in the allocation order of some vir tual | |||
/// register, so a register allocator needs to track its liveness and | /// register, so a register allocator needs to track its liveness and | |||
/// availability. | /// availability. | |||
bool isAllocatable(unsigned PhysReg) const { | bool isAllocatable(unsigned PhysReg) const { | |||
return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg); | return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg); | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// LiveIn/LiveOut Management | // LiveIn Management | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// addLiveIn/Out - Add the specified register as a live in/out. Note th at it | /// addLiveIn - Add the specified register as a live-in. Note that it | |||
/// is an error to add the same register to the same set more than once. | /// is an error to add the same register to the same set more than once. | |||
void addLiveIn(unsigned Reg, unsigned vreg = 0) { | void addLiveIn(unsigned Reg, unsigned vreg = 0) { | |||
LiveIns.push_back(std::make_pair(Reg, vreg)); | LiveIns.push_back(std::make_pair(Reg, vreg)); | |||
} | } | |||
void addLiveOut(unsigned Reg) { LiveOuts.push_back(Reg); } | ||||
// Iteration support for live in/out sets. These sets are kept in sorted | // Iteration support for the live-ins set. It's kept in sorted order | |||
// order by their register number. | // by register number. | |||
typedef std::vector<std::pair<unsigned,unsigned> >::const_iterator | typedef std::vector<std::pair<unsigned,unsigned> >::const_iterator | |||
livein_iterator; | livein_iterator; | |||
typedef std::vector<unsigned>::const_iterator liveout_iterator; | ||||
livein_iterator livein_begin() const { return LiveIns.begin(); } | livein_iterator livein_begin() const { return LiveIns.begin(); } | |||
livein_iterator livein_end() const { return LiveIns.end(); } | livein_iterator livein_end() const { return LiveIns.end(); } | |||
bool livein_empty() const { return LiveIns.empty(); } | bool livein_empty() const { return LiveIns.empty(); } | |||
liveout_iterator liveout_begin() const { return LiveOuts.begin(); } | ||||
liveout_iterator liveout_end() const { return LiveOuts.end(); } | ||||
bool liveout_empty() const { return LiveOuts.empty(); } | ||||
bool isLiveIn(unsigned Reg) const; | bool isLiveIn(unsigned Reg) const; | |||
bool isLiveOut(unsigned Reg) const; | ||||
/// getLiveInPhysReg - If VReg is a live-in virtual register, return the | /// getLiveInPhysReg - If VReg is a live-in virtual register, return the | |||
/// corresponding live-in physical register. | /// corresponding live-in physical register. | |||
unsigned getLiveInPhysReg(unsigned VReg) const; | unsigned getLiveInPhysReg(unsigned VReg) const; | |||
/// getLiveInVirtReg - If PReg is a live-in physical register, return the | /// getLiveInVirtReg - If PReg is a live-in physical register, return the | |||
/// corresponding live-in physical register. | /// corresponding live-in physical register. | |||
unsigned getLiveInVirtReg(unsigned PReg) const; | unsigned getLiveInVirtReg(unsigned PReg) const; | |||
/// EmitLiveInCopies - Emit copies to initialize livein virtual registers | /// EmitLiveInCopies - Emit copies to initialize livein virtual registers | |||
End of changes. 13 change blocks. | ||||
20 lines changed or deleted | 28 lines changed or added | |||
MachineScheduler.h | MachineScheduler.h | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
// static MachineSchedRegistry | // static MachineSchedRegistry | |||
// SchedCustomRegistry("custom", "Run my target's custom scheduler", | // SchedCustomRegistry("custom", "Run my target's custom scheduler", | |||
// createCustomMachineSched); | // createCustomMachineSched); | |||
// | // | |||
// Inside <Target>PassConfig: | // Inside <Target>PassConfig: | |||
// enablePass(&MachineSchedulerID); | // enablePass(&MachineSchedulerID); | |||
// MachineSchedRegistry::setDefault(createCustomMachineSched); | // MachineSchedRegistry::setDefault(createCustomMachineSched); | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef MACHINESCHEDULER_H | #ifndef LLVM_CODEGEN_MACHINESCHEDULER_H | |||
#define MACHINESCHEDULER_H | #define LLVM_CODEGEN_MACHINESCHEDULER_H | |||
#include "llvm/CodeGen/MachinePassRegistry.h" | #include "llvm/CodeGen/MachinePassRegistry.h" | |||
#include "llvm/CodeGen/RegisterPressure.h" | #include "llvm/CodeGen/RegisterPressure.h" | |||
#include "llvm/CodeGen/ScheduleDAGInstrs.h" | #include "llvm/CodeGen/ScheduleDAGInstrs.h" | |||
#include "llvm/Target/TargetInstrInfo.h" | #include "llvm/Target/TargetInstrInfo.h" | |||
namespace llvm { | namespace llvm { | |||
extern cl::opt<bool> ForceTopDown; | extern cl::opt<bool> ForceTopDown; | |||
extern cl::opt<bool> ForceBottomUp; | extern cl::opt<bool> ForceBottomUp; | |||
class AliasAnalysis; | class AliasAnalysis; | |||
class LiveIntervals; | class LiveIntervals; | |||
class MachineDominatorTree; | class MachineDominatorTree; | |||
class MachineLoopInfo; | class MachineLoopInfo; | |||
class RegisterClassInfo; | class RegisterClassInfo; | |||
class ScheduleDAGInstrs; | class ScheduleDAGInstrs; | |||
class SchedDFSResult; | ||||
/// MachineSchedContext provides enough context from the MachineScheduler p ass | /// MachineSchedContext provides enough context from the MachineScheduler p ass | |||
/// for the target to instantiate a scheduler. | /// for the target to instantiate a scheduler. | |||
struct MachineSchedContext { | struct MachineSchedContext { | |||
MachineFunction *MF; | MachineFunction *MF; | |||
const MachineLoopInfo *MLI; | const MachineLoopInfo *MLI; | |||
const MachineDominatorTree *MDT; | const MachineDominatorTree *MDT; | |||
const TargetPassConfig *PassConfig; | const TargetPassConfig *PassConfig; | |||
AliasAnalysis *AA; | AliasAnalysis *AA; | |||
LiveIntervals *LIS; | LiveIntervals *LIS; | |||
skipping to change at line 122 | skipping to change at line 123 | |||
/// Notify this strategy that all roots have been released (including tho se | /// Notify this strategy that all roots have been released (including tho se | |||
/// that depend on EntrySU or ExitSU). | /// that depend on EntrySU or ExitSU). | |||
virtual void registerRoots() {} | virtual void registerRoots() {} | |||
/// Pick the next node to schedule, or return NULL. Set IsTopNode to true to | /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to | |||
/// schedule the node at the top of the unscheduled region. Otherwise it will | /// schedule the node at the top of the unscheduled region. Otherwise it will | |||
/// be scheduled at the bottom. | /// be scheduled at the bottom. | |||
virtual SUnit *pickNode(bool &IsTopNode) = 0; | virtual SUnit *pickNode(bool &IsTopNode) = 0; | |||
/// \brief Scheduler callback to notify that a new subtree is scheduled. | ||||
virtual void scheduleTree(unsigned SubtreeID) {} | ||||
/// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an | /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an | |||
/// instruction and updated scheduled/remaining flags in the DAG nodes. | /// instruction and updated scheduled/remaining flags in the DAG nodes. | |||
virtual void schedNode(SUnit *SU, bool IsTopNode) = 0; | virtual void schedNode(SUnit *SU, bool IsTopNode) = 0; | |||
/// When all predecessor dependencies have been resolved, free this node for | /// When all predecessor dependencies have been resolved, free this node for | |||
/// top-down scheduling. | /// top-down scheduling. | |||
virtual void releaseTopNode(SUnit *SU) = 0; | virtual void releaseTopNode(SUnit *SU) = 0; | |||
/// When all successor dependencies have been resolved, free this node fo r | /// When all successor dependencies have been resolved, free this node fo r | |||
/// bottom-up scheduling. | /// bottom-up scheduling. | |||
virtual void releaseBottomNode(SUnit *SU) = 0; | virtual void releaseBottomNode(SUnit *SU) = 0; | |||
skipping to change at line 167 | skipping to change at line 171 | |||
void clear() { Queue.clear(); } | void clear() { Queue.clear(); } | |||
unsigned size() const { return Queue.size(); } | unsigned size() const { return Queue.size(); } | |||
typedef std::vector<SUnit*>::iterator iterator; | typedef std::vector<SUnit*>::iterator iterator; | |||
iterator begin() { return Queue.begin(); } | iterator begin() { return Queue.begin(); } | |||
iterator end() { return Queue.end(); } | iterator end() { return Queue.end(); } | |||
ArrayRef<SUnit*> elements() { return Queue; } | ||||
iterator find(SUnit *SU) { | iterator find(SUnit *SU) { | |||
return std::find(Queue.begin(), Queue.end(), SU); | return std::find(Queue.begin(), Queue.end(), SU); | |||
} | } | |||
void push(SUnit *SU) { | void push(SUnit *SU) { | |||
Queue.push_back(SU); | Queue.push_back(SU); | |||
SU->NodeQueueId |= ID; | SU->NodeQueueId |= ID; | |||
} | } | |||
iterator remove(iterator I) { | iterator remove(iterator I) { | |||
(*I)->NodeQueueId &= ~ID; | (*I)->NodeQueueId &= ~ID; | |||
*I = Queue.back(); | *I = Queue.back(); | |||
unsigned idx = I - Queue.begin(); | unsigned idx = I - Queue.begin(); | |||
Queue.pop_back(); | Queue.pop_back(); | |||
return Queue.begin() + idx; | return Queue.begin() + idx; | |||
} | } | |||
#ifndef NDEBUG | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | |||
void dump(); | void dump(); | |||
#endif | #endif | |||
}; | }; | |||
/// Mutate the DAG as a postpass after normal DAG building. | /// Mutate the DAG as a postpass after normal DAG building. | |||
class ScheduleDAGMutation { | class ScheduleDAGMutation { | |||
public: | public: | |||
virtual ~ScheduleDAGMutation() {} | virtual ~ScheduleDAGMutation() {} | |||
virtual void apply(ScheduleDAGMI *DAG) = 0; | virtual void apply(ScheduleDAGMI *DAG) = 0; | |||
}; | }; | |||
/// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules | /// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules | |||
/// machine instructions while updating LiveIntervals and tracking regpress ure. | /// machine instructions while updating LiveIntervals and tracking regpress ure. | |||
class ScheduleDAGMI : public ScheduleDAGInstrs { | class ScheduleDAGMI : public ScheduleDAGInstrs { | |||
protected: | protected: | |||
AliasAnalysis *AA; | AliasAnalysis *AA; | |||
RegisterClassInfo *RegClassInfo; | RegisterClassInfo *RegClassInfo; | |||
MachineSchedStrategy *SchedImpl; | MachineSchedStrategy *SchedImpl; | |||
/// Information about DAG subtrees. If DFSResult is NULL, then SchedulerT | ||||
rees | ||||
/// will be empty. | ||||
SchedDFSResult *DFSResult; | ||||
BitVector ScheduledTrees; | ||||
/// Topo - A topological ordering for SUnits which permits fast IsReachab | ||||
le | ||||
/// and similar queries. | ||||
ScheduleDAGTopologicalSort Topo; | ||||
/// Ordered list of DAG postprocessing steps. | /// Ordered list of DAG postprocessing steps. | |||
std::vector<ScheduleDAGMutation*> Mutations; | std::vector<ScheduleDAGMutation*> Mutations; | |||
MachineBasicBlock::iterator LiveRegionEnd; | MachineBasicBlock::iterator LiveRegionEnd; | |||
/// Register pressure in this region computed by buildSchedGraph. | /// Register pressure in this region computed by buildSchedGraph. | |||
IntervalPressure RegPressure; | IntervalPressure RegPressure; | |||
RegPressureTracker RPTracker; | RegPressureTracker RPTracker; | |||
/// List of pressure sets that exceed the target's pressure limit before | /// List of pressure sets that exceed the target's pressure limit before | |||
skipping to change at line 229 | skipping to change at line 244 | |||
/// The top of the unscheduled zone. | /// The top of the unscheduled zone. | |||
MachineBasicBlock::iterator CurrentTop; | MachineBasicBlock::iterator CurrentTop; | |||
IntervalPressure TopPressure; | IntervalPressure TopPressure; | |||
RegPressureTracker TopRPTracker; | RegPressureTracker TopRPTracker; | |||
/// The bottom of the unscheduled zone. | /// The bottom of the unscheduled zone. | |||
MachineBasicBlock::iterator CurrentBottom; | MachineBasicBlock::iterator CurrentBottom; | |||
IntervalPressure BotPressure; | IntervalPressure BotPressure; | |||
RegPressureTracker BotRPTracker; | RegPressureTracker BotRPTracker; | |||
/// Record the next node in a scheduled cluster. | ||||
const SUnit *NextClusterPred; | ||||
const SUnit *NextClusterSucc; | ||||
#ifndef NDEBUG | #ifndef NDEBUG | |||
/// The number of instructions scheduled so far. Used to cut off the | /// The number of instructions scheduled so far. Used to cut off the | |||
/// scheduler at the point determined by misched-cutoff. | /// scheduler at the point determined by misched-cutoff. | |||
unsigned NumInstrsScheduled; | unsigned NumInstrsScheduled; | |||
#endif | #endif | |||
public: | public: | |||
ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S): | ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S): | |||
ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS) , | ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS) , | |||
AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S), | AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S), DFSResult(0), | |||
RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure), | Topo(SUnits, &ExitSU), RPTracker(RegPressure), CurrentTop(), | |||
CurrentBottom(), BotRPTracker(BotPressure) { | TopRPTracker(TopPressure), CurrentBottom(), BotRPTracker(BotPressure), | |||
NextClusterPred(NULL), NextClusterSucc(NULL) { | ||||
#ifndef NDEBUG | #ifndef NDEBUG | |||
NumInstrsScheduled = 0; | NumInstrsScheduled = 0; | |||
#endif | #endif | |||
} | } | |||
virtual ~ScheduleDAGMI() { | virtual ~ScheduleDAGMI(); | |||
delete SchedImpl; | ||||
} | ||||
/// Add a postprocessing step to the DAG builder. | /// Add a postprocessing step to the DAG builder. | |||
/// Mutations are applied in the order that they are added after normal D AG | /// Mutations are applied in the order that they are added after normal D AG | |||
/// building and before MachineSchedStrategy initialization. | /// building and before MachineSchedStrategy initialization. | |||
/// | ||||
/// ScheduleDAGMI takes ownership of the Mutation object. | ||||
void addMutation(ScheduleDAGMutation *Mutation) { | void addMutation(ScheduleDAGMutation *Mutation) { | |||
Mutations.push_back(Mutation); | Mutations.push_back(Mutation); | |||
} | } | |||
/// \brief True if an edge can be added from PredSU to SuccSU without cre | ||||
ating | ||||
/// a cycle. | ||||
bool canAddEdge(SUnit *SuccSU, SUnit *PredSU); | ||||
/// \brief Add a DAG edge to the given SU with the given predecessor | ||||
/// dependence data. | ||||
/// | ||||
/// \returns true if the edge may be added without creating a cycle OR if | ||||
an | ||||
/// equivalent edge already existed (false indicates failure). | ||||
bool addEdge(SUnit *SuccSU, const SDep &PredDep); | ||||
MachineBasicBlock::iterator top() const { return CurrentTop; } | MachineBasicBlock::iterator top() const { return CurrentTop; } | |||
MachineBasicBlock::iterator bottom() const { return CurrentBottom; } | MachineBasicBlock::iterator bottom() const { return CurrentBottom; } | |||
/// Implement the ScheduleDAGInstrs interface for handling the next sched uling | /// Implement the ScheduleDAGInstrs interface for handling the next sched uling | |||
/// region. This covers all instructions in a block, while schedule() may only | /// region. This covers all instructions in a block, while schedule() may only | |||
/// cover a subset. | /// cover a subset. | |||
void enterRegion(MachineBasicBlock *bb, | void enterRegion(MachineBasicBlock *bb, | |||
MachineBasicBlock::iterator begin, | MachineBasicBlock::iterator begin, | |||
MachineBasicBlock::iterator end, | MachineBasicBlock::iterator end, | |||
unsigned endcount); | unsigned endcount); | |||
/// Implement ScheduleDAGInstrs interface for scheduling a sequence of | /// Implement ScheduleDAGInstrs interface for scheduling a sequence of | |||
/// reorderable instructions. | /// reorderable instructions. | |||
virtual void schedule(); | virtual void schedule(); | |||
/// Change the position of an instruction within the basic block and upda | ||||
te | ||||
/// live ranges and region boundary iterators. | ||||
void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator Insert | ||||
Pos); | ||||
/// Get current register pressure for the top scheduled instructions. | /// Get current register pressure for the top scheduled instructions. | |||
const IntervalPressure &getTopPressure() const { return TopPressure; } | const IntervalPressure &getTopPressure() const { return TopPressure; } | |||
const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; } | const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; } | |||
/// Get current register pressure for the bottom scheduled instructions. | /// Get current register pressure for the bottom scheduled instructions. | |||
const IntervalPressure &getBotPressure() const { return BotPressure; } | const IntervalPressure &getBotPressure() const { return BotPressure; } | |||
const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; } | const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; } | |||
/// Get register pressure for the entire scheduling region before schedul ing. | /// Get register pressure for the entire scheduling region before schedul ing. | |||
const IntervalPressure &getRegPressure() const { return RegPressure; } | const IntervalPressure &getRegPressure() const { return RegPressure; } | |||
const std::vector<PressureElement> &getRegionCriticalPSets() const { | const std::vector<PressureElement> &getRegionCriticalPSets() const { | |||
return RegionCriticalPSets; | return RegionCriticalPSets; | |||
} | } | |||
const SUnit *getNextClusterPred() const { return NextClusterPred; } | ||||
const SUnit *getNextClusterSucc() const { return NextClusterSucc; } | ||||
/// Compute a DFSResult after DAG building is complete, and before any | ||||
/// queue comparisons. | ||||
void computeDFSResult(); | ||||
/// Return a non-null DFS result if the scheduling strategy initialized i | ||||
t. | ||||
const SchedDFSResult *getDFSResult() const { return DFSResult; } | ||||
BitVector &getScheduledTrees() { return ScheduledTrees; } | ||||
void viewGraph(const Twine &Name, const Twine &Title) LLVM_OVERRIDE; | ||||
void viewGraph() LLVM_OVERRIDE; | ||||
protected: | protected: | |||
// Top-Level entry points for the schedule() driver... | // Top-Level entry points for the schedule() driver... | |||
/// Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracki ng | /// Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracki ng | |||
/// enabled. This sets up three trackers. RPTracker will cover the entire DAG | /// enabled. This sets up three trackers. RPTracker will cover the entire DAG | |||
/// region, TopTracker and BottomTracker will be initialized to the top a nd | /// region, TopTracker and BottomTracker will be initialized to the top a nd | |||
/// bottom of the DAG region without covereing any unscheduled instructio n. | /// bottom of the DAG region without covereing any unscheduled instructio n. | |||
void buildDAGWithRegPressure(); | void buildDAGWithRegPressure(); | |||
/// Apply each ScheduleDAGMutation step in order. This allows different | /// Apply each ScheduleDAGMutation step in order. This allows different | |||
/// instances of ScheduleDAGMI to perform custom DAG postprocessing. | /// instances of ScheduleDAGMI to perform custom DAG postprocessing. | |||
void postprocessDAG(); | void postprocessDAG(); | |||
/// Identify DAG roots and setup scheduler queues. | /// Release ExitSU predecessors and setup scheduler queues. | |||
void initQueues(); | void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots); | |||
/// Move an instruction and update register pressure. | /// Move an instruction and update register pressure. | |||
void scheduleMI(SUnit *SU, bool IsTopNode); | void scheduleMI(SUnit *SU, bool IsTopNode); | |||
/// Update scheduler DAG and queues after scheduling an instruction. | /// Update scheduler DAG and queues after scheduling an instruction. | |||
void updateQueues(SUnit *SU, bool IsTopNode); | void updateQueues(SUnit *SU, bool IsTopNode); | |||
/// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues. | /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues. | |||
void placeDebugValues(); | void placeDebugValues(); | |||
/// \brief dump the scheduled Sequence. | /// \brief dump the scheduled Sequence. | |||
void dumpSchedule() const; | void dumpSchedule() const; | |||
// Lesser helpers... | // Lesser helpers... | |||
void initRegPressure(); | void initRegPressure(); | |||
void updateScheduledPressure(std::vector<unsigned> NewMaxPressure); | void updateScheduledPressure(const std::vector<unsigned> &NewMaxPressure) ; | |||
void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator Insert Pos); | ||||
bool checkSchedLimit(); | bool checkSchedLimit(); | |||
void releaseRoots(); | void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots, | |||
SmallVectorImpl<SUnit*> &BotRoots); | ||||
void releaseSucc(SUnit *SU, SDep *SuccEdge); | void releaseSucc(SUnit *SU, SDep *SuccEdge); | |||
void releaseSuccessors(SUnit *SU); | void releaseSuccessors(SUnit *SU); | |||
void releasePred(SUnit *SU, SDep *PredEdge); | void releasePred(SUnit *SU, SDep *PredEdge); | |||
void releasePredecessors(SUnit *SU); | void releasePredecessors(SUnit *SU); | |||
}; | }; | |||
} // namespace llvm | } // namespace llvm | |||
#endif | #endif | |||
End of changes. 17 change blocks. | ||||
14 lines changed or deleted | 72 lines changed or added | |||
Mangler.h | Mangler.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// Unified name mangler for various backends. | // Unified name mangler for various backends. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_MANGLER_H | #ifndef LLVM_TARGET_MANGLER_H | |||
#define LLVM_SUPPORT_MANGLER_H | #define LLVM_TARGET_MANGLER_H | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
namespace llvm { | namespace llvm { | |||
class Twine; | class Twine; | |||
class GlobalValue; | class GlobalValue; | |||
template <typename T> class SmallVectorImpl; | template <typename T> class SmallVectorImpl; | |||
class MCContext; | class MCContext; | |||
class MCSymbol; | class MCSymbol; | |||
class DataLayout; | class DataLayout; | |||
skipping to change at line 72 | skipping to change at line 72 | |||
/// getNameWithPrefix - Fill OutName with the name of the appropriate pre fix | /// getNameWithPrefix - Fill OutName with the name of the appropriate pre fix | |||
/// and the specified name as the global variable name. GVName must not be | /// and the specified name as the global variable name. GVName must not be | |||
/// empty. | /// empty. | |||
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVNam e, | void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVNam e, | |||
ManglerPrefixTy PrefixTy = Mangler::Default); | ManglerPrefixTy PrefixTy = Mangler::Default); | |||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif // LLVM_SUPPORT_MANGLER_H | #endif // LLVM_TARGET_MANGLER_H | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
MapVector.h | MapVector.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// and 2 copies are kept, one for indexing in a DenseMap, one for iteration in | // and 2 copies are kept, one for indexing in a DenseMap, one for iteration in | |||
// a std::vector. | // a std::vector. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_MAPVECTOR_H | #ifndef LLVM_ADT_MAPVECTOR_H | |||
#define LLVM_ADT_MAPVECTOR_H | #define LLVM_ADT_MAPVECTOR_H | |||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/STLExtras.h" | ||||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
/// This class implements a map that also provides access to all stored val ues | /// This class implements a map that also provides access to all stored val ues | |||
/// in a deterministic order. The values are kept in a std::vector and the | /// in a deterministic order. The values are kept in a std::vector and the | |||
/// mapping is done with DenseMap from Keys to indexes in that vector. | /// mapping is done with DenseMap from Keys to indexes in that vector. | |||
template<typename KeyT, typename ValueT, | template<typename KeyT, typename ValueT, | |||
typename MapType = llvm::DenseMap<KeyT, unsigned>, | typename MapType = llvm::DenseMap<KeyT, unsigned>, | |||
typename VectorType = std::vector<std::pair<KeyT, ValueT> > > | typename VectorType = std::vector<std::pair<KeyT, ValueT> > > | |||
skipping to change at line 66 | skipping to change at line 67 | |||
} | } | |||
const_iterator end() const { | const_iterator end() const { | |||
return Vector.end(); | return Vector.end(); | |||
} | } | |||
bool empty() const { | bool empty() const { | |||
return Vector.empty(); | return Vector.empty(); | |||
} | } | |||
std::pair<KeyT, ValueT> &front() { return Vector.front(); } | ||||
const std::pair<KeyT, ValueT> &front() const { return Vector.front(); } | ||||
std::pair<KeyT, ValueT> &back() { return Vector.back(); } | ||||
const std::pair<KeyT, ValueT> &back() const { return Vector.back(); } | ||||
void clear() { | void clear() { | |||
Map.clear(); | Map.clear(); | |||
Vector.clear(); | Vector.clear(); | |||
} | } | |||
ValueT &operator[](const KeyT &Key) { | ValueT &operator[](const KeyT &Key) { | |||
std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0); | std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0); | |||
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair); | std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair); | |||
unsigned &I = Result.first->second; | unsigned &I = Result.first->second; | |||
if (Result.second) { | if (Result.second) { | |||
Vector.push_back(std::make_pair(Key, ValueT())); | Vector.push_back(std::make_pair(Key, ValueT())); | |||
I = Vector.size() - 1; | I = Vector.size() - 1; | |||
} | } | |||
return Vector[I].second; | return Vector[I].second; | |||
} | } | |||
ValueT lookup(const KeyT &Key) const { | ||||
typename MapType::const_iterator Pos = Map.find(Key); | ||||
return Pos == Map.end()? ValueT() : Vector[Pos->second].second; | ||||
} | ||||
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) { | ||||
std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0); | ||||
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair); | ||||
unsigned &I = Result.first->second; | ||||
if (Result.second) { | ||||
Vector.push_back(std::make_pair(KV.first, KV.second)); | ||||
I = Vector.size() - 1; | ||||
return std::make_pair(llvm::prior(end()), true); | ||||
} | ||||
return std::make_pair(begin() + I, false); | ||||
} | ||||
unsigned count(const KeyT &Key) const { | unsigned count(const KeyT &Key) const { | |||
typename MapType::const_iterator Pos = Map.find(Key); | typename MapType::const_iterator Pos = Map.find(Key); | |||
return Pos == Map.end()? 0 : 1; | return Pos == Map.end()? 0 : 1; | |||
} | } | |||
iterator find(const KeyT &Key) { | ||||
typename MapType::const_iterator Pos = Map.find(Key); | ||||
return Pos == Map.end()? Vector.end() : | ||||
(Vector.begin() + Pos->second); | ||||
} | ||||
const_iterator find(const KeyT &Key) const { | ||||
typename MapType::const_iterator Pos = Map.find(Key); | ||||
return Pos == Map.end()? Vector.end() : | ||||
(Vector.begin() + Pos->second); | ||||
} | ||||
/// \brief Remove the last element from the vector. | ||||
void pop_back() { | ||||
typename MapType::iterator Pos = Map.find(Vector.back().first); | ||||
Map.erase(Pos); | ||||
Vector.pop_back(); | ||||
} | ||||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
0 lines changed or deleted | 42 lines changed or added | |||
Math.h | Math.h | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_PBQP_MATH_H | #ifndef LLVM_CODEGEN_PBQP_MATH_H | |||
#define LLVM_CODEGEN_PBQP_MATH_H | #define LLVM_CODEGEN_PBQP_MATH_H | |||
#include <cassert> | ||||
#include <algorithm> | #include <algorithm> | |||
#include <cassert> | ||||
#include <functional> | #include <functional> | |||
namespace PBQP { | namespace PBQP { | |||
typedef float PBQPNum; | typedef float PBQPNum; | |||
/// \brief PBQP Vector class. | /// \brief PBQP Vector class. | |||
class Vector { | class Vector { | |||
public: | public: | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
MathExtras.h | MathExtras.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file contains some functions that are useful for math stuff. | // This file contains some functions that are useful for math stuff. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_MATHEXTRAS_H | #ifndef LLVM_SUPPORT_MATHEXTRAS_H | |||
#define LLVM_SUPPORT_MATHEXTRAS_H | #define LLVM_SUPPORT_MATHEXTRAS_H | |||
#include "llvm/Support/SwapByteOrder.h" | #include "llvm/Support/SwapByteOrder.h" | |||
#ifdef _MSC_VER | ||||
# include <intrin.h> | ||||
#endif | ||||
namespace llvm { | namespace llvm { | |||
// NOTE: The following support functions use the _32/_64 extensions instead of | // NOTE: The following support functions use the _32/_64 extensions instead of | |||
// type overloading so that signed and unsigned integers can be used withou t | // type overloading so that signed and unsigned integers can be used withou t | |||
// ambiguity. | // ambiguity. | |||
/// Hi_32 - This function returns the high 32 bits of a 64 bit value. | /// Hi_32 - This function returns the high 32 bits of a 64 bit value. | |||
inline uint32_t Hi_32(uint64_t Value) { | inline uint32_t Hi_32(uint64_t Value) { | |||
return static_cast<uint32_t>(Value >> 32); | return static_cast<uint32_t>(Value >> 32); | |||
} | } | |||
skipping to change at line 64 | skipping to change at line 68 | |||
/// isShiftedInt<N,S> - Checks if a signed integer is an N bit number shift ed | /// isShiftedInt<N,S> - Checks if a signed integer is an N bit number shift ed | |||
/// left by S. | /// left by S. | |||
template<unsigned N, unsigned S> | template<unsigned N, unsigned S> | |||
inline bool isShiftedInt(int64_t x) { | inline bool isShiftedInt(int64_t x) { | |||
return isInt<N+S>(x) && (x % (1<<S) == 0); | return isInt<N+S>(x) && (x % (1<<S) == 0); | |||
} | } | |||
/// isUInt - Checks if an unsigned integer fits into the given bit width. | /// isUInt - Checks if an unsigned integer fits into the given bit width. | |||
template<unsigned N> | template<unsigned N> | |||
inline bool isUInt(uint64_t x) { | inline bool isUInt(uint64_t x) { | |||
return N >= 64 || x < (UINT64_C(1)<<N); | return N >= 64 || x < (UINT64_C(1)<<(N)); | |||
} | } | |||
// Template specializations to get better code for common cases. | // Template specializations to get better code for common cases. | |||
template<> | template<> | |||
inline bool isUInt<8>(uint64_t x) { | inline bool isUInt<8>(uint64_t x) { | |||
return static_cast<uint8_t>(x) == x; | return static_cast<uint8_t>(x) == x; | |||
} | } | |||
template<> | template<> | |||
inline bool isUInt<16>(uint64_t x) { | inline bool isUInt<16>(uint64_t x) { | |||
return static_cast<uint16_t>(x) == x; | return static_cast<uint16_t>(x) == x; | |||
} | } | |||
skipping to change at line 257 | skipping to change at line 261 | |||
/// Returns 32 if the word is zero. | /// Returns 32 if the word is zero. | |||
inline unsigned CountTrailingZeros_32(uint32_t Value) { | inline unsigned CountTrailingZeros_32(uint32_t Value) { | |||
#if __GNUC__ >= 4 | #if __GNUC__ >= 4 | |||
return Value ? __builtin_ctz(Value) : 32; | return Value ? __builtin_ctz(Value) : 32; | |||
#else | #else | |||
static const unsigned Mod37BitPosition[] = { | static const unsigned Mod37BitPosition[] = { | |||
32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, | 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, | |||
4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, | 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, | |||
5, 20, 8, 19, 18 | 5, 20, 8, 19, 18 | |||
}; | }; | |||
return Mod37BitPosition[(-Value & Value) % 37]; | // Replace "-Value" by "1+~Value" in the following commented code to avoi | |||
d | ||||
// MSVC warning C4146 | ||||
// return Mod37BitPosition[(-Value & Value) % 37]; | ||||
return Mod37BitPosition[((1 + ~Value) & Value) % 37]; | ||||
#endif | #endif | |||
} | } | |||
/// CountTrailingOnes_32 - this function performs the operation of | /// CountTrailingOnes_32 - this function performs the operation of | |||
/// counting the number of ones from the least significant bit to the first zero | /// counting the number of ones from the least significant bit to the first zero | |||
/// bit. Ex. CountTrailingOnes_32(0x00FF00FF) == 8. | /// bit. Ex. CountTrailingOnes_32(0x00FF00FF) == 8. | |||
/// Returns 32 if the word is all ones. | /// Returns 32 if the word is all ones. | |||
inline unsigned CountTrailingOnes_32(uint32_t Value) { | inline unsigned CountTrailingOnes_32(uint32_t Value) { | |||
return CountTrailingZeros_32(~Value); | return CountTrailingZeros_32(~Value); | |||
} | } | |||
skipping to change at line 284 | skipping to change at line 291 | |||
#if __GNUC__ >= 4 | #if __GNUC__ >= 4 | |||
return Value ? __builtin_ctzll(Value) : 64; | return Value ? __builtin_ctzll(Value) : 64; | |||
#else | #else | |||
static const unsigned Mod67Position[] = { | static const unsigned Mod67Position[] = { | |||
64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54, | 64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54, | |||
4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55, | 4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55, | |||
47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27, | 47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27, | |||
29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56, | 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56, | |||
7, 48, 35, 6, 34, 33, 0 | 7, 48, 35, 6, 34, 33, 0 | |||
}; | }; | |||
return Mod67Position[(-Value & Value) % 67]; | // Replace "-Value" by "1+~Value" in the following commented code to avoi | |||
d | ||||
// MSVC warning C4146 | ||||
// return Mod67Position[(-Value & Value) % 67]; | ||||
return Mod67Position[((1 + ~Value) & Value) % 67]; | ||||
#endif | #endif | |||
} | } | |||
/// CountTrailingOnes_64 - This function performs the operation | /// CountTrailingOnes_64 - This function performs the operation | |||
/// of counting the number of ones from the least significant bit to the fi rst | /// of counting the number of ones from the least significant bit to the fi rst | |||
/// zero bit (64 bit edition.) | /// zero bit (64 bit edition.) | |||
/// Returns 64 if the word is all ones. | /// Returns 64 if the word is all ones. | |||
inline unsigned CountTrailingOnes_64(uint64_t Value) { | inline unsigned CountTrailingOnes_64(uint64_t Value) { | |||
return CountTrailingZeros_64(~Value); | return CountTrailingZeros_64(~Value); | |||
} | } | |||
skipping to change at line 419 | skipping to change at line 429 | |||
int IsNAN(double d); | int IsNAN(double d); | |||
/// Platform-independent wrappers for the C99 isinf() function. | /// Platform-independent wrappers for the C99 isinf() function. | |||
int IsInf(float f); | int IsInf(float f); | |||
int IsInf(double d); | int IsInf(double d); | |||
/// MinAlign - A and B are either alignments or offsets. Return the minimu m | /// MinAlign - A and B are either alignments or offsets. Return the minimu m | |||
/// alignment that may be assumed after adding the two together. | /// alignment that may be assumed after adding the two together. | |||
inline uint64_t MinAlign(uint64_t A, uint64_t B) { | inline uint64_t MinAlign(uint64_t A, uint64_t B) { | |||
// The largest power of 2 that divides both A and B. | // The largest power of 2 that divides both A and B. | |||
return (A | B) & -(A | B); | // | |||
// Replace "-Value" by "1+~Value" in the following commented code to avoi | ||||
d | ||||
// MSVC warning C4146 | ||||
// return (A | B) & -(A | B); | ||||
return (A | B) & (1 + ~(A | B)); | ||||
} | } | |||
/// NextPowerOf2 - Returns the next power of two (in 64-bits) | /// NextPowerOf2 - Returns the next power of two (in 64-bits) | |||
/// that is strictly greater than A. Returns zero on overflow. | /// that is strictly greater than A. Returns zero on overflow. | |||
inline uint64_t NextPowerOf2(uint64_t A) { | inline uint64_t NextPowerOf2(uint64_t A) { | |||
A |= (A >> 1); | A |= (A >> 1); | |||
A |= (A >> 2); | A |= (A >> 2); | |||
A |= (A >> 4); | A |= (A >> 4); | |||
A |= (A >> 8); | A |= (A >> 8); | |||
A |= (A >> 16); | A |= (A >> 16); | |||
End of changes. 5 change blocks. | ||||
4 lines changed or deleted | 21 lines changed or added | |||
Memory.h | Memory.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the llvm::sys::Memory class. | // This file declares the llvm::sys::Memory class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_MEMORY_H | #ifndef LLVM_SUPPORT_MEMORY_H | |||
#define LLVM_SYSTEM_MEMORY_H | #define LLVM_SUPPORT_MEMORY_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/system_error.h" | #include "llvm/Support/system_error.h" | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
/// This class encapsulates the notion of a memory block which has an add ress | /// This class encapsulates the notion of a memory block which has an add ress | |||
/// and a size. It is used by the Memory class (a friend) as the result o f | /// and a size. It is used by the Memory class (a friend) as the result o f | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
MemoryBuffer.h | MemoryBuffer.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the MemoryBuffer interface. | // This file defines the MemoryBuffer interface. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_MEMORYBUFFER_H | #ifndef LLVM_SUPPORT_MEMORYBUFFER_H | |||
#define LLVM_SUPPORT_MEMORYBUFFER_H | #define LLVM_SUPPORT_MEMORYBUFFER_H | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/CBindingWrapping.h" | ||||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm-c/Core.h" | ||||
namespace llvm { | namespace llvm { | |||
class error_code; | class error_code; | |||
template<class T> class OwningPtr; | template<class T> class OwningPtr; | |||
/// MemoryBuffer - This interface provides simple read-only access to a blo ck | /// MemoryBuffer - This interface provides simple read-only access to a blo ck | |||
/// of memory, and provides simple methods for reading files and standard i nput | /// of memory, and provides simple methods for reading files and standard i nput | |||
/// into a memory buffer. In addition to basic access to the characters in the | /// into a memory buffer. In addition to basic access to the characters in the | |||
/// file, this interface guarantees you can read one character past the end of | /// file, this interface guarantees you can read one character past the end of | |||
skipping to change at line 138 | skipping to change at line 140 | |||
enum BufferKind { | enum BufferKind { | |||
MemoryBuffer_Malloc, | MemoryBuffer_Malloc, | |||
MemoryBuffer_MMap | MemoryBuffer_MMap | |||
}; | }; | |||
/// Return information on the memory mechanism used to support the | /// Return information on the memory mechanism used to support the | |||
/// MemoryBuffer. | /// MemoryBuffer. | |||
virtual BufferKind getBufferKind() const = 0; | virtual BufferKind getBufferKind() const = 0; | |||
}; | }; | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef) | ||||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 5 lines changed or added | |||
MemoryBuiltins.h | MemoryBuiltins.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This family of functions identifies calls to builtin functions that allo cate | // This family of functions identifies calls to builtin functions that allo cate | |||
// or free memory. | // or free memory. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H | #ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H | |||
#define LLVM_ANALYSIS_MEMORYBUILTINS_H | #define LLVM_ANALYSIS_MEMORYBUILTINS_H | |||
#include "llvm/IRBuilder.h" | ||||
#include "llvm/Operator.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/IR/IRBuilder.h" | ||||
#include "llvm/IR/Operator.h" | ||||
#include "llvm/InstVisitor.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/InstVisitor.h" | ||||
#include "llvm/Support/TargetFolder.h" | #include "llvm/Support/TargetFolder.h" | |||
#include "llvm/Support/ValueHandle.h" | #include "llvm/Support/ValueHandle.h" | |||
namespace llvm { | namespace llvm { | |||
class CallInst; | class CallInst; | |||
class PointerType; | class PointerType; | |||
class DataLayout; | class DataLayout; | |||
class TargetLibraryInfo; | class TargetLibraryInfo; | |||
class Type; | class Type; | |||
class Value; | class Value; | |||
skipping to change at line 136 | skipping to change at line 136 | |||
static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) { | static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) { | |||
return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI)); | return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI)); | |||
} | } | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Utility functions to compute size of objects. | // Utility functions to compute size of objects. | |||
// | // | |||
/// \brief Compute the size of the object pointed by Ptr. Returns true and the | /// \brief Compute the size of the object pointed by Ptr. Returns true and the | |||
/// object size in Size if successful, and false otherwise. | /// object size in Size if successful, and false otherwise. In this context | |||
, by | ||||
/// object we mean the region of memory starting at Ptr to the end of the | ||||
/// underlying object pointed to by Ptr. | ||||
/// If RoundToAlign is true, then Size is rounded up to the aligment of all ocas, | /// If RoundToAlign is true, then Size is rounded up to the aligment of all ocas, | |||
/// byval arguments, and global variables. | /// byval arguments, and global variables. | |||
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD, | bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD, | |||
const TargetLibraryInfo *TLI, bool RoundToAlign = false) ; | const TargetLibraryInfo *TLI, bool RoundToAlign = false) ; | |||
typedef std::pair<APInt, APInt> SizeOffsetType; | 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 ponted by a Value* | |||
/// statically. Fails if size or offset are not known at compile time. | /// statically. Fails if size or offset are not known at compile time. | |||
class ObjectSizeOffsetVisitor | class ObjectSizeOffsetVisitor | |||
skipping to change at line 187 | skipping to change at line 189 | |||
return knownSize(SizeOffset) && knownOffset(SizeOffset); | return knownSize(SizeOffset) && knownOffset(SizeOffset); | |||
} | } | |||
SizeOffsetType visitAllocaInst(AllocaInst &I); | SizeOffsetType visitAllocaInst(AllocaInst &I); | |||
SizeOffsetType visitArgument(Argument &A); | SizeOffsetType visitArgument(Argument &A); | |||
SizeOffsetType visitCallSite(CallSite CS); | SizeOffsetType visitCallSite(CallSite CS); | |||
SizeOffsetType visitConstantPointerNull(ConstantPointerNull&); | SizeOffsetType visitConstantPointerNull(ConstantPointerNull&); | |||
SizeOffsetType visitExtractElementInst(ExtractElementInst &I); | SizeOffsetType visitExtractElementInst(ExtractElementInst &I); | |||
SizeOffsetType visitExtractValueInst(ExtractValueInst &I); | SizeOffsetType visitExtractValueInst(ExtractValueInst &I); | |||
SizeOffsetType visitGEPOperator(GEPOperator &GEP); | SizeOffsetType visitGEPOperator(GEPOperator &GEP); | |||
SizeOffsetType visitGlobalAlias(GlobalAlias &GA); | ||||
SizeOffsetType visitGlobalVariable(GlobalVariable &GV); | SizeOffsetType visitGlobalVariable(GlobalVariable &GV); | |||
SizeOffsetType visitIntToPtrInst(IntToPtrInst&); | SizeOffsetType visitIntToPtrInst(IntToPtrInst&); | |||
SizeOffsetType visitLoadInst(LoadInst &I); | SizeOffsetType visitLoadInst(LoadInst &I); | |||
SizeOffsetType visitPHINode(PHINode&); | SizeOffsetType visitPHINode(PHINode&); | |||
SizeOffsetType visitSelectInst(SelectInst &I); | SizeOffsetType visitSelectInst(SelectInst &I); | |||
SizeOffsetType visitUndefValue(UndefValue&); | SizeOffsetType visitUndefValue(UndefValue&); | |||
SizeOffsetType visitInstruction(Instruction &I); | SizeOffsetType visitInstruction(Instruction &I); | |||
}; | }; | |||
typedef std::pair<Value*, Value*> SizeOffsetEvalType; | typedef std::pair<Value*, Value*> SizeOffsetEvalType; | |||
End of changes. 5 change blocks. | ||||
4 lines changed or deleted | 8 lines changed or added | |||
MemoryDependenceAnalysis.h | MemoryDependenceAnalysis.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the MemoryDependenceAnalysis analysis pass. | // This file defines the MemoryDependenceAnalysis analysis pass. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H | #ifndef LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H | |||
#define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H | #define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H | |||
#include "llvm/BasicBlock.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/Support/ValueHandle.h" | ||||
#include "llvm/Analysis/AliasAnalysis.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | ||||
#include "llvm/ADT/OwningPtr.h" | #include "llvm/ADT/OwningPtr.h" | |||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | ||||
#include "llvm/Analysis/AliasAnalysis.h" | ||||
#include "llvm/IR/BasicBlock.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/Support/ValueHandle.h" | ||||
namespace llvm { | namespace llvm { | |||
class Function; | class Function; | |||
class FunctionPass; | class FunctionPass; | |||
class Instruction; | class Instruction; | |||
class CallSite; | class CallSite; | |||
class AliasAnalysis; | class AliasAnalysis; | |||
class DataLayout; | class DataLayout; | |||
class MemoryDependenceAnalysis; | class MemoryDependenceAnalysis; | |||
class PredIteratorCache; | class PredIteratorCache; | |||
skipping to change at line 392 | skipping to change at line 392 | |||
void invalidateCachedPointerInfo(Value *Ptr); | void invalidateCachedPointerInfo(Value *Ptr); | |||
/// invalidateCachedPredecessors - Clear the PredIteratorCache info. | /// invalidateCachedPredecessors - Clear the PredIteratorCache info. | |||
/// This needs to be done when the CFG changes, e.g., due to splitting | /// This needs to be done when the CFG changes, e.g., due to splitting | |||
/// critical edges. | /// critical edges. | |||
void invalidateCachedPredecessors(); | void invalidateCachedPredecessors(); | |||
/// getPointerDependencyFrom - Return the instruction on which a memory | /// getPointerDependencyFrom - Return the instruction on which a memory | |||
/// location depends. If isLoad is true, this routine ignores may-alia ses | /// location depends. If isLoad is true, this routine ignores may-alia ses | |||
/// with read-only operations. If isLoad is false, this routine ignore s | /// with read-only operations. If isLoad is false, this routine ignore s | |||
/// may-aliases with reads from read-only locations. | /// may-aliases with reads from read-only locations. If possible, pass | |||
/// the query instruction as well; this function may take advantage of | ||||
/// the metadata annotated to the query instruction to refine the resul | ||||
t. | ||||
/// | /// | |||
/// Note that this is an uncached query, and thus may be inefficient. | /// Note that this is an uncached query, and thus may be inefficient. | |||
/// | /// | |||
MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Lo c, | MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Lo c, | |||
bool isLoad, | bool isLoad, | |||
BasicBlock::iterator ScanIt, | BasicBlock::iterator ScanIt, | |||
BasicBlock *BB); | BasicBlock *BB, | |||
Instruction *QueryInst = 0); | ||||
/// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that | /// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that | |||
/// looks at a memory location for a load (specified by MemLocBase, Off s, | /// looks at a memory location for a load (specified by MemLocBase, Off s, | |||
/// and Size) and compares it against a load. If the specified load co uld | /// and Size) and compares it against a load. If the specified load co uld | |||
/// be safely widened to a larger integer load that is 1) still efficie nt, | /// be safely widened to a larger integer load that is 1) still efficie nt, | |||
/// 2) safe for the target, and 3) would provide the specified memory | /// 2) safe for the target, and 3) would provide the specified memory | |||
/// location value, then this function returns the size in bytes of the | /// location value, then this function returns the size in bytes of the | |||
/// load width to use. If not, this returns zero. | /// load width to use. If not, this returns zero. | |||
static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase , | static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase , | |||
int64_t MemLocOffs, | int64_t MemLocOffs, | |||
End of changes. 6 change blocks. | ||||
9 lines changed or deleted | 13 lines changed or added | |||
MemoryObject.h | MemoryObject.h | |||
---|---|---|---|---|
//===- MemoryObject.h - Abstract memory interface ---------------*- C++ -*- ===// | //===- MemoryObject.h - Abstract memory interface ---------------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef MEMORYOBJECT_H | #ifndef LLVM_SUPPORT_MEMORYOBJECT_H | |||
#define MEMORYOBJECT_H | #define LLVM_SUPPORT_MEMORYOBJECT_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
/// MemoryObject - Abstract base class for contiguous addressable memory. | /// MemoryObject - Abstract base class for contiguous addressable memory. | |||
/// Necessary for cases in which the memory is in another process, in a | /// Necessary for cases in which the memory is in another process, in a | |||
/// file, or on a remote machine. | /// file, or on a remote machine. | |||
/// All size and offset parameters are uint64_ts, to allow 32-bit process es | /// All size and offset parameters are uint64_ts, to allow 32-bit process es | |||
/// access to 64-bit address spaces. | /// access to 64-bit address spaces. | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Metadata.h | Metadata.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
/// @file | /// @file | |||
/// This file contains the declarations for metadata subclasses. | /// This file contains the declarations for metadata subclasses. | |||
/// They represent the different flavors of metadata that live in LLVM. | /// They represent the different flavors of metadata that live in LLVM. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_METADATA_H | #ifndef LLVM_IR_METADATA_H | |||
#define LLVM_METADATA_H | #define LLVM_IR_METADATA_H | |||
#include "llvm/Value.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/FoldingSet.h" | #include "llvm/ADT/FoldingSet.h" | |||
#include "llvm/ADT/ilist_node.h" | #include "llvm/ADT/ilist_node.h" | |||
#include "llvm/IR/Value.h" | ||||
namespace llvm { | namespace llvm { | |||
class Constant; | class Constant; | |||
class Instruction; | class Instruction; | |||
class LLVMContext; | class LLVMContext; | |||
class Module; | class Module; | |||
template <typename T> class SmallVectorImpl; | template <typename T> class SmallVectorImpl; | |||
template<typename ValueSubClass, typename ItemParentClass> | template<typename ValueSubClass, typename ItemParentClass> | |||
class SymbolTableListTraits; | class SymbolTableListTraits; | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
Module.h | Module.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
/// @file | /// @file | |||
/// Module.h This file contains the declarations for the Module class. | /// Module.h This file contains the declarations for the Module class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MODULE_H | #ifndef LLVM_IR_MODULE_H | |||
#define LLVM_MODULE_H | #define LLVM_IR_MODULE_H | |||
#include "llvm/Function.h" | ||||
#include "llvm/GlobalVariable.h" | ||||
#include "llvm/GlobalAlias.h" | ||||
#include "llvm/Metadata.h" | ||||
#include "llvm/ADT/OwningPtr.h" | #include "llvm/ADT/OwningPtr.h" | |||
#include "llvm/IR/Function.h" | ||||
#include "llvm/IR/GlobalAlias.h" | ||||
#include "llvm/IR/GlobalVariable.h" | ||||
#include "llvm/IR/Metadata.h" | ||||
#include "llvm/Support/CBindingWrapping.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
class FunctionType; | class FunctionType; | |||
class GVMaterializer; | class GVMaterializer; | |||
class LLVMContext; | class LLVMContext; | |||
class StructType; | class StructType; | |||
template<typename T> struct DenseMapInfo; | template<typename T> struct DenseMapInfo; | |||
template<typename KeyT, typename ValueT, typename KeyInfoT> class DenseMap; | template<typename KeyT, typename ValueT, typename KeyInfoT> class DenseMap; | |||
skipping to change at line 125 | skipping to change at line 125 | |||
public: | public: | |||
/// The type for the list of global variables. | /// The type for the list of global variables. | |||
typedef iplist<GlobalVariable> GlobalListType; | typedef iplist<GlobalVariable> GlobalListType; | |||
/// The type for the list of functions. | /// The type for the list of functions. | |||
typedef iplist<Function> FunctionListType; | typedef iplist<Function> FunctionListType; | |||
/// The type for the list of aliases. | /// The type for the list of aliases. | |||
typedef iplist<GlobalAlias> AliasListType; | typedef iplist<GlobalAlias> AliasListType; | |||
/// The type for the list of named metadata. | /// The type for the list of named metadata. | |||
typedef ilist<NamedMDNode> NamedMDListType; | typedef ilist<NamedMDNode> NamedMDListType; | |||
/// The type for the list of dependent libraries. | ||||
typedef std::vector<std::string> LibraryListType; | ||||
/// The Global Variable iterator. | /// The Global Variable iterator. | |||
typedef GlobalListType::iterator global_iterator; | typedef GlobalListType::iterator global_iterator; | |||
/// The Global Variable constant iterator. | /// The Global Variable constant iterator. | |||
typedef GlobalListType::const_iterator const_global_iterator; | typedef GlobalListType::const_iterator const_global_iterator; | |||
/// The Function iterators. | /// The Function iterators. | |||
typedef FunctionListType::iterator iterator; | typedef FunctionListType::iterator iterator; | |||
/// The Function constant iterator | /// The Function constant iterator | |||
typedef FunctionListType::const_iterator const_iterator; | typedef FunctionListType::const_iterator const_iterator; | |||
/// The Global Alias iterators. | /// The Global Alias iterators. | |||
typedef AliasListType::iterator alias_iterator; | typedef AliasListType::iterator alias_iterator; | |||
/// The Global Alias constant iterator | /// The Global Alias constant iterator | |||
typedef AliasListType::const_iterator const_alias_iterator; | typedef AliasListType::const_iterator const_alias_iterator; | |||
/// The named metadata iterators. | /// The named metadata iterators. | |||
typedef NamedMDListType::iterator named_metadata_iterator; | typedef NamedMDListType::iterator named_metadata_iterator; | |||
/// The named metadata constant interators. | /// The named metadata constant interators. | |||
typedef NamedMDListType::const_iterator const_named_metadata_iterator; | typedef NamedMDListType::const_iterator const_named_metadata_iterator; | |||
/// The Library list iterator. | ||||
typedef LibraryListType::const_iterator lib_iterator; | ||||
/// An enumeration for describing the endianess of the target machine. | /// An enumeration for describing the endianess of the target machine. | |||
enum Endianness { AnyEndianness, LittleEndian, BigEndian }; | enum Endianness { AnyEndianness, LittleEndian, BigEndian }; | |||
/// An enumeration for describing the size of a pointer on the target mac hine. | /// An enumeration for describing the size of a pointer on the target mac hine. | |||
enum PointerSize { AnyPointerSize, Pointer32, Pointer64 }; | enum PointerSize { AnyPointerSize, Pointer32, Pointer64 }; | |||
/// An enumeration for the supported behaviors of module flags. The follo | /// This enumeration defines the supported behaviors of module flags. | |||
wing | enum ModFlagBehavior { | |||
/// module flags behavior values are supported: | /// Emits an error if two values disagree, otherwise the resulting valu | |||
/// | e is | |||
/// Value Behavior | /// that of the operands. | |||
/// ----- -------- | Error = 1, | |||
/// 1 Error | ||||
/// Emits an error if two values disagree. | /// Emits a warning if two values disagree. The result value will be th | |||
/// | e | |||
/// 2 Warning | /// operand for the flag from the first module being linked. | |||
/// Emits a warning if two values disagree. | Warning = 2, | |||
/// | ||||
/// 3 Require | /// Adds a requirement that another module flag be present and have a | |||
/// Emits an error when the specified value is not pres | /// specified value after linking is performed. The value must be a met | |||
ent | adata | |||
/// or doesn't have the specified value. It is an error | /// pair, where the first element of the pair is the ID of the module f | |||
for | lag | |||
/// two (or more) llvm.module.flags with the same ID to | /// to be restricted, and the second element of the pair is the value t | |||
have | he | |||
/// the Require behavior but different values. There ma | /// module flag should be restricted to. This behavior can be used to | |||
y be | /// restrict the allowable results (via triggering of an error) of link | |||
/// multiple Require flags per ID. | ing | |||
/// | /// IDs with the **Override** behavior. | |||
/// 4 Override | Require = 3, | |||
/// Uses the specified value if the two values disagree | ||||
. It | /// Uses the specified value, regardless of the behavior or value of th | |||
/// is an error for two (or more) llvm.module.flags wit | e | |||
h the | /// other module. If both modules specify **Override**, but the values | |||
/// same ID to have the Override behavior but different | /// differ, an error will be emitted. | |||
/// values. | Override = 4, | |||
enum ModFlagBehavior { Error = 1, Warning = 2, Require = 3, Override = 4 | ||||
}; | /// Appends the two values, which are required to be metadata nodes. | |||
Append = 5, | ||||
/// Appends the two values, which are required to be metadata | ||||
/// nodes. However, duplicate entries in the second list are dropped | ||||
/// during the append operation. | ||||
AppendUnique = 6 | ||||
}; | ||||
struct ModuleFlagEntry { | struct ModuleFlagEntry { | |||
ModFlagBehavior Behavior; | ModFlagBehavior Behavior; | |||
MDString *Key; | MDString *Key; | |||
Value *Val; | Value *Val; | |||
ModuleFlagEntry(ModFlagBehavior B, MDString *K, Value *V) | ModuleFlagEntry(ModFlagBehavior B, MDString *K, Value *V) | |||
: Behavior(B), Key(K), Val(V) {} | : Behavior(B), Key(K), Val(V) {} | |||
}; | }; | |||
/// @} | /// @} | |||
/// @name Member Variables | /// @name Member Variables | |||
/// @{ | /// @{ | |||
private: | private: | |||
LLVMContext &Context; ///< The LLVMContext from which types and | LLVMContext &Context; ///< The LLVMContext from which types and | |||
///< constants are allocated. | ///< constants are allocated. | |||
GlobalListType GlobalList; ///< The Global Variables in the module | GlobalListType GlobalList; ///< The Global Variables in the module | |||
FunctionListType FunctionList; ///< The Functions in the module | FunctionListType FunctionList; ///< The Functions in the module | |||
AliasListType AliasList; ///< The Aliases in the module | AliasListType AliasList; ///< The Aliases in the module | |||
LibraryListType LibraryList; ///< The Libraries needed by the module | ||||
NamedMDListType NamedMDList; ///< The named metadata in the module | NamedMDListType NamedMDList; ///< The named metadata in the module | |||
std::string GlobalScopeAsm; ///< Inline Asm at global scope. | std::string GlobalScopeAsm; ///< Inline Asm at global scope. | |||
ValueSymbolTable *ValSymTab; ///< Symbol table for values | ValueSymbolTable *ValSymTab; ///< Symbol table for values | |||
OwningPtr<GVMaterializer> Materializer; ///< Used to materialize GlobalV alues | OwningPtr<GVMaterializer> Materializer; ///< Used to materialize GlobalV alues | |||
std::string ModuleID; ///< Human readable identifier for the mo dule | std::string ModuleID; ///< Human readable identifier for the mo dule | |||
std::string TargetTriple; ///< Platform target triple Module compil ed on | std::string TargetTriple; ///< Platform target triple Module compil ed on | |||
std::string DataLayout; ///< Target data description | std::string DataLayout; ///< Target data description | |||
void *NamedMDSymTab; ///< NamedMDNode names. | void *NamedMDSymTab; ///< NamedMDNode names. | |||
friend class Constant; | friend class Constant; | |||
skipping to change at line 321 | skipping to change at line 323 | |||
/// getOrInsertFunction - Look up the specified function in the module sy mbol | /// getOrInsertFunction - Look up the specified function in the module sy mbol | |||
/// table. Four possibilities: | /// table. Four possibilities: | |||
/// 1. If it does not exist, add a prototype for the function and retur n it. | /// 1. If it does not exist, add a prototype for the function and retur n it. | |||
/// 2. If it exists, and has a local linkage, the existing function is | /// 2. If it exists, and has a local linkage, the existing function is | |||
/// renamed and a new one is inserted. | /// renamed and a new one is inserted. | |||
/// 3. Otherwise, if the existing function has the correct prototype, r eturn | /// 3. Otherwise, if the existing function has the correct prototype, r eturn | |||
/// the existing function. | /// the existing function. | |||
/// 4. Finally, the function exists but has the wrong prototype: return the | /// 4. Finally, the function exists but has the wrong prototype: return the | |||
/// function with a constantexpr cast to the right prototype. | /// function with a constantexpr cast to the right prototype. | |||
Constant *getOrInsertFunction(StringRef Name, FunctionType *T, | Constant *getOrInsertFunction(StringRef Name, FunctionType *T, | |||
AttrListPtr AttributeList); | AttributeSet AttributeList); | |||
Constant *getOrInsertFunction(StringRef Name, FunctionType *T); | Constant *getOrInsertFunction(StringRef Name, FunctionType *T); | |||
/// getOrInsertFunction - Look up the specified function in the module sy mbol | /// getOrInsertFunction - Look up the specified function in the module sy mbol | |||
/// table. If it does not exist, add a prototype for the function and re turn | /// table. If it does not exist, add a prototype for the function and re turn | |||
/// it. This function guarantees to return a constant of pointer to the | /// it. This function guarantees to return a constant of pointer to the | |||
/// specified function type or a ConstantExpr BitCast of that type if the | /// specified function type or a ConstantExpr BitCast of that type if the | |||
/// named function has a different type. This version of the method take s a | /// named function has a different type. This version of the method take s a | |||
/// null terminated list of function arguments, which makes it easier for | /// null terminated list of function arguments, which makes it easier for | |||
/// clients to use. | /// clients to use. | |||
Constant *getOrInsertFunction(StringRef Name, | Constant *getOrInsertFunction(StringRef Name, | |||
AttrListPtr AttributeList, | AttributeSet AttributeList, | |||
Type *RetTy, ...) END_WITH_NULL; | Type *RetTy, ...) END_WITH_NULL; | |||
/// getOrInsertFunction - Same as above, but without the attributes. | /// getOrInsertFunction - Same as above, but without the attributes. | |||
Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ...) | Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ...) | |||
END_WITH_NULL; | END_WITH_NULL; | |||
Constant *getOrInsertTargetIntrinsic(StringRef Name, | Constant *getOrInsertTargetIntrinsic(StringRef Name, | |||
FunctionType *Ty, | FunctionType *Ty, | |||
AttrListPtr AttributeList); | AttributeSet AttributeList); | |||
/// getFunction - Look up the specified function in the module symbol tab le. | /// getFunction - Look up the specified function in the module symbol tab le. | |||
/// If it does not exist, return null. | /// If it does not exist, return null. | |||
Function *getFunction(StringRef Name) const; | Function *getFunction(StringRef Name) const; | |||
/// @} | /// @} | |||
/// @name Global Variable Accessors | /// @name Global Variable Accessors | |||
/// @{ | /// @{ | |||
/// getGlobalVariable - Look up the specified global variable in the modu le | /// getGlobalVariable - Look up the specified global variable in the modu le | |||
skipping to change at line 529 | skipping to change at line 531 | |||
/// @{ | /// @{ | |||
iterator begin() { return FunctionList.begin(); } | iterator begin() { return FunctionList.begin(); } | |||
const_iterator begin() const { return FunctionList.begin(); } | const_iterator begin() const { return FunctionList.begin(); } | |||
iterator end () { return FunctionList.end(); } | iterator end () { return FunctionList.end(); } | |||
const_iterator end () const { return FunctionList.end(); } | const_iterator end () const { return FunctionList.end(); } | |||
size_t size() const { return FunctionList.size(); } | size_t size() const { return FunctionList.size(); } | |||
bool empty() const { return FunctionList.empty(); } | bool empty() const { return FunctionList.empty(); } | |||
/// @} | /// @} | |||
/// @name Dependent Library Iteration | ||||
/// @{ | ||||
/// @brief Get a constant iterator to beginning of dependent library list | ||||
. | ||||
inline lib_iterator lib_begin() const { return LibraryList.begin(); } | ||||
/// @brief Get a constant iterator to end of dependent library list. | ||||
inline lib_iterator lib_end() const { return LibraryList.end(); } | ||||
/// @brief Returns the number of items in the list of libraries. | ||||
inline size_t lib_size() const { return LibraryList.size(); } | ||||
/// @brief Add a library to the list of dependent libraries | ||||
void addLibrary(StringRef Lib); | ||||
/// @brief Remove a library from the list of dependent libraries | ||||
void removeLibrary(StringRef Lib); | ||||
/// @brief Get all the libraries | ||||
inline const LibraryListType& getLibraries() const { return LibraryList; | ||||
} | ||||
/// @} | ||||
/// @name Alias Iteration | /// @name Alias Iteration | |||
/// @{ | /// @{ | |||
alias_iterator alias_begin() { return AliasList.begin(); } | alias_iterator alias_begin() { return AliasList.begin(); } | |||
const_alias_iterator alias_begin() const { return AliasList.begin(); } | const_alias_iterator alias_begin() const { return AliasList.begin(); } | |||
alias_iterator alias_end () { return AliasList.end(); } | alias_iterator alias_end () { return AliasList.end(); } | |||
const_alias_iterator alias_end () const { return AliasList.end(); } | const_alias_iterator alias_end () const { return AliasList.end(); } | |||
size_t alias_size () const { return AliasList.size(); } | size_t alias_size () const { return AliasList.size(); } | |||
bool alias_empty() const { return AliasList.empty(); } | bool alias_empty() const { return AliasList.empty(); } | |||
skipping to change at line 600 | skipping to change at line 585 | |||
void dropAllReferences(); | void dropAllReferences(); | |||
/// @} | /// @} | |||
}; | }; | |||
/// An raw_ostream inserter for modules. | /// An raw_ostream inserter for modules. | |||
inline raw_ostream &operator<<(raw_ostream &O, const Module &M) { | inline raw_ostream &operator<<(raw_ostream &O, const Module &M) { | |||
M.print(O, 0); | M.print(O, 0); | |||
return O; | return O; | |||
} | } | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef) | ||||
/* LLVMModuleProviderRef exists for historical reasons, but now just holds | ||||
a | ||||
* Module. | ||||
*/ | ||||
inline Module *unwrap(LLVMModuleProviderRef MP) { | ||||
return reinterpret_cast<Module*>(MP); | ||||
} | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 13 change blocks. | ||||
67 lines changed or deleted | 60 lines changed or added | |||
ModuleUtils.h | ModuleUtils.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This family of functions perform manipulations on Modules. | // This family of functions perform manipulations on Modules. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H | #ifndef LLVM_TRANSFORMS_UTILS_MODULEUTILS_H | |||
#define LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H | #define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H | |||
namespace llvm { | namespace llvm { | |||
class Module; | class Module; | |||
class Function; | class Function; | |||
/// Append F to the list of global ctors of module M with the given Priorit y. | /// Append F to the list of global ctors of module M with the given Priorit y. | |||
/// This wraps the function in the appropriate structure and stores it alon g | /// This wraps the function in the appropriate structure and stores it alon g | |||
/// side other global constructors. For details see | /// side other global constructors. For details see | |||
/// http://llvm.org/docs/LangRef.html#intg_global_ctors | /// http://llvm.org/docs/LangRef.html#intg_global_ctors | |||
void appendToGlobalCtors(Module &M, Function *F, int Priority); | void appendToGlobalCtors(Module &M, Function *F, int Priority); | |||
/// Same as appendToGlobalCtors(), but for global dtors. | /// Same as appendToGlobalCtors(), but for global dtors. | |||
void appendToGlobalDtors(Module &M, Function *F, int Priority); | void appendToGlobalDtors(Module &M, Function *F, int Priority); | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif // LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H | #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Mutex.h | Mutex.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the llvm::sys::Mutex class. | // This file declares the llvm::sys::Mutex class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_MUTEX_H | #ifndef LLVM_SUPPORT_MUTEX_H | |||
#define LLVM_SYSTEM_MUTEX_H | #define LLVM_SUPPORT_MUTEX_H | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/Threading.h" | #include "llvm/Support/Threading.h" | |||
#include <cassert> | #include <cassert> | |||
namespace llvm | namespace llvm | |||
{ | { | |||
namespace sys | namespace sys | |||
{ | { | |||
/// @brief Platform agnostic Mutex class. | /// @brief Platform agnostic Mutex class. | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
NoFolder.h | NoFolder.h | |||
---|---|---|---|---|
skipping to change at line 26 | skipping to change at line 26 | |||
// | // | |||
// Note: since it is not actually possible to create unfolded constants, th is | // Note: since it is not actually possible to create unfolded constants, th is | |||
// class returns instructions rather than constants. | // class returns instructions rather than constants. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_NOFOLDER_H | #ifndef LLVM_SUPPORT_NOFOLDER_H | |||
#define LLVM_SUPPORT_NOFOLDER_H | #define LLVM_SUPPORT_NOFOLDER_H | |||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/Constants.h" | #include "llvm/IR/Constants.h" | |||
#include "llvm/Instructions.h" | #include "llvm/IR/Instructions.h" | |||
namespace llvm { | namespace llvm { | |||
/// NoFolder - Create "constants" (actually, instructions) with no folding. | /// NoFolder - Create "constants" (actually, instructions) with no folding. | |||
class NoFolder { | class NoFolder { | |||
public: | public: | |||
explicit NoFolder() {} | explicit NoFolder() {} | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Binary Operators | // Binary Operators | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
NullablePtr.h | NullablePtr.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines and implements the NullablePtr class. | // This file defines and implements the NullablePtr class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_NULLABLE_PTR_H | #ifndef LLVM_ADT_NULLABLEPTR_H | |||
#define LLVM_ADT_NULLABLE_PTR_H | #define LLVM_ADT_NULLABLEPTR_H | |||
#include <cassert> | #include <cassert> | |||
#include <cstddef> | #include <cstddef> | |||
namespace llvm { | namespace llvm { | |||
/// NullablePtr pointer wrapper - NullablePtr is used for APIs where a | /// NullablePtr pointer wrapper - NullablePtr is used for APIs where a | |||
/// potentially-null pointer gets passed around that must be explicitly han dled | /// potentially-null pointer gets passed around that must be explicitly han dled | |||
/// in lots of places. By putting a wrapper around the null pointer, it ma kes | /// in lots of places. By putting a wrapper around the null pointer, it ma kes | |||
/// it more likely that the null pointer case will be handled correctly. | /// it more likely that the null pointer case will be handled correctly. | |||
template<class T> | template<class T> | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
OProfileWrapper.h | OProfileWrapper.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// daemon is running, and provides wrappers for opagent functions used to | // daemon is running, and provides wrappers for opagent functions used to | |||
// communicate with the oprofile JIT interface. The dynamic library libopag ent | // communicate with the oprofile JIT interface. The dynamic library libopag ent | |||
// does not need to be linked directly as this object lazily loads the libr ary | // does not need to be linked directly as this object lazily loads the libr ary | |||
// when the first op_ function is called. | // when the first op_ function is called. | |||
// | // | |||
// See http://oprofile.sourceforge.net/doc/devel/jit-interface.html for the | // See http://oprofile.sourceforge.net/doc/devel/jit-interface.html for the | |||
// definition of the interface. | // definition of the interface. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef OPROFILE_WRAPPER_H | #ifndef LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H | |||
#define OPROFILE_WRAPPER_H | #define LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <opagent.h> | #include <opagent.h> | |||
namespace llvm { | namespace llvm { | |||
class OProfileWrapper { | class OProfileWrapper { | |||
typedef op_agent_t (*op_open_agent_ptr_t)(); | typedef op_agent_t (*op_open_agent_ptr_t)(); | |||
typedef int (*op_close_agent_ptr_t)(op_agent_t); | typedef int (*op_close_agent_ptr_t)(op_agent_t); | |||
typedef int (*op_write_native_code_ptr_t)(op_agent_t, | typedef int (*op_write_native_code_ptr_t)(op_agent_t, | |||
skipping to change at line 43 | skipping to change at line 43 | |||
uint64_t, | uint64_t, | |||
void const*, | void const*, | |||
const unsigned int); | const unsigned int); | |||
typedef int (*op_write_debug_line_info_ptr_t)(op_agent_t, | typedef int (*op_write_debug_line_info_ptr_t)(op_agent_t, | |||
void const*, | void const*, | |||
size_t, | size_t, | |||
struct debug_line_info cons t*); | struct debug_line_info cons t*); | |||
typedef int (*op_unload_native_code_ptr_t)(op_agent_t, uint64_ t); | typedef int (*op_unload_native_code_ptr_t)(op_agent_t, uint64_ t); | |||
// Also used for op_minor_version function which has the same signature | // Also used for op_minor_version function which has the same signature | |||
typedef int (*op_major_version_ptr_t)(void); | typedef int (*op_major_version_ptr_t)(); | |||
// This is not a part of the opagent API, but is useful nonetheless | // This is not a part of the opagent API, but is useful nonetheless | |||
typedef bool (*IsOProfileRunningPtrT)(void); | typedef bool (*IsOProfileRunningPtrT)(); | |||
op_agent_t Agent; | op_agent_t Agent; | |||
op_open_agent_ptr_t OpenAgentFunc; | op_open_agent_ptr_t OpenAgentFunc; | |||
op_close_agent_ptr_t CloseAgentFunc; | op_close_agent_ptr_t CloseAgentFunc; | |||
op_write_native_code_ptr_t WriteNativeCodeFunc; | op_write_native_code_ptr_t WriteNativeCodeFunc; | |||
op_write_debug_line_info_ptr_t WriteDebugLineInfoFunc; | op_write_debug_line_info_ptr_t WriteDebugLineInfoFunc; | |||
op_unload_native_code_ptr_t UnloadNativeCodeFunc; | op_unload_native_code_ptr_t UnloadNativeCodeFunc; | |||
op_major_version_ptr_t MajorVersionFunc; | op_major_version_ptr_t MajorVersionFunc; | |||
op_major_version_ptr_t MinorVersionFunc; | op_major_version_ptr_t MinorVersionFunc; | |||
IsOProfileRunningPtrT IsOProfileRunningFunc; | IsOProfileRunningPtrT IsOProfileRunningFunc; | |||
skipping to change at line 100 | skipping to change at line 100 | |||
int op_close_agent(); | int op_close_agent(); | |||
int op_write_native_code(const char* name, | int op_write_native_code(const char* name, | |||
uint64_t addr, | uint64_t addr, | |||
void const* code, | void const* code, | |||
const unsigned int size); | const unsigned int size); | |||
int op_write_debug_line_info(void const* code, | int op_write_debug_line_info(void const* code, | |||
size_t num_entries, | size_t num_entries, | |||
struct debug_line_info const* info); | struct debug_line_info const* info); | |||
int op_unload_native_code(uint64_t addr); | int op_unload_native_code(uint64_t addr); | |||
int op_major_version(void); | int op_major_version(); | |||
int op_minor_version(void); | int op_minor_version(); | |||
// Returns true if the oprofiled process is running, the opagent library is | // Returns true if the oprofiled process is running, the opagent library is | |||
// loaded and a connection to the agent has been established, and false | // loaded and a connection to the agent has been established, and false | |||
// otherwise. | // otherwise. | |||
bool isAgentAvailable(); | bool isAgentAvailable(); | |||
private: | private: | |||
// Loads the libopagent library and initializes this wrapper if the oprof ile | // Loads the libopagent library and initializes this wrapper if the oprof ile | |||
// daemon is running | // daemon is running | |||
bool initialize(); | bool initialize(); | |||
// Searches /proc for the oprofile daemon and returns true if the process if | // Searches /proc for the oprofile daemon and returns true if the process if | |||
// found, or false otherwise. | // found, or false otherwise. | |||
bool checkForOProfileProcEntry(); | bool checkForOProfileProcEntry(); | |||
bool isOProfileRunning(); | bool isOProfileRunning(); | |||
}; | }; | |||
} // namespace llvm | } // namespace llvm | |||
#endif //OPROFILE_WRAPPER_H | #endif // LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H | |||
End of changes. 5 change blocks. | ||||
6 lines changed or deleted | 6 lines changed or added | |||
Object.h | Object.h | |||
---|---|---|---|---|
skipping to change at line 26 | skipping to change at line 26 | |||
/* */ | /* */ | |||
/*===---------------------------------------------------------------------- ===*/ | /*===---------------------------------------------------------------------- ===*/ | |||
#ifndef LLVM_C_OBJECT_H | #ifndef LLVM_C_OBJECT_H | |||
#define LLVM_C_OBJECT_H | #define LLVM_C_OBJECT_H | |||
#include "llvm-c/Core.h" | #include "llvm-c/Core.h" | |||
#include "llvm/Config/llvm-config.h" | #include "llvm/Config/llvm-config.h" | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
#include "llvm/Object/ObjectFile.h" | ||||
extern "C" { | extern "C" { | |||
#endif | #endif | |||
/** | /** | |||
* @defgroup LLVMCObject Object file reading and writing | * @defgroup LLVMCObject Object file reading and writing | |||
* @ingroup LLVMC | * @ingroup LLVMC | |||
* | * | |||
* @{ | * @{ | |||
*/ | */ | |||
skipping to change at line 101 | skipping to change at line 99 | |||
// following functions. | // following functions. | |||
const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI); | const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI); | |||
const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI); | const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI); | |||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} | } | |||
namespace llvm { | ||||
namespace object { | ||||
inline ObjectFile *unwrap(LLVMObjectFileRef OF) { | ||||
return reinterpret_cast<ObjectFile*>(OF); | ||||
} | ||||
inline LLVMObjectFileRef wrap(const ObjectFile *OF) { | ||||
return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF | ||||
)); | ||||
} | ||||
inline section_iterator *unwrap(LLVMSectionIteratorRef SI) { | ||||
return reinterpret_cast<section_iterator*>(SI); | ||||
} | ||||
inline LLVMSectionIteratorRef | ||||
wrap(const section_iterator *SI) { | ||||
return reinterpret_cast<LLVMSectionIteratorRef> | ||||
(const_cast<section_iterator*>(SI)); | ||||
} | ||||
inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) { | ||||
return reinterpret_cast<symbol_iterator*>(SI); | ||||
} | ||||
inline LLVMSymbolIteratorRef | ||||
wrap(const symbol_iterator *SI) { | ||||
return reinterpret_cast<LLVMSymbolIteratorRef> | ||||
(const_cast<symbol_iterator*>(SI)); | ||||
} | ||||
inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) { | ||||
return reinterpret_cast<relocation_iterator*>(SI); | ||||
} | ||||
inline LLVMRelocationIteratorRef | ||||
wrap(const relocation_iterator *SI) { | ||||
return reinterpret_cast<LLVMRelocationIteratorRef> | ||||
(const_cast<relocation_iterator*>(SI)); | ||||
} | ||||
} | ||||
} | ||||
#endif /* defined(__cplusplus) */ | #endif /* defined(__cplusplus) */ | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
47 lines changed or deleted | 0 lines changed or added | |||
ObjectBuffer.h | ObjectBuffer.h | |||
---|---|---|---|---|
//===---- ObjectBuffer.h - Utility class to wrap object image memory -----= ==// | //===---- ObjectBuffer.h - Utility class to wrap object image memory -----= ==// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares a wrapper class to hold the memory into which an | // This file declares a wrapper class to hold the memory into which an | |||
// object will be generated. | // object will be generated. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H | #ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H | |||
#define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H | #define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/OwningPtr.h" | #include "llvm/ADT/OwningPtr.h" | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/Support/MemoryBuffer.h" | #include "llvm/Support/MemoryBuffer.h" | |||
#include "llvm/Support/raw_ostream.h" | ||||
namespace llvm { | namespace llvm { | |||
/// ObjectBuffer - This class acts as a container for the memory buffer use d during | /// ObjectBuffer - This class acts as a container for the memory buffer use d during | |||
/// generation and loading of executable objects using MCJIT and RuntimeDyl d. The | /// generation and loading of executable objects using MCJIT and RuntimeDyl d. The | |||
/// underlying memory for the object will be owned by the ObjectBuffer inst ance | /// underlying memory for the object will be owned by the ObjectBuffer inst ance | |||
/// throughout its lifetime. The getMemBuffer() method provides a way to c reate a | /// throughout its lifetime. The getMemBuffer() method provides a way to c reate a | |||
/// MemoryBuffer wrapper object instance to be owned by other classes (such as | /// MemoryBuffer wrapper object instance to be owned by other classes (such as | |||
/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own the | /// ObjectFile) as needed, but the MemoryBuffer instance returned does not own the | |||
/// actual memory it points to. | /// actual memory it points to. | |||
skipping to change at line 69 | skipping to change at line 69 | |||
ObjectBufferStream() : OS(SV) {} | ObjectBufferStream() : OS(SV) {} | |||
virtual ~ObjectBufferStream() {} | virtual ~ObjectBufferStream() {} | |||
raw_ostream &getOStream() { return OS; } | raw_ostream &getOStream() { return OS; } | |||
void flush() | void flush() | |||
{ | { | |||
OS.flush(); | OS.flush(); | |||
// Make the data accessible via the ObjectBuffer::Buffer | // Make the data accessible via the ObjectBuffer::Buffer | |||
Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()) , | Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()) , | |||
"", | "", | |||
false)); | false)); | |||
} | } | |||
protected: | protected: | |||
SmallVector<char, 4096> SV; // Working buffer into which we JIT. | SmallVector<char, 4096> SV; // Working buffer into which we JIT. | |||
raw_svector_ostream OS; // streaming wrapper | raw_svector_ostream OS; // streaming wrapper | |||
}; | }; | |||
} // namespace llvm | } // namespace llvm | |||
#endif | #endif | |||
End of changes. 6 change blocks. | ||||
6 lines changed or deleted | 6 lines changed or added | |||
ObjectFile.h | ObjectFile.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares a file format independent ObjectFile class. | // This file declares a file format independent ObjectFile class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_OBJECT_OBJECT_FILE_H | #ifndef LLVM_OBJECT_OBJECTFILE_H | |||
#define LLVM_OBJECT_OBJECT_FILE_H | #define LLVM_OBJECT_OBJECTFILE_H | |||
#include "llvm/Object/Binary.h" | ||||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Object/Binary.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include "llvm/Support/MemoryBuffer.h" | #include "llvm/Support/MemoryBuffer.h" | |||
#include <cstring> | #include <cstring> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
namespace object { | namespace object { | |||
class ObjectFile; | class ObjectFile; | |||
skipping to change at line 220 | skipping to change at line 220 | |||
bool operator==(const SymbolRef &Other) const; | bool operator==(const SymbolRef &Other) const; | |||
bool operator<(const SymbolRef &Other) const; | bool operator<(const SymbolRef &Other) const; | |||
error_code getNext(SymbolRef &Result) const; | error_code getNext(SymbolRef &Result) const; | |||
error_code getName(StringRef &Result) const; | error_code getName(StringRef &Result) const; | |||
/// Returns the symbol virtual address (i.e. address at which it will be | /// Returns the symbol virtual address (i.e. address at which it will be | |||
/// mapped). | /// mapped). | |||
error_code getAddress(uint64_t &Result) const; | error_code getAddress(uint64_t &Result) const; | |||
error_code getFileOffset(uint64_t &Result) const; | error_code getFileOffset(uint64_t &Result) const; | |||
/// @brief Get the alignment of this symbol as the actual value (not log | ||||
2). | ||||
error_code getAlignment(uint32_t &Result) const; | ||||
error_code getSize(uint64_t &Result) const; | error_code getSize(uint64_t &Result) const; | |||
error_code getType(SymbolRef::Type &Result) const; | error_code getType(SymbolRef::Type &Result) const; | |||
/// Returns the ascii char that should be displayed in a symbol table dum p via | /// Returns the ascii char that should be displayed in a symbol table dum p via | |||
/// nm for this symbol. | /// nm for this symbol. | |||
error_code getNMTypeChar(char &Result) const; | error_code getNMTypeChar(char &Result) const; | |||
/// Get symbol flags (bitwise OR of SymbolRef::Flags) | /// Get symbol flags (bitwise OR of SymbolRef::Flags) | |||
error_code getFlags(uint32_t &Result) const; | error_code getFlags(uint32_t &Result) const; | |||
/// @brief Return true for common symbols such as uninitialized globals | ||||
error_code isCommon(bool &Result) const; | ||||
/// @brief Get section this symbol is defined in reference to. Result is | /// @brief Get section this symbol is defined in reference to. Result is | |||
/// end_sections() if it is undefined or is an absolute symbol. | /// end_sections() if it is undefined or is an absolute symbol. | |||
error_code getSection(section_iterator &Result) const; | error_code getSection(section_iterator &Result) const; | |||
/// @brief Get value of the symbol in the symbol table. | /// @brief Get value of the symbol in the symbol table. | |||
error_code getValue(uint64_t &Val) const; | error_code getValue(uint64_t &Val) const; | |||
DataRefImpl getRawDataRefImpl() const; | DataRefImpl getRawDataRefImpl() const; | |||
}; | }; | |||
typedef content_iterator<SymbolRef> symbol_iterator; | typedef content_iterator<SymbolRef> symbol_iterator; | |||
skipping to change at line 279 | skipping to change at line 278 | |||
/// ObjectFile - This class is the base class for all object file types. | /// ObjectFile - This class is the base class for all object file types. | |||
/// Concrete instances of this object are created by createObjectFile, whic h | /// Concrete instances of this object are created by createObjectFile, whic h | |||
/// figures out which type to create. | /// figures out which type to create. | |||
class ObjectFile : public Binary { | class ObjectFile : public Binary { | |||
virtual void anchor(); | virtual void anchor(); | |||
ObjectFile() LLVM_DELETED_FUNCTION; | ObjectFile() LLVM_DELETED_FUNCTION; | |||
ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION; | ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION; | |||
protected: | protected: | |||
ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec); | ObjectFile(unsigned int Type, MemoryBuffer *source); | |||
const uint8_t *base() const { | const uint8_t *base() const { | |||
return reinterpret_cast<const uint8_t *>(Data->getBufferStart()); | return reinterpret_cast<const uint8_t *>(Data->getBufferStart()); | |||
} | } | |||
// These functions are for SymbolRef to call internally. The main goal of | // These functions are for SymbolRef to call internally. The main goal of | |||
// this is to allow SymbolRef::SymbolPimpl to point directly to the symbo l | // this is to allow SymbolRef::SymbolPimpl to point directly to the symbo l | |||
// entry in the memory mapped object file. SymbolPimpl cannot contain any | // entry in the memory mapped object file. SymbolPimpl cannot contain any | |||
// virtual functions because then it could not point into the memory mapp ed | // virtual functions because then it could not point into the memory mapp ed | |||
// file. | // file. | |||
// | // | |||
// Implementations assume that the DataRefImpl is valid and has not been | // Implementations assume that the DataRefImpl is valid and has not been | |||
// modified externally. It's UB otherwise. | // modified externally. It's UB otherwise. | |||
friend class SymbolRef; | friend class SymbolRef; | |||
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0; | virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0; | |||
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0; | virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0; | |||
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) cons t = 0; | virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) cons t = 0; | |||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res)co nst=0; | virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res)co nst=0; | |||
virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) co nst; | ||||
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0; | virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0; | |||
virtual error_code getSymbolType(DataRefImpl Symb, | virtual error_code getSymbolType(DataRefImpl Symb, | |||
SymbolRef::Type &Res) const = 0; | SymbolRef::Type &Res) const = 0; | |||
virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0; | virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0; | |||
virtual error_code getSymbolFlags(DataRefImpl Symb, | virtual error_code getSymbolFlags(DataRefImpl Symb, | |||
uint32_t &Res) const = 0; | uint32_t &Res) const = 0; | |||
virtual error_code getSymbolSection(DataRefImpl Symb, | virtual error_code getSymbolSection(DataRefImpl Symb, | |||
section_iterator &Res) const = 0; | section_iterator &Res) const = 0; | |||
virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const = 0; | virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const = 0; | |||
skipping to change at line 430 | skipping to change at line 430 | |||
} | } | |||
inline error_code SymbolRef::getAddress(uint64_t &Result) const { | inline error_code SymbolRef::getAddress(uint64_t &Result) const { | |||
return OwningObject->getSymbolAddress(SymbolPimpl, Result); | return OwningObject->getSymbolAddress(SymbolPimpl, Result); | |||
} | } | |||
inline error_code SymbolRef::getFileOffset(uint64_t &Result) const { | inline error_code SymbolRef::getFileOffset(uint64_t &Result) const { | |||
return OwningObject->getSymbolFileOffset(SymbolPimpl, Result); | return OwningObject->getSymbolFileOffset(SymbolPimpl, Result); | |||
} | } | |||
inline error_code SymbolRef::getAlignment(uint32_t &Result) const { | ||||
return OwningObject->getSymbolAlignment(SymbolPimpl, Result); | ||||
} | ||||
inline error_code SymbolRef::getSize(uint64_t &Result) const { | inline error_code SymbolRef::getSize(uint64_t &Result) const { | |||
return OwningObject->getSymbolSize(SymbolPimpl, Result); | return OwningObject->getSymbolSize(SymbolPimpl, Result); | |||
} | } | |||
inline error_code SymbolRef::getNMTypeChar(char &Result) const { | inline error_code SymbolRef::getNMTypeChar(char &Result) const { | |||
return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result); | return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result); | |||
} | } | |||
inline error_code SymbolRef::getFlags(uint32_t &Result) const { | inline error_code SymbolRef::getFlags(uint32_t &Result) const { | |||
return OwningObject->getSymbolFlags(SymbolPimpl, Result); | return OwningObject->getSymbolFlags(SymbolPimpl, Result); | |||
End of changes. 8 change blocks. | ||||
7 lines changed or deleted | 12 lines changed or added | |||
ObjectImage.h | ObjectImage.h | |||
---|---|---|---|---|
//===---- ObjectImage.h - Format independent executuable object image ----- ===// | //===---- ObjectImage.h - Format independent executuable object image ----- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares a file format independent ObjectImage class. | // This file declares a file format independent ObjectImage class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H | #ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H | |||
#define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H | #define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H | |||
#include "llvm/Object/ObjectFile.h" | ||||
#include "llvm/ExecutionEngine/ObjectBuffer.h" | #include "llvm/ExecutionEngine/ObjectBuffer.h" | |||
#include "llvm/Object/ObjectFile.h" | ||||
namespace llvm { | namespace llvm { | |||
/// ObjectImage - A container class that represents an ObjectFile that has been | /// ObjectImage - A container class that represents an ObjectFile that has been | |||
/// or is in the process of being loaded into memory for execution. | /// or is in the process of being loaded into memory for execution. | |||
class ObjectImage { | class ObjectImage { | |||
ObjectImage() LLVM_DELETED_FUNCTION; | ObjectImage() LLVM_DELETED_FUNCTION; | |||
ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION; | ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION; | |||
protected: | protected: | |||
skipping to change at line 46 | skipping to change at line 46 | |||
virtual object::symbol_iterator end_symbols() const = 0; | virtual object::symbol_iterator end_symbols() const = 0; | |||
virtual object::section_iterator begin_sections() const = 0; | virtual object::section_iterator begin_sections() const = 0; | |||
virtual object::section_iterator end_sections() const = 0; | virtual object::section_iterator end_sections() const = 0; | |||
virtual /* Triple::ArchType */ unsigned getArch() const = 0; | virtual /* Triple::ArchType */ unsigned getArch() const = 0; | |||
// Subclasses can override these methods to update the image with loaded | // Subclasses can override these methods to update the image with loaded | |||
// addresses for sections and common symbols | // addresses for sections and common symbols | |||
virtual void updateSectionAddress(const object::SectionRef &Sec, | virtual void updateSectionAddress(const object::SectionRef &Sec, | |||
uint64_t Addr) = 0; | uint64_t Addr) = 0; | |||
virtual void updateSymbolAddress(const object::SymbolRef &Sym, | virtual void updateSymbolAddress(const object::SymbolRef &Sym, | |||
uint64_t Addr) = 0; | uint64_t Addr) = 0; | |||
virtual StringRef getData() const = 0; | virtual StringRef getData() const = 0; | |||
virtual object::ObjectFile* getObjectFile() const = 0; | ||||
// Subclasses can override these methods to provide JIT debugging support | // Subclasses can override these methods to provide JIT debugging support | |||
virtual void registerWithDebugger() = 0; | virtual void registerWithDebugger() = 0; | |||
virtual void deregisterWithDebugger() = 0; | virtual void deregisterWithDebugger() = 0; | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H | #endif // LLVM_EXECUTIONENGINE_OBJECTIMAGE_H | |||
End of changes. 7 change blocks. | ||||
4 lines changed or deleted | 6 lines changed or added | |||
OperandTraits.h | OperandTraits.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the traits classes that are handy for enforcing the co rrect | // This file defines the traits classes that are handy for enforcing the co rrect | |||
// layout of various User subclasses. It also provides the means for access ing | // layout of various User subclasses. It also provides the means for access ing | |||
// the operands in the most efficient manner. | // the operands in the most efficient manner. | |||
// | // | |||
#ifndef LLVM_OPERAND_TRAITS_H | #ifndef LLVM_IR_OPERANDTRAITS_H | |||
#define LLVM_OPERAND_TRAITS_H | #define LLVM_IR_OPERANDTRAITS_H | |||
#include "llvm/User.h" | #include "llvm/IR/User.h" | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// FixedNumOperand Trait Class | // FixedNumOperand Trait Class | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// FixedNumOperandTraits - determine the allocation regime of the Use arra y | /// FixedNumOperandTraits - determine the allocation regime of the Use arra y | |||
/// when it is a prefix to the User object, and the number of Use objects i s | /// when it is a prefix to the User object, and the number of Use objects i s | |||
/// known at compile time. | /// known at compile time. | |||
End of changes. 2 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
Operator.h | Operator.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines various classes for working with Instructions and | // This file defines various classes for working with Instructions and | |||
// ConstantExprs. | // ConstantExprs. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_OPERATOR_H | #ifndef LLVM_IR_OPERATOR_H | |||
#define LLVM_OPERATOR_H | #define LLVM_IR_OPERATOR_H | |||
#include "llvm/Constants.h" | #include "llvm/IR/Constants.h" | |||
#include "llvm/DerivedTypes.h" | #include "llvm/IR/DataLayout.h" | |||
#include "llvm/Instruction.h" | #include "llvm/IR/DerivedTypes.h" | |||
#include "llvm/Type.h" | #include "llvm/IR/Instruction.h" | |||
#include "llvm/IR/Type.h" | ||||
#include "llvm/Support/GetElementPtrTypeIterator.h" | ||||
namespace llvm { | namespace llvm { | |||
class GetElementPtrInst; | class GetElementPtrInst; | |||
class BinaryOperator; | class BinaryOperator; | |||
class ConstantExpr; | class ConstantExpr; | |||
/// Operator - This is a utility class that provides an abstraction for the | /// Operator - This is a utility class that provides an abstraction for the | |||
/// common functionality between Instructions and ConstantExprs. | /// common functionality between Instructions and ConstantExprs. | |||
/// | /// | |||
class Operator : public User { | class Operator : public User { | |||
private: | private: | |||
// Do not implement any of these. The Operator class is intended to be us | // The Operator class is intended to be used as a utility, and is never i | |||
ed | tself | |||
// as a utility, and is never itself instantiated. | // instantiated. | |||
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; | void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; | |||
void *operator new(size_t s) LLVM_DELETED_FUNCTION; | void *operator new(size_t s) LLVM_DELETED_FUNCTION; | |||
Operator() LLVM_DELETED_FUNCTION; | Operator() LLVM_DELETED_FUNCTION; | |||
protected: | protected: | |||
// NOTE: Cannot use LLVM_DELETED_FUNCTION because it's not legal to delet e | // NOTE: Cannot use LLVM_DELETED_FUNCTION because it's not legal to delet e | |||
// an overridden method that's not deleted in the base class. Cannot leav e | // an overridden method that's not deleted in the base class. Cannot leav e | |||
// this unimplemented because that leads to an ODR-violation. | // this unimplemented because that leads to an ODR-violation. | |||
~Operator(); | ~Operator(); | |||
skipping to change at line 167 | skipping to change at line 169 | |||
} | } | |||
static inline bool classof(const Instruction *I) { | static inline bool classof(const Instruction *I) { | |||
return isPossiblyExactOpcode(I->getOpcode()); | return isPossiblyExactOpcode(I->getOpcode()); | |||
} | } | |||
static inline bool classof(const Value *V) { | static inline bool classof(const Value *V) { | |||
return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || | return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || | |||
(isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); | (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); | |||
} | } | |||
}; | }; | |||
/// Convenience struct for specifying and reasoning about fast-math flags. | ||||
class FastMathFlags { | ||||
private: | ||||
friend class FPMathOperator; | ||||
unsigned Flags; | ||||
FastMathFlags(unsigned F) : Flags(F) { } | ||||
public: | ||||
enum { | ||||
UnsafeAlgebra = (1 << 0), | ||||
NoNaNs = (1 << 1), | ||||
NoInfs = (1 << 2), | ||||
NoSignedZeros = (1 << 3), | ||||
AllowReciprocal = (1 << 4) | ||||
}; | ||||
FastMathFlags() : Flags(0) | ||||
{ } | ||||
/// Whether any flag is set | ||||
bool any() { return Flags != 0; } | ||||
/// Set all the flags to false | ||||
void clear() { Flags = 0; } | ||||
/// Flag queries | ||||
bool noNaNs() { return 0 != (Flags & NoNaNs); } | ||||
bool noInfs() { return 0 != (Flags & NoInfs); } | ||||
bool noSignedZeros() { return 0 != (Flags & NoSignedZeros); } | ||||
bool allowReciprocal() { return 0 != (Flags & AllowReciprocal); } | ||||
bool unsafeAlgebra() { return 0 != (Flags & UnsafeAlgebra); } | ||||
/// Flag setters | ||||
void setNoNaNs() { Flags |= NoNaNs; } | ||||
void setNoInfs() { Flags |= NoInfs; } | ||||
void setNoSignedZeros() { Flags |= NoSignedZeros; } | ||||
void setAllowReciprocal() { Flags |= AllowReciprocal; } | ||||
void setUnsafeAlgebra() { | ||||
Flags |= UnsafeAlgebra; | ||||
setNoNaNs(); | ||||
setNoInfs(); | ||||
setNoSignedZeros(); | ||||
setAllowReciprocal(); | ||||
} | ||||
}; | ||||
/// FPMathOperator - Utility class for floating point operations which can have | /// FPMathOperator - Utility class for floating point operations which can have | |||
/// information about relaxed accuracy requirements attached to them. | /// information about relaxed accuracy requirements attached to them. | |||
class FPMathOperator : public Operator { | class FPMathOperator : public Operator { | |||
private: | ||||
friend class Instruction; | ||||
void setHasUnsafeAlgebra(bool B) { | ||||
SubclassOptionalData = | ||||
(SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) | | ||||
(B * FastMathFlags::UnsafeAlgebra); | ||||
// Unsafe algebra implies all the others | ||||
if (B) { | ||||
setHasNoNaNs(true); | ||||
setHasNoInfs(true); | ||||
setHasNoSignedZeros(true); | ||||
setHasAllowReciprocal(true); | ||||
} | ||||
} | ||||
void setHasNoNaNs(bool B) { | ||||
SubclassOptionalData = | ||||
(SubclassOptionalData & ~FastMathFlags::NoNaNs) | | ||||
(B * FastMathFlags::NoNaNs); | ||||
} | ||||
void setHasNoInfs(bool B) { | ||||
SubclassOptionalData = | ||||
(SubclassOptionalData & ~FastMathFlags::NoInfs) | | ||||
(B * FastMathFlags::NoInfs); | ||||
} | ||||
void setHasNoSignedZeros(bool B) { | ||||
SubclassOptionalData = | ||||
(SubclassOptionalData & ~FastMathFlags::NoSignedZeros) | | ||||
(B * FastMathFlags::NoSignedZeros); | ||||
} | ||||
void setHasAllowReciprocal(bool B) { | ||||
SubclassOptionalData = | ||||
(SubclassOptionalData & ~FastMathFlags::AllowReciprocal) | | ||||
(B * FastMathFlags::AllowReciprocal); | ||||
} | ||||
/// Convenience function for setting all the fast-math flags | ||||
void setFastMathFlags(FastMathFlags FMF) { | ||||
SubclassOptionalData |= FMF.Flags; | ||||
} | ||||
public: | public: | |||
/// Test whether this operation is permitted to be | ||||
/// algebraically transformed, aka the 'A' fast-math property. | ||||
bool hasUnsafeAlgebra() const { | ||||
return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0; | ||||
} | ||||
/// Test whether this operation's arguments and results are to be | ||||
/// treated as non-NaN, aka the 'N' fast-math property. | ||||
bool hasNoNaNs() const { | ||||
return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0; | ||||
} | ||||
/// Test whether this operation's arguments and results are to be | ||||
/// treated as NoN-Inf, aka the 'I' fast-math property. | ||||
bool hasNoInfs() const { | ||||
return (SubclassOptionalData & FastMathFlags::NoInfs) != 0; | ||||
} | ||||
/// Test whether this operation can treat the sign of zero | ||||
/// as insignificant, aka the 'S' fast-math property. | ||||
bool hasNoSignedZeros() const { | ||||
return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0; | ||||
} | ||||
/// Test whether this operation is permitted to use | ||||
/// reciprocal instead of division, aka the 'R' fast-math property. | ||||
bool hasAllowReciprocal() const { | ||||
return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0; | ||||
} | ||||
/// Convenience function for getting all the fast-math flags | ||||
FastMathFlags getFastMathFlags() const { | ||||
return FastMathFlags(SubclassOptionalData); | ||||
} | ||||
/// \brief Get the maximum error permitted by this operation in ULPs. An | /// \brief Get the maximum error permitted by this operation in ULPs. An | |||
/// accuracy of 0.0 means that the operation should be performed with the | /// accuracy of 0.0 means that the operation should be performed with the | |||
/// default precision. | /// default precision. | |||
float getFPAccuracy() const; | float getFPAccuracy() const; | |||
static inline bool classof(const Instruction *I) { | static inline bool classof(const Instruction *I) { | |||
return I->getType()->isFPOrFPVectorTy(); | return I->getType()->isFPOrFPVectorTy(); | |||
} | } | |||
static inline bool classof(const Value *V) { | static inline bool classof(const Value *V) { | |||
skipping to change at line 306 | skipping to change at line 430 | |||
/// hasAllConstantIndices - Return true if all of the indices of this GEP are | /// hasAllConstantIndices - Return true if all of the indices of this GEP are | |||
/// constant integers. If so, the result pointer and the first operand h ave | /// constant integers. If so, the result pointer and the first operand h ave | |||
/// a constant offset between them. | /// a constant offset between them. | |||
bool hasAllConstantIndices() const { | bool hasAllConstantIndices() const { | |||
for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { | for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { | |||
if (!isa<ConstantInt>(I)) | if (!isa<ConstantInt>(I)) | |||
return false; | return false; | |||
} | } | |||
return true; | return true; | |||
} | } | |||
/// \brief Accumulate the constant address offset of this GEP if possible | ||||
. | ||||
/// | ||||
/// This routine accepts an APInt into which it will accumulate the const | ||||
ant | ||||
/// offset of this GEP if the GEP is in fact constant. If the GEP is not | ||||
/// all-constant, it returns false and the value of the offset APInt is | ||||
/// undefined (it is *not* preserved!). The APInt passed into this routin | ||||
e | ||||
/// must be at least as wide as the IntPtr type for the address space of | ||||
/// the base GEP pointer. | ||||
bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const | ||||
{ | ||||
assert(Offset.getBitWidth() == | ||||
DL.getPointerSizeInBits(getPointerAddressSpace()) && | ||||
"The offset must have exactly as many bits as our pointer."); | ||||
for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(t | ||||
his); | ||||
GTI != GTE; ++GTI) { | ||||
ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand()); | ||||
if (!OpC) | ||||
return false; | ||||
if (OpC->isZero()) | ||||
continue; | ||||
// Handle a struct index, which adds its field offset to the pointer. | ||||
if (StructType *STy = dyn_cast<StructType>(*GTI)) { | ||||
unsigned ElementIdx = OpC->getZExtValue(); | ||||
const StructLayout *SL = DL.getStructLayout(STy); | ||||
Offset += APInt(Offset.getBitWidth(), | ||||
SL->getElementOffset(ElementIdx)); | ||||
continue; | ||||
} | ||||
// For array or vector indices, scale the index by the size of the ty | ||||
pe. | ||||
APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth()); | ||||
Offset += Index * APInt(Offset.getBitWidth(), | ||||
DL.getTypeAllocSize(GTI.getIndexedType())); | ||||
} | ||||
return true; | ||||
} | ||||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 7 change blocks. | ||||
9 lines changed or deleted | 178 lines changed or added | |||
Optional.h | Optional.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file provides Optional, a template class modeled in the spirit of | // This file provides Optional, a template class modeled in the spirit of | |||
// OCaml's 'opt' variant. The idea is to strongly type whether or not | // OCaml's 'opt' variant. The idea is to strongly type whether or not | |||
// a value can be optional. | // a value can be optional. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_OPTIONAL | #ifndef LLVM_ADT_OPTIONAL_H | |||
#define LLVM_ADT_OPTIONAL | #define LLVM_ADT_OPTIONAL_H | |||
#include "llvm/ADT/None.h" | ||||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/AlignOf.h" | ||||
#include <cassert> | #include <cassert> | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
#include <utility> | #include <utility> | |||
#endif | #endif | |||
namespace llvm { | namespace llvm { | |||
template<typename T> | template<typename T> | |||
class Optional { | class Optional { | |||
T x; | AlignedCharArrayUnion<T> storage; | |||
unsigned hasVal : 1; | bool hasVal; | |||
public: | public: | |||
explicit Optional() : x(), hasVal(false) {} | Optional(NoneType) : hasVal(false) {} | |||
Optional(const T &y) : x(y), hasVal(true) {} | explicit Optional() : hasVal(false) {} | |||
Optional(const T &y) : hasVal(true) { | ||||
new (storage.buffer) T(y); | ||||
} | ||||
Optional(const Optional &O) : hasVal(O.hasVal) { | ||||
if (hasVal) | ||||
new (storage.buffer) T(*O); | ||||
} | ||||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {} | Optional(T &&y) : hasVal(true) { | |||
new (storage.buffer) T(std::forward<T>(y)); | ||||
} | ||||
Optional(Optional<T> &&O) : hasVal(O) { | ||||
if (O) { | ||||
new (storage.buffer) T(std::move(*O)); | ||||
O.reset(); | ||||
} | ||||
} | ||||
Optional &operator=(T &&y) { | ||||
if (hasVal) | ||||
**this = std::move(y); | ||||
else { | ||||
new (storage.buffer) T(std::move(y)); | ||||
hasVal = true; | ||||
} | ||||
return *this; | ||||
} | ||||
Optional &operator=(Optional &&O) { | ||||
if (!O) | ||||
reset(); | ||||
else { | ||||
*this = std::move(*O); | ||||
O.reset(); | ||||
} | ||||
return *this; | ||||
} | ||||
#endif | #endif | |||
static inline Optional create(const T* y) { | static inline Optional create(const T* y) { | |||
return y ? Optional(*y) : Optional(); | return y ? Optional(*y) : Optional(); | |||
} | } | |||
// FIXME: these assignments (& the equivalent const T&/const Optional& ct | ||||
ors) | ||||
// could be made more efficient by passing by value, possibly unifying th | ||||
em | ||||
// with the rvalue versions above - but this could place a different set | ||||
of | ||||
// requirements (notably: the existence of a default ctor) when implement | ||||
ed | ||||
// in that way. Careful SFINAE to avoid such pitfalls would be required. | ||||
Optional &operator=(const T &y) { | Optional &operator=(const T &y) { | |||
x = y; | if (hasVal) | |||
hasVal = true; | **this = y; | |||
else { | ||||
new (storage.buffer) T(y); | ||||
hasVal = true; | ||||
} | ||||
return *this; | return *this; | |||
} | } | |||
const T* getPointer() const { assert(hasVal); return &x; } | Optional &operator=(const Optional &O) { | |||
const T& getValue() const { assert(hasVal); return x; } | if (!O) | |||
reset(); | ||||
else | ||||
*this = *O; | ||||
return *this; | ||||
} | ||||
operator bool() const { return hasVal; } | void reset() { | |||
if (hasVal) { | ||||
(**this).~T(); | ||||
hasVal = false; | ||||
} | ||||
} | ||||
~Optional() { | ||||
reset(); | ||||
} | ||||
const T* getPointer() const { assert(hasVal); return reinterpret_cast<con | ||||
st T*>(storage.buffer); } | ||||
T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buf | ||||
fer); } | ||||
const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return * | ||||
getPointer(); } | ||||
T& getValue() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer() | ||||
; } | ||||
LLVM_EXPLICIT operator bool() const { return hasVal; } | ||||
bool hasValue() const { return hasVal; } | bool hasValue() const { return hasVal; } | |||
const T* operator->() const { return getPointer(); } | const T* operator->() const { return getPointer(); } | |||
const T& operator*() const { assert(hasVal); return x; } | T* operator->() { return getPointer(); } | |||
const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return | ||||
*getPointer(); } | ||||
T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer( | ||||
); } | ||||
#if LLVM_HAS_RVALUE_REFERENCE_THIS | ||||
T&& getValue() && { assert(hasVal); return std::move(*getPointer()); } | ||||
T&& operator*() && { assert(hasVal); return std::move(*getPointer()); } | ||||
#endif | ||||
}; | }; | |||
template<typename T> struct simplify_type; | template <typename T> struct isPodLike; | |||
template <typename T> struct isPodLike<Optional<T> > { | ||||
template <typename T> | // An Optional<T> is pod-like if T is. | |||
struct simplify_type<const Optional<T> > { | static const bool value = isPodLike<T>::value; | |||
typedef const T* SimpleType; | ||||
static SimpleType getSimplifiedValue(const Optional<T> &Val) { | ||||
return Val.getPointer(); | ||||
} | ||||
}; | }; | |||
template <typename T> | ||||
struct simplify_type<Optional<T> > | ||||
: public simplify_type<const Optional<T> > {}; | ||||
/// \brief Poison comparison between two \c Optional objects. Clients needs to | /// \brief Poison comparison between two \c Optional objects. Clients needs to | |||
/// explicitly compare the underlying values and account for empty \c Optio nal | /// explicitly compare the underlying values and account for empty \c Optio nal | |||
/// objects. | /// objects. | |||
/// | /// | |||
/// This routine will never be defined. It returns \c void to help diagnose | /// This routine will never be defined. It returns \c void to help diagnose | |||
/// errors at compile time. | /// errors at compile time. | |||
template<typename T, typename U> | template<typename T, typename U> | |||
void operator==(const Optional<T> &X, const Optional<U> &Y); | void operator==(const Optional<T> &X, const Optional<U> &Y); | |||
/// \brief Poison comparison between two \c Optional objects. Clients needs to | /// \brief Poison comparison between two \c Optional objects. Clients needs to | |||
End of changes. 14 change blocks. | ||||
27 lines changed or deleted | 101 lines changed or added | |||
OwningPtr.h | OwningPtr.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines and implements the OwningPtr class. | // This file defines and implements the OwningPtr class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_OWNING_PTR_H | #ifndef LLVM_ADT_OWNINGPTR_H | |||
#define LLVM_ADT_OWNING_PTR_H | #define LLVM_ADT_OWNINGPTR_H | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include <cassert> | #include <cassert> | |||
#include <cstddef> | #include <cstddef> | |||
namespace llvm { | namespace llvm { | |||
/// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except th at it | /// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except th at it | |||
/// guarantees deletion of the object pointed to, either on destruction of the | /// guarantees deletion of the object pointed to, either on destruction of the | |||
/// OwningPtr or via an explicit reset(). Once created, ownership of the | /// OwningPtr or via an explicit reset(). Once created, ownership of the | |||
/// pointee object can be taken away from OwningPtr by using the take metho d. | /// pointee object can be taken away from OwningPtr by using the take metho d. | |||
template<class T> | template<class T> | |||
class OwningPtr { | class OwningPtr { | |||
OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION; | OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION; | |||
OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION; | OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION; | |||
T *Ptr; | T *Ptr; | |||
public: | public: | |||
explicit OwningPtr(T *P = 0) : Ptr(P) {} | explicit OwningPtr(T *P = 0) : Ptr(P) {} | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {} | OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {} | |||
OwningPtr &operator=(OwningPtr &&Other) { | OwningPtr &operator=(OwningPtr &&Other) { | |||
reset(Other.take()); | reset(Other.take()); | |||
return *this; | return *this; | |||
} | } | |||
#endif | #endif | |||
~OwningPtr() { | ~OwningPtr() { | |||
delete Ptr; | delete Ptr; | |||
skipping to change at line 98 | skipping to change at line 98 | |||
/// OwningArrayPtr smart pointer - OwningArrayPtr provides the same | /// OwningArrayPtr smart pointer - OwningArrayPtr provides the same | |||
/// functionality as OwningPtr, except that it works for array types. | /// functionality as OwningPtr, except that it works for array types. | |||
template<class T> | template<class T> | |||
class OwningArrayPtr { | class OwningArrayPtr { | |||
OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION; | OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION; | |||
OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION; | OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION; | |||
T *Ptr; | T *Ptr; | |||
public: | public: | |||
explicit OwningArrayPtr(T *P = 0) : Ptr(P) {} | explicit OwningArrayPtr(T *P = 0) : Ptr(P) {} | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {} | OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {} | |||
OwningArrayPtr &operator=(OwningArrayPtr &&Other) { | OwningArrayPtr &operator=(OwningArrayPtr &&Other) { | |||
reset(Other.take()); | reset(Other.take()); | |||
return *this; | return *this; | |||
} | } | |||
#endif | #endif | |||
~OwningArrayPtr() { | ~OwningArrayPtr() { | |||
delete [] Ptr; | delete [] Ptr; | |||
End of changes. 3 change blocks. | ||||
4 lines changed or deleted | 4 lines changed or added | |||
PHITransAddr.h | PHITransAddr.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the PHITransAddr class. | // This file declares the PHITransAddr class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_PHITRANSADDR_H | #ifndef LLVM_ANALYSIS_PHITRANSADDR_H | |||
#define LLVM_ANALYSIS_PHITRANSADDR_H | #define LLVM_ANALYSIS_PHITRANSADDR_H | |||
#include "llvm/Instruction.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/IR/Instruction.h" | ||||
namespace llvm { | namespace llvm { | |||
class DominatorTree; | class DominatorTree; | |||
class DataLayout; | class DataLayout; | |||
class TargetLibraryInfo; | class TargetLibraryInfo; | |||
/// PHITransAddr - An address value which tracks and handles phi translatio n. | /// PHITransAddr - An address value which tracks and handles phi translatio n. | |||
/// As we walk "up" the CFG through predecessors, we need to ensure that th e | /// As we walk "up" the CFG through predecessors, we need to ensure that th e | |||
/// address we're tracking is kept up to date. For example, if we're analy zing | /// address we're tracking is kept up to date. For example, if we're analy zing | |||
/// an address of "&A[i]" and walk through the definition of 'i' which is a PHI | /// an address of "&A[i]" and walk through the definition of 'i' which is a PHI | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Pass.h | Pass.h | |||
---|---|---|---|---|
skipping to change at line 106 | skipping to change at line 106 | |||
/// implemented in terms of the name that is registered by one of the | /// implemented in terms of the name that is registered by one of the | |||
/// Registration templates, but can be overloaded directly. | /// Registration templates, but can be overloaded directly. | |||
/// | /// | |||
virtual const char *getPassName() const; | virtual const char *getPassName() const; | |||
/// getPassID - Return the PassID number that corresponds to this pass. | /// getPassID - Return the PassID number that corresponds to this pass. | |||
AnalysisID getPassID() const { | AnalysisID getPassID() const { | |||
return PassID; | return PassID; | |||
} | } | |||
/// doInitialization - Virtual method overridden by subclasses to do | ||||
/// any necessary initialization before any pass is run. | ||||
/// | ||||
virtual bool doInitialization(Module &) { return false; } | ||||
/// doFinalization - Virtual method overriden by subclasses to do any | ||||
/// necessary clean up after all passes have run. | ||||
/// | ||||
virtual bool doFinalization(Module &) { return false; } | ||||
/// print - Print out the internal state of the pass. This is called by | /// print - Print out the internal state of the pass. This is called by | |||
/// Analyze to print out the contents of an analysis. Otherwise it is no t | /// Analyze to print out the contents of an analysis. Otherwise it is no t | |||
/// necessary to implement this method. Beware that the module pointer M AY be | /// necessary to implement this method. Beware that the module pointer M AY be | |||
/// null. This automatically forwards to a virtual function that does no t | /// null. This automatically forwards to a virtual function that does no t | |||
/// provide the Module* in case the analysis doesn't need it it can just be | /// provide the Module* in case the analysis doesn't need it it can just be | |||
/// ignored. | /// ignored. | |||
/// | /// | |||
virtual void print(raw_ostream &O, const Module *M) const; | virtual void print(raw_ostream &O, const Module *M) const; | |||
void dump() const; // dump - Print to stderr. | void dump() const; // dump - Print to stderr. | |||
skipping to change at line 287 | skipping to change at line 297 | |||
/// 2. Optimizing a function does not cause the addition or removal of any | /// 2. Optimizing a function does not cause the addition or removal of any | |||
/// functions in the module | /// functions in the module | |||
/// | /// | |||
class FunctionPass : public Pass { | class FunctionPass : public Pass { | |||
public: | public: | |||
explicit FunctionPass(char &pid) : Pass(PT_Function, pid) {} | explicit FunctionPass(char &pid) : Pass(PT_Function, pid) {} | |||
/// createPrinterPass - Get a function printer pass. | /// createPrinterPass - Get a function printer pass. | |||
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; | Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; | |||
/// doInitialization - Virtual method overridden by subclasses to do | ||||
/// any necessary per-module initialization. | ||||
/// | ||||
virtual bool doInitialization(Module &); | ||||
/// runOnFunction - Virtual method overriden by subclasses to do the | /// runOnFunction - Virtual method overriden by subclasses to do the | |||
/// per-function processing of the pass. | /// per-function processing of the pass. | |||
/// | /// | |||
virtual bool runOnFunction(Function &F) = 0; | virtual bool runOnFunction(Function &F) = 0; | |||
/// doFinalization - Virtual method overriden by subclasses to do any pos | ||||
t | ||||
/// processing needed after all passes have run. | ||||
/// | ||||
virtual bool doFinalization(Module &); | ||||
virtual void assignPassManager(PMStack &PMS, | virtual void assignPassManager(PMStack &PMS, | |||
PassManagerType T); | PassManagerType T); | |||
/// Return what kind of Pass Manager can manage this pass. | /// Return what kind of Pass Manager can manage this pass. | |||
virtual PassManagerType getPotentialPassManagerType() const; | virtual PassManagerType getPotentialPassManagerType() const; | |||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// BasicBlockPass class - This class is used to implement most local | /// BasicBlockPass class - This class is used to implement most local | |||
/// optimizations. Optimizations should subclass this class if they | /// optimizations. Optimizations should subclass this class if they | |||
skipping to change at line 326 | skipping to change at line 326 | |||
/// other basic block in the function. | /// other basic block in the function. | |||
/// 3. Optimizations conform to all of the constraints of FunctionPasses. | /// 3. Optimizations conform to all of the constraints of FunctionPasses. | |||
/// | /// | |||
class BasicBlockPass : public Pass { | class BasicBlockPass : public Pass { | |||
public: | public: | |||
explicit BasicBlockPass(char &pid) : Pass(PT_BasicBlock, pid) {} | explicit BasicBlockPass(char &pid) : Pass(PT_BasicBlock, pid) {} | |||
/// createPrinterPass - Get a basic block printer pass. | /// createPrinterPass - Get a basic block printer pass. | |||
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; | Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; | |||
/// doInitialization - Virtual method overridden by subclasses to do | using llvm::Pass::doInitialization; | |||
/// any necessary per-module initialization. | using llvm::Pass::doFinalization; | |||
/// | ||||
virtual bool doInitialization(Module &); | ||||
/// doInitialization - Virtual method overridden by BasicBlockPass subcla sses | /// doInitialization - Virtual method overridden by BasicBlockPass subcla sses | |||
/// to do any necessary per-function initialization. | /// to do any necessary per-function initialization. | |||
/// | /// | |||
virtual bool doInitialization(Function &); | virtual bool doInitialization(Function &); | |||
/// runOnBasicBlock - Virtual method overriden by subclasses to do the | /// runOnBasicBlock - Virtual method overriden by subclasses to do the | |||
/// per-basicblock processing of the pass. | /// per-basicblock processing of the pass. | |||
/// | /// | |||
virtual bool runOnBasicBlock(BasicBlock &BB) = 0; | virtual bool runOnBasicBlock(BasicBlock &BB) = 0; | |||
/// doFinalization - Virtual method overriden by BasicBlockPass subclasse s to | /// doFinalization - Virtual method overriden by BasicBlockPass subclasse s to | |||
/// do any post processing needed after all passes have run. | /// do any post processing needed after all passes have run. | |||
/// | /// | |||
virtual bool doFinalization(Function &); | virtual bool doFinalization(Function &); | |||
/// doFinalization - Virtual method overriden by subclasses to do any pos | ||||
t | ||||
/// processing needed after all passes have run. | ||||
/// | ||||
virtual bool doFinalization(Module &); | ||||
virtual void assignPassManager(PMStack &PMS, | virtual void assignPassManager(PMStack &PMS, | |||
PassManagerType T); | PassManagerType T); | |||
/// Return what kind of Pass Manager can manage this pass. | /// Return what kind of Pass Manager can manage this pass. | |||
virtual PassManagerType getPotentialPassManagerType() const; | virtual PassManagerType getPotentialPassManagerType() const; | |||
}; | }; | |||
/// If the user specifies the -time-passes argument on an LLVM tool command line | /// If the user specifies the -time-passes argument on an LLVM tool command line | |||
/// then the value of this boolean will be true, otherwise false. | /// then the value of this boolean will be true, otherwise false. | |||
/// @brief This is the storage for the -time-passes option. | /// @brief This is the storage for the -time-passes option. | |||
End of changes. 5 change blocks. | ||||
21 lines changed or deleted | 12 lines changed or added | |||
PassAnalysisSupport.h | PassAnalysisSupport.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file defines stuff that is used to define and "use" Analysis Passes . | // This file defines stuff that is used to define and "use" Analysis Passes . | |||
// This file is automatically #included by Pass.h, so: | // This file is automatically #included by Pass.h, so: | |||
// | // | |||
// NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY | // NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY | |||
// | // | |||
// Instead, #include Pass.h | // Instead, #include Pass.h | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_PASS_ANALYSIS_SUPPORT_H | #ifndef LLVM_PASSANALYSISSUPPORT_H | |||
#define LLVM_PASS_ANALYSIS_SUPPORT_H | #define LLVM_PASSANALYSISSUPPORT_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Pass.h" | ||||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// AnalysisUsage - Represent the analysis usage information of a pass. Thi s | // AnalysisUsage - Represent the analysis usage information of a pass. Thi s | |||
// tracks analyses that the pass REQUIRES (must be available when the pass | // tracks analyses that the pass REQUIRES (must be available when the pass | |||
// runs), REQUIRES TRANSITIVE (must be available throughout the lifetime of the | // runs), REQUIRES TRANSITIVE (must be available throughout the lifetime of the | |||
// pass), and analyses that the pass PRESERVES (the pass does not invalidat e the | // pass), and analyses that the pass PRESERVES (the pass does not invalidat e the | |||
// results of these analyses). This information is provided by a pass to t he | // results of these analyses). This information is provided by a pass to t he | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
PassManager.h | PassManager.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// maintain, and optimize execution of Passes. The PassManager class ensur es | // maintain, and optimize execution of Passes. The PassManager class ensur es | |||
// that analysis results are available before a pass runs, and that Pass's are | // that analysis results are available before a pass runs, and that Pass's are | |||
// destroyed when the PassManager is destroyed. | // destroyed when the PassManager is destroyed. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_PASSMANAGER_H | #ifndef LLVM_PASSMANAGER_H | |||
#define LLVM_PASSMANAGER_H | #define LLVM_PASSMANAGER_H | |||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
#include "llvm/Support/CBindingWrapping.h" | ||||
namespace llvm { | namespace llvm { | |||
class Pass; | class Pass; | |||
class Module; | class Module; | |||
class PassManagerImpl; | class PassManagerImpl; | |||
class FunctionPassManagerImpl; | class FunctionPassManagerImpl; | |||
/// PassManagerBase - An abstract interface to allow code to add passes to | /// PassManagerBase - An abstract interface to allow code to add passes to | |||
skipping to change at line 101 | skipping to change at line 102 | |||
/// doFinalization - Run all of the finalizers for the function passes. | /// doFinalization - Run all of the finalizers for the function passes. | |||
/// | /// | |||
bool doFinalization(); | bool doFinalization(); | |||
private: | private: | |||
FunctionPassManagerImpl *FPM; | FunctionPassManagerImpl *FPM; | |||
Module *M; | Module *M; | |||
}; | }; | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef) | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 4 lines changed or added | |||
PassManagerBuilder.h | PassManagerBuilder.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
|* *| | |* *| | |||
|* This file is distributed under the University of Illinois Open Source *| | |* This file is distributed under the University of Illinois Open Source *| | |||
|* License. See LICENSE.TXT for details. *| | |* License. See LICENSE.TXT for details. *| | |||
|* *| | |* *| | |||
|*===---------------------------------------------------------------------- ===*| | |*===---------------------------------------------------------------------- ===*| | |||
|* *| | |* *| | |||
|* This header declares the C interface to the PassManagerBuilder class. *| | |* This header declares the C interface to the PassManagerBuilder class. *| | |||
|* *| | |* *| | |||
\*===---------------------------------------------------------------------- ===*/ | \*===---------------------------------------------------------------------- ===*/ | |||
#ifndef LLVM_C_PASSMANAGERBUILDER | #ifndef LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H | |||
#define LLVM_C_PASSMANAGERBUILDER | #define LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H | |||
#include "llvm-c/Core.h" | #include "llvm-c/Core.h" | |||
typedef struct LLVMOpaquePassManagerBuilder *LLVMPassManagerBuilderRef; | typedef struct LLVMOpaquePassManagerBuilder *LLVMPassManagerBuilderRef; | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
#include "llvm/Transforms/IPO/PassManagerBuilder.h" | #include "llvm/Transforms/IPO/PassManagerBuilder.h" | |||
extern "C" { | extern "C" { | |||
#endif | #endif | |||
skipping to change at line 80 | skipping to change at line 80 | |||
LLVMPassManagerRef PM); | LLVMPassManagerRef PM); | |||
/** See llvm::PassManagerBuilder::populateModulePassManager. */ | /** See llvm::PassManagerBuilder::populateModulePassManager. */ | |||
void | void | |||
LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef P MB, | LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef P MB, | |||
LLVMPassManagerRef PM); | LLVMPassManagerRef PM); | |||
/** See llvm::PassManagerBuilder::populateLTOPassManager. */ | /** See llvm::PassManagerBuilder::populateLTOPassManager. */ | |||
void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB, | void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB, | |||
LLVMPassManagerRef PM, | LLVMPassManagerRef PM, | |||
bool Internalize, | LLVMBool Internalize, | |||
bool RunInliner); | LLVMBool RunInliner); | |||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} | } | |||
namespace llvm { | ||||
inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) { | ||||
return reinterpret_cast<PassManagerBuilder*>(P); | ||||
} | ||||
inline LLVMPassManagerBuilderRef wrap(PassManagerBuilder *P) { | ||||
return reinterpret_cast<LLVMPassManagerBuilderRef>(P); | ||||
} | ||||
} | ||||
#endif | #endif | |||
#endif | #endif | |||
End of changes. 3 change blocks. | ||||
14 lines changed or deleted | 4 lines changed or added | |||
PassManagers.h | PassManagers.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the LLVM Pass Manager infrastructure. | // This file declares the LLVM Pass Manager infrastructure. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_PASSMANAGERS_H | #ifndef LLVM_PASSMANAGERS_H | |||
#define LLVM_PASSMANAGERS_H | #define LLVM_PASSMANAGERS_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/SmallPtrSet.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include <vector> | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/Pass.h" | ||||
#include <map> | #include <map> | |||
#include <vector> | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Overview: | // Overview: | |||
// The Pass Manager Infrastructure manages passes. It's responsibilities ar e: | // The Pass Manager Infrastructure manages passes. It's responsibilities ar e: | |||
// | // | |||
// o Manage optimization pass execution order | // o Manage optimization pass execution order | |||
// o Make required Analysis information available before pass P is run | // o Make required Analysis information available before pass P is run | |||
// o Release memory occupied by dead passes | // o Release memory occupied by dead passes | |||
// o If Analysis information is dirtied by a pass then regenerate Analysi s | // o If Analysis information is dirtied by a pass then regenerate Analysi s | |||
// information before it is consumed by another pass. | // information before it is consumed by another pass. | |||
skipping to change at line 169 | skipping to change at line 169 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// PMTopLevelManager | // PMTopLevelManager | |||
// | // | |||
/// PMTopLevelManager manages LastUser info and collects common APIs used b y | /// PMTopLevelManager manages LastUser info and collects common APIs used b y | |||
/// top level pass managers. | /// top level pass managers. | |||
class PMTopLevelManager { | class PMTopLevelManager { | |||
protected: | protected: | |||
explicit PMTopLevelManager(PMDataManager *PMDM); | explicit PMTopLevelManager(PMDataManager *PMDM); | |||
virtual unsigned getNumContainedManagers() const { | unsigned getNumContainedManagers() const { | |||
return (unsigned)PassManagers.size(); | return (unsigned)PassManagers.size(); | |||
} | } | |||
void initializeAllAnalysisInfo(); | void initializeAllAnalysisInfo(); | |||
private: | private: | |||
virtual PMDataManager *getAsPMDataManager() = 0; | virtual PMDataManager *getAsPMDataManager() = 0; | |||
virtual PassManagerType getTopLevelPassManagerType() = 0; | virtual PassManagerType getTopLevelPassManagerType() = 0; | |||
public: | public: | |||
skipping to change at line 341 | skipping to change at line 341 | |||
void setDepth(unsigned newDepth) { Depth = newDepth; } | void setDepth(unsigned newDepth) { Depth = newDepth; } | |||
// Print routines used by debug-pass | // Print routines used by debug-pass | |||
void dumpLastUses(Pass *P, unsigned Offset) const; | void dumpLastUses(Pass *P, unsigned Offset) const; | |||
void dumpPassArguments() const; | void dumpPassArguments() const; | |||
void dumpPassInfo(Pass *P, enum PassDebuggingString S1, | void dumpPassInfo(Pass *P, enum PassDebuggingString S1, | |||
enum PassDebuggingString S2, StringRef Msg); | enum PassDebuggingString S2, StringRef Msg); | |||
void dumpRequiredSet(const Pass *P) const; | void dumpRequiredSet(const Pass *P) const; | |||
void dumpPreservedSet(const Pass *P) const; | void dumpPreservedSet(const Pass *P) const; | |||
virtual unsigned getNumContainedPasses() const { | unsigned getNumContainedPasses() const { | |||
return (unsigned)PassVector.size(); | return (unsigned)PassVector.size(); | |||
} | } | |||
virtual PassManagerType getPassManagerType() const { | virtual PassManagerType getPassManagerType() const { | |||
assert ( 0 && "Invalid use of getPassManagerType"); | assert ( 0 && "Invalid use of getPassManagerType"); | |||
return PMT_Unknown; | return PMT_Unknown; | |||
} | } | |||
std::map<AnalysisID, Pass*> *getAvailableAnalysis() { | DenseMap<AnalysisID, Pass*> *getAvailableAnalysis() { | |||
return &AvailableAnalysis; | return &AvailableAnalysis; | |||
} | } | |||
// Collect AvailableAnalysis from all the active Pass Managers. | // Collect AvailableAnalysis from all the active Pass Managers. | |||
void populateInheritedAnalysis(PMStack &PMS) { | void populateInheritedAnalysis(PMStack &PMS) { | |||
unsigned Index = 0; | unsigned Index = 0; | |||
for (PMStack::iterator I = PMS.begin(), E = PMS.end(); | for (PMStack::iterator I = PMS.begin(), E = PMS.end(); | |||
I != E; ++I) | I != E; ++I) | |||
InheritedAnalysis[Index++] = (*I)->getAvailableAnalysis(); | InheritedAnalysis[Index++] = (*I)->getAvailableAnalysis(); | |||
} | } | |||
skipping to change at line 373 | skipping to change at line 373 | |||
// Top level manager. | // Top level manager. | |||
PMTopLevelManager *TPM; | PMTopLevelManager *TPM; | |||
// Collection of pass that are managed by this manager | // Collection of pass that are managed by this manager | |||
SmallVector<Pass *, 16> PassVector; | SmallVector<Pass *, 16> PassVector; | |||
// Collection of Analysis provided by Parent pass manager and | // Collection of Analysis provided by Parent pass manager and | |||
// used by current pass manager. At at time there can not be more | // used by current pass manager. At at time there can not be more | |||
// then PMT_Last active pass mangers. | // then PMT_Last active pass mangers. | |||
std::map<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last]; | DenseMap<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last]; | |||
/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executio ns | /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executio ns | |||
/// or higher is specified. | /// or higher is specified. | |||
bool isPassDebuggingExecutionsOrMore() const; | bool isPassDebuggingExecutionsOrMore() const; | |||
private: | private: | |||
void dumpAnalysisUsage(StringRef Msg, const Pass *P, | void dumpAnalysisUsage(StringRef Msg, const Pass *P, | |||
const AnalysisUsage::VectorType &Set) const; | const AnalysisUsage::VectorType &Set) const; | |||
// Set of available Analysis. This information is used while scheduling | // Set of available Analysis. This information is used while scheduling | |||
// pass. If a pass requires an analysis which is not available then | // pass. If a pass requires an analysis which is not available then | |||
// the required analysis pass is scheduled to run before the pass itself is | // the required analysis pass is scheduled to run before the pass itself is | |||
// scheduled to run. | // scheduled to run. | |||
std::map<AnalysisID, Pass*> AvailableAnalysis; | DenseMap<AnalysisID, Pass*> AvailableAnalysis; | |||
// Collection of higher level analysis used by the pass managed by | // Collection of higher level analysis used by the pass managed by | |||
// this manager. | // this manager. | |||
SmallVector<Pass *, 8> HigherLevelAnalysis; | SmallVector<Pass *, 8> HigherLevelAnalysis; | |||
unsigned Depth; | unsigned Depth; | |||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// FPPassManager | // FPPassManager | |||
skipping to change at line 417 | skipping to change at line 417 | |||
: ModulePass(ID), PMDataManager() { } | : ModulePass(ID), PMDataManager() { } | |||
/// run - Execute all of the passes scheduled for execution. Keep track of | /// run - Execute all of the passes scheduled for execution. Keep track of | |||
/// whether any of the passes modifies the module, and if so, return true . | /// whether any of the passes modifies the module, and if so, return true . | |||
bool runOnFunction(Function &F); | bool runOnFunction(Function &F); | |||
bool runOnModule(Module &M); | bool runOnModule(Module &M); | |||
/// cleanup - After running all passes, clean up pass manager cache. | /// cleanup - After running all passes, clean up pass manager cache. | |||
void cleanup(); | void cleanup(); | |||
/// doInitialization - Overrides ModulePass doInitialization for global | ||||
/// initialization tasks | ||||
/// | ||||
using ModulePass::doInitialization; | ||||
/// doInitialization - Run all of the initializers for the function passe s. | /// doInitialization - Run all of the initializers for the function passe s. | |||
/// | /// | |||
bool doInitialization(Module &M); | bool doInitialization(Module &M); | |||
/// doFinalization - Overrides ModulePass doFinalization for global | ||||
/// finalization tasks | ||||
/// | ||||
using ModulePass::doFinalization; | ||||
/// doFinalization - Run all of the finalizers for the function passes. | /// doFinalization - Run all of the finalizers for the function passes. | |||
/// | /// | |||
bool doFinalization(Module &M); | bool doFinalization(Module &M); | |||
virtual PMDataManager *getAsPMDataManager() { return this; } | virtual PMDataManager *getAsPMDataManager() { return this; } | |||
virtual Pass *getAsPass() { return this; } | virtual Pass *getAsPass() { return this; } | |||
/// Pass Manager itself does not invalidate any analysis info. | /// Pass Manager itself does not invalidate any analysis info. | |||
void getAnalysisUsage(AnalysisUsage &Info) const { | void getAnalysisUsage(AnalysisUsage &Info) const { | |||
Info.setPreservesAll(); | Info.setPreservesAll(); | |||
End of changes. 11 change blocks. | ||||
9 lines changed or deleted | 19 lines changed or added | |||
PassNameParser.h | PassNameParser.h | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// | // | |||
// The PassNameParser class adds ALL passes linked into the system (that ar e | // The PassNameParser class adds ALL passes linked into the system (that ar e | |||
// creatable) as command line arguments to the tool (when instantiated with the | // creatable) as command line arguments to the tool (when instantiated with the | |||
// appropriate command line option template). The FilteredPassNameParser<> | // appropriate command line option template). The FilteredPassNameParser<> | |||
// template is used for the same purposes as PassNameParser, except that it only | // template is used for the same purposes as PassNameParser, except that it only | |||
// includes passes that have a PassType that are compatible with the filter | // includes passes that have a PassType that are compatible with the filter | |||
// (which is the template argument). | // (which is the template argument). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H | #ifndef LLVM_SUPPORT_PASSNAMEPARSER_H | |||
#define LLVM_SUPPORT_PASS_NAME_PARSER_H | #define LLVM_SUPPORT_PASSNAMEPARSER_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/ADT/STLExtras.h" | #include "llvm/ADT/STLExtras.h" | |||
#include "llvm/Pass.h" | ||||
#include "llvm/Support/CommandLine.h" | #include "llvm/Support/CommandLine.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
#include <cstring> | #include <cstring> | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// PassNameParser class - Make use of the pass registration mechanism to | // PassNameParser class - Make use of the pass registration mechanism to | |||
// automatically add a command line argument to opt for each pass. | // automatically add a command line argument to opt for each pass. | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
PassRegistry.h | PassRegistry.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// and registration of passes. At application startup, passes are register ed | // and registration of passes. At application startup, passes are register ed | |||
// with the PassRegistry, which is later provided to the PassManager for | // with the PassRegistry, which is later provided to the PassManager for | |||
// dependency resolution and similar tasks. | // dependency resolution and similar tasks. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_PASSREGISTRY_H | #ifndef LLVM_PASSREGISTRY_H | |||
#define LLVM_PASSREGISTRY_H | #define LLVM_PASSREGISTRY_H | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/CBindingWrapping.h" | ||||
#include "llvm-c/Core.h" | ||||
namespace llvm { | namespace llvm { | |||
class PassInfo; | class PassInfo; | |||
struct PassRegistrationListener; | struct PassRegistrationListener; | |||
/// PassRegistry - This class manages the registration and intitialization of | /// PassRegistry - This class manages the registration and intitialization of | |||
/// the pass subsystem as application startup, and assists the PassManager | /// the pass subsystem as application startup, and assists the PassManager | |||
/// in resolving pass dependencies. | /// in resolving pass dependencies. | |||
/// NOTE: PassRegistry is NOT thread-safe. If you want to use LLVM on mult iple | /// NOTE: PassRegistry is NOT thread-safe. If you want to use LLVM on mult iple | |||
skipping to change at line 82 | skipping to change at line 84 | |||
/// addRegistrationListener - Register the given PassRegistrationListener | /// addRegistrationListener - Register the given PassRegistrationListener | |||
/// to receive passRegistered() callbacks whenever a new pass is register ed. | /// to receive passRegistered() callbacks whenever a new pass is register ed. | |||
void addRegistrationListener(PassRegistrationListener *L); | void addRegistrationListener(PassRegistrationListener *L); | |||
/// removeRegistrationListener - Unregister a PassRegistrationListener so that | /// removeRegistrationListener - Unregister a PassRegistrationListener so that | |||
/// it no longer receives passRegistered() callbacks. | /// it no longer receives passRegistered() callbacks. | |||
void removeRegistrationListener(PassRegistrationListener *L); | void removeRegistrationListener(PassRegistrationListener *L); | |||
}; | }; | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassRegistry, LLVMPassRegistryRef) | ||||
} | } | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 5 lines changed or added | |||
PassSupport.h | PassSupport.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// is automatically #included by Pass.h, so: | // is automatically #included by Pass.h, so: | |||
// | // | |||
// NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY | // NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY | |||
// | // | |||
// Instead, #include Pass.h. | // Instead, #include Pass.h. | |||
// | // | |||
// This file defines Pass registration code and classes used for it. | // This file defines Pass registration code and classes used for it. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_PASS_SUPPORT_H | #ifndef LLVM_PASSSUPPORT_H | |||
#define LLVM_PASS_SUPPORT_H | #define LLVM_PASSSUPPORT_H | |||
#include "Pass.h" | #include "Pass.h" | |||
#include "llvm/PassRegistry.h" | ||||
#include "llvm/InitializePasses.h" | #include "llvm/InitializePasses.h" | |||
#include "llvm/PassRegistry.h" | ||||
#include "llvm/Support/Atomic.h" | #include "llvm/Support/Atomic.h" | |||
#include "llvm/Support/Valgrind.h" | #include "llvm/Support/Valgrind.h" | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ----- | //===---------------------------------------------------------------------- ----- | |||
/// PassInfo class - An instance of this class exists for every pass known by | /// PassInfo class - An instance of this class exists for every pass known by | |||
/// the system, and can be obtained from a live Pass by calling its | /// the system, and can be obtained from a live Pass by calling its | |||
/// getPassInfo() method. These objects are set up by the RegisterPass<> | /// getPassInfo() method. These objects are set up by the RegisterPass<> | |||
skipping to change at line 305 | skipping to change at line 305 | |||
} \ | } \ | |||
void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ | void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ | |||
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ | CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ | |||
} | } | |||
//===---------------------------------------------------------------------- ----- | //===---------------------------------------------------------------------- ----- | |||
/// PassRegistrationListener class - This class is meant to be derived from by | /// PassRegistrationListener class - This class is meant to be derived from by | |||
/// clients that are interested in which passes get registered and unregist ered | /// clients that are interested in which passes get registered and unregist ered | |||
/// at runtime (which can be because of the RegisterPass constructors being run | /// at runtime (which can be because of the RegisterPass constructors being run | |||
/// as the program starts up, or may be because a shared object just got | /// as the program starts up, or may be because a shared object just got | |||
/// loaded). Deriving from the PassRegistationListener class automatically | /// loaded). Deriving from the PassRegistrationListener class automaticall y | |||
/// registers your object to receive callbacks indicating when passes are l oaded | /// registers your object to receive callbacks indicating when passes are l oaded | |||
/// and removed. | /// and removed. | |||
/// | /// | |||
struct PassRegistrationListener { | struct PassRegistrationListener { | |||
/// PassRegistrationListener ctor - Add the current object to the list of | /// PassRegistrationListener ctor - Add the current object to the list of | |||
/// PassRegistrationListeners... | /// PassRegistrationListeners... | |||
PassRegistrationListener(); | PassRegistrationListener(); | |||
/// dtor - Remove object from list of listeners... | /// dtor - Remove object from list of listeners... | |||
End of changes. 4 change blocks. | ||||
4 lines changed or deleted | 4 lines changed or added | |||
Passes.h | Passes.h | |||
---|---|---|---|---|
skipping to change at line 28 | skipping to change at line 28 | |||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
#include "llvm/Target/TargetMachine.h" | #include "llvm/Target/TargetMachine.h" | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class FunctionPass; | class FunctionPass; | |||
class MachineFunctionPass; | class MachineFunctionPass; | |||
class PassInfo; | class PassInfo; | |||
class PassManagerBase; | class PassManagerBase; | |||
class TargetLoweringBase; | ||||
class TargetLowering; | class TargetLowering; | |||
class TargetRegisterClass; | class TargetRegisterClass; | |||
class raw_ostream; | class raw_ostream; | |||
} | } | |||
namespace llvm { | namespace llvm { | |||
class PassConfigImpl; | class PassConfigImpl; | |||
/// Discriminated union of Pass ID types. | ||||
/// | ||||
/// The PassConfig API prefers dealing with IDs because they are safer and | ||||
more | ||||
/// efficient. IDs decouple configuration from instantiation. This way, whe | ||||
n a | ||||
/// pass is overriden, it isn't unnecessarily instantiated. It is also unsa | ||||
fe to | ||||
/// refer to a Pass pointer after adding it to a pass manager, which delete | ||||
s | ||||
/// redundant pass instances. | ||||
/// | ||||
/// However, it is convient to directly instantiate target passes with | ||||
/// non-default ctors. These often don't have a registered PassInfo. Rather | ||||
than | ||||
/// force all target passes to implement the pass registry boilerplate, all | ||||
ow | ||||
/// the PassConfig API to handle either type. | ||||
/// | ||||
/// AnalysisID is sadly char*, so PointerIntPair won't work. | ||||
class IdentifyingPassPtr { | ||||
union { | ||||
AnalysisID ID; | ||||
Pass *P; | ||||
}; | ||||
bool IsInstance; | ||||
public: | ||||
IdentifyingPassPtr() : P(0), IsInstance(false) {} | ||||
IdentifyingPassPtr(AnalysisID IDPtr) : ID(IDPtr), IsInstance(false) {} | ||||
IdentifyingPassPtr(Pass *InstancePtr) : P(InstancePtr), IsInstance(true) | ||||
{} | ||||
bool isValid() const { return P; } | ||||
bool isInstance() const { return IsInstance; } | ||||
AnalysisID getID() const { | ||||
assert(!IsInstance && "Not a Pass ID"); | ||||
return ID; | ||||
} | ||||
Pass *getInstance() const { | ||||
assert(IsInstance && "Not a Pass Instance"); | ||||
return P; | ||||
} | ||||
}; | ||||
template <> struct isPodLike<IdentifyingPassPtr> { | ||||
static const bool value = true; | ||||
}; | ||||
/// Target-Independent Code Generator Pass Configuration Options. | /// Target-Independent Code Generator Pass Configuration Options. | |||
/// | /// | |||
/// This is an ImmutablePass solely for the purpose of exposing CodeGen opt ions | /// This is an ImmutablePass solely for the purpose of exposing CodeGen opt ions | |||
/// to the internals of other CodeGen passes. | /// to the internals of other CodeGen passes. | |||
class TargetPassConfig : public ImmutablePass { | class TargetPassConfig : public ImmutablePass { | |||
public: | public: | |||
/// Pseudo Pass IDs. These are defined within TargetPassConfig because th ey | /// Pseudo Pass IDs. These are defined within TargetPassConfig because th ey | |||
/// are unregistered pass IDs. They are only useful for use with | /// are unregistered pass IDs. They are only useful for use with | |||
/// TargetPassConfig APIs to identify multiple occurrences of the same pa ss. | /// TargetPassConfig APIs to identify multiple occurrences of the same pa ss. | |||
/// | /// | |||
skipping to change at line 119 | skipping to change at line 162 | |||
} | } | |||
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); } | void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); } | |||
bool getEnableTailMerge() const { return EnableTailMerge; } | bool getEnableTailMerge() const { return EnableTailMerge; } | |||
void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); } | void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); } | |||
/// Allow the target to override a specific pass without overriding the p ass | /// Allow the target to override a specific pass without overriding the p ass | |||
/// pipeline. When passes are added to the standard pipeline at the | /// pipeline. When passes are added to the standard pipeline at the | |||
/// point where StandardID is expected, add TargetID in its place. | /// point where StandardID is expected, add TargetID in its place. | |||
void substitutePass(AnalysisID StandardID, AnalysisID TargetID); | void substitutePass(AnalysisID StandardID, IdentifyingPassPtr TargetID); | |||
/// Insert InsertedPassID pass after TargetPassID pass. | /// Insert InsertedPassID pass after TargetPassID pass. | |||
void insertPass(AnalysisID TargetPassID, AnalysisID InsertedPassID); | void insertPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassI D); | |||
/// Allow the target to enable a specific standard pass by default. | /// Allow the target to enable a specific standard pass by default. | |||
void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); } | void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); } | |||
/// Allow the target to disable a specific standard pass by default. | /// Allow the target to disable a specific standard pass by default. | |||
void disablePass(AnalysisID PassID) { substitutePass(PassID, 0); } | void disablePass(AnalysisID PassID) { | |||
substitutePass(PassID, IdentifyingPassPtr()); | ||||
} | ||||
/// Return the pass substituted for StandardID by the target. | /// Return the pass substituted for StandardID by the target. | |||
/// If no substitution exists, return StandardID. | /// If no substitution exists, return StandardID. | |||
AnalysisID getPassSubstitution(AnalysisID StandardID) const; | IdentifyingPassPtr getPassSubstitution(AnalysisID StandardID) const; | |||
/// Return true if the optimized regalloc pipeline is enabled. | /// Return true if the optimized regalloc pipeline is enabled. | |||
bool getOptimizeRegAlloc() const; | bool getOptimizeRegAlloc() const; | |||
/// Add common target configurable passes that perform LLVM IR to IR | /// Add common target configurable passes that perform LLVM IR to IR | |||
/// transforms following machine independent optimization. | /// transforms following machine independent optimization. | |||
virtual void addIRPasses(); | virtual void addIRPasses(); | |||
/// Add passes to lower exception handling for the code generator. | /// Add passes to lower exception handling for the code generator. | |||
void addPassesToHandleExceptions(); | void addPassesToHandleExceptions(); | |||
/// Add pass to prepare the LLVM IR for code generation. This should be d | ||||
one | ||||
/// before exception handling preparation passes. | ||||
virtual void addCodeGenPrepare(); | ||||
/// Add common passes that perform LLVM IR to IR transforms in preparatio n for | /// Add common passes that perform LLVM IR to IR transforms in preparatio n for | |||
/// instruction selection. | /// instruction selection. | |||
virtual void addISelPrepare(); | virtual void addISelPrepare(); | |||
/// addInstSelector - This method should install an instruction selector pass, | /// addInstSelector - This method should install an instruction selector pass, | |||
/// which converts from LLVM code to machine instructions. | /// which converts from LLVM code to machine instructions. | |||
virtual bool addInstSelector() { | virtual bool addInstSelector() { | |||
return true; | return true; | |||
} | } | |||
skipping to change at line 179 | skipping to change at line 228 | |||
/// addPreISelPasses - This method should add any "last minute" LLVM->LLV M | /// addPreISelPasses - This method should add any "last minute" LLVM->LLV M | |||
/// passes (which are run just before instruction selector). | /// passes (which are run just before instruction selector). | |||
virtual bool addPreISel() { | virtual bool addPreISel() { | |||
return true; | return true; | |||
} | } | |||
/// addMachineSSAOptimization - Add standard passes that optimize machine | /// addMachineSSAOptimization - Add standard passes that optimize machine | |||
/// instructions in SSA form. | /// instructions in SSA form. | |||
virtual void addMachineSSAOptimization(); | virtual void addMachineSSAOptimization(); | |||
/// Add passes that optimize instruction level parallelism for out-of-ord | ||||
er | ||||
/// targets. These passes are run while the machine code is still in SSA | ||||
/// form, so they can use MachineTraceMetrics to control their heuristics | ||||
. | ||||
/// | ||||
/// All passes added here should preserve the MachineDominatorTree, | ||||
/// MachineLoopInfo, and MachineTraceMetrics analyses. | ||||
virtual bool addILPOpts() { | ||||
return false; | ||||
} | ||||
/// addPreRegAlloc - This method may be implemented by targets that want to | /// addPreRegAlloc - This method may be implemented by targets that want to | |||
/// run passes immediately before register allocation. This should return | /// run passes immediately before register allocation. This should return | |||
/// true if -print-machineinstrs should print after these passes. | /// true if -print-machineinstrs should print after these passes. | |||
virtual bool addPreRegAlloc() { | virtual bool addPreRegAlloc() { | |||
return false; | return false; | |||
} | } | |||
/// createTargetRegisterAllocator - Create the register allocator pass fo r | /// createTargetRegisterAllocator - Create the register allocator pass fo r | |||
/// this target at the current optimization level. | /// this target at the current optimization level. | |||
virtual FunctionPass *createTargetRegisterAllocator(bool Optimized); | virtual FunctionPass *createTargetRegisterAllocator(bool Optimized); | |||
skipping to change at line 210 | skipping to change at line 269 | |||
/// rewritten to physical registers. | /// rewritten to physical registers. | |||
/// | /// | |||
/// These passes must preserve VirtRegMap and LiveIntervals, and when run ning | /// These passes must preserve VirtRegMap and LiveIntervals, and when run ning | |||
/// after RABasic or RAGreedy, they should take advantage of LiveRegMatri x. | /// after RABasic or RAGreedy, they should take advantage of LiveRegMatri x. | |||
/// When these passes run, VirtRegMap contains legal physreg assignments for | /// When these passes run, VirtRegMap contains legal physreg assignments for | |||
/// all virtual registers. | /// all virtual registers. | |||
virtual bool addPreRewrite() { | virtual bool addPreRewrite() { | |||
return false; | return false; | |||
} | } | |||
/// addFinalizeRegAlloc - This method may be implemented by targets that | ||||
want | ||||
/// to run passes within the regalloc pipeline, immediately after the reg | ||||
ister | ||||
/// allocation pass itself. These passes run as soon as virtual regisiter | ||||
s | ||||
/// have been rewritten to physical registers but before and other postRA | ||||
/// optimization happens. Targets that have marked instructions for bundl | ||||
ing | ||||
/// must have finalized those bundles by the time these passes have run, | ||||
/// because subsequent passes are not guaranteed to be bundle-aware. | ||||
virtual bool addFinalizeRegAlloc() { | ||||
return false; | ||||
} | ||||
/// addPostRegAlloc - This method may be implemented by targets that want to | /// addPostRegAlloc - This method may be implemented by targets that want to | |||
/// run passes after register allocation pass pipeline but before | /// run passes after register allocation pass pipeline but before | |||
/// prolog-epilog insertion. This should return true if -print-machinein strs | /// prolog-epilog insertion. This should return true if -print-machinein strs | |||
/// should print after these passes. | /// should print after these passes. | |||
virtual bool addPostRegAlloc() { | virtual bool addPostRegAlloc() { | |||
return false; | return false; | |||
} | } | |||
/// Add passes that optimize machine instructions after register allocati on. | /// Add passes that optimize machine instructions after register allocati on. | |||
virtual void addMachineLateOptimization(); | virtual void addMachineLateOptimization(); | |||
/// addPreSched2 - This method may be implemented by targets that want to | /// addPreSched2 - This method may be implemented by targets that want to | |||
/// run passes after prolog-epilog insertion and before the second instru ction | /// run passes after prolog-epilog insertion and before the second instru ction | |||
/// scheduling pass. This should return true if -print-machineinstrs sho uld | /// scheduling pass. This should return true if -print-machineinstrs sho uld | |||
/// print after these passes. | /// print after these passes. | |||
virtual bool addPreSched2() { | virtual bool addPreSched2() { | |||
return false; | return false; | |||
} | } | |||
/// addGCPasses - Add late codegen passes that analyze code for garbage | ||||
/// collection. This should return true if GC info should be printed afte | ||||
r | ||||
/// these passes. | ||||
virtual bool addGCPasses(); | ||||
/// Add standard basic block placement passes. | /// Add standard basic block placement passes. | |||
virtual void addBlockPlacement(); | virtual void addBlockPlacement(); | |||
/// addPreEmitPass - This pass may be implemented by targets that want to run | /// addPreEmitPass - This pass may be implemented by targets that want to run | |||
/// passes immediately before machine code is emitted. This should retur n | /// passes immediately before machine code is emitted. This should retur n | |||
/// true if -print-machineinstrs should print out the code after the pass es. | /// true if -print-machineinstrs should print out the code after the pass es. | |||
virtual bool addPreEmitPass() { | virtual bool addPreEmitPass() { | |||
return false; | return false; | |||
} | } | |||
skipping to change at line 274 | skipping to change at line 327 | |||
/// printAndVerify - Add a pass to dump then verify the machine function, if | /// printAndVerify - Add a pass to dump then verify the machine function, if | |||
/// those steps are enabled. | /// those steps are enabled. | |||
/// | /// | |||
void printAndVerify(const char *Banner); | void printAndVerify(const char *Banner); | |||
}; | }; | |||
} // namespace llvm | } // namespace llvm | |||
/// List of target independent CodeGen pass IDs. | /// List of target independent CodeGen pass IDs. | |||
namespace llvm { | namespace llvm { | |||
/// \brief Create a basic TargetTransformInfo analysis pass. | ||||
/// | ||||
/// This pass implements the target transform info analysis using the tar | ||||
get | ||||
/// independent information available to the LLVM code generator. | ||||
ImmutablePass * | ||||
createBasicTargetTransformInfoPass(const TargetLoweringBase *TLI); | ||||
/// createUnreachableBlockEliminationPass - The LLVM code generator does not | /// createUnreachableBlockEliminationPass - The LLVM code generator does not | |||
/// work well with unreachable basic blocks (what live ranges make sense for a | /// work well with unreachable basic blocks (what live ranges make sense for a | |||
/// block that cannot be reached?). As such, a code generator should eit her | /// block that cannot be reached?). As such, a code generator should eit her | |||
/// not instruction select unreachable blocks, or run this pass as its | /// not instruction select unreachable blocks, or run this pass as its | |||
/// last LLVM modifying pass to clean up blocks that are not reachable fr om | /// last LLVM modifying pass to clean up blocks that are not reachable fr om | |||
/// the entry block. | /// the entry block. | |||
FunctionPass *createUnreachableBlockEliminationPass(); | FunctionPass *createUnreachableBlockEliminationPass(); | |||
/// MachineFunctionPrinter pass - This pass prints out the machine functi on to | /// MachineFunctionPrinter pass - This pass prints out the machine functi on to | |||
/// the given stream as a debugging tool. | /// the given stream as a debugging tool. | |||
MachineFunctionPass * | MachineFunctionPass * | |||
createMachineFunctionPrinterPass(raw_ostream &OS, | createMachineFunctionPrinterPass(raw_ostream &OS, | |||
const std::string &Banner =""); | const std::string &Banner =""); | |||
/// MachineLoopInfo - This pass is a loop analysis pass. | /// MachineLoopInfo - This pass is a loop analysis pass. | |||
extern char &MachineLoopInfoID; | extern char &MachineLoopInfoID; | |||
/// MachineLoopRanges - This pass is an on-demand loop coverage analysis. | ||||
extern char &MachineLoopRangesID; | ||||
/// MachineDominators - This pass is a machine dominators analysis pass. | /// MachineDominators - This pass is a machine dominators analysis pass. | |||
extern char &MachineDominatorsID; | extern char &MachineDominatorsID; | |||
/// EdgeBundles analysis - Bundle machine CFG edges. | /// EdgeBundles analysis - Bundle machine CFG edges. | |||
extern char &EdgeBundlesID; | extern char &EdgeBundlesID; | |||
/// LiveVariables pass - This pass computes the set of blocks in which ea ch | /// LiveVariables pass - This pass computes the set of blocks in which ea ch | |||
/// variable is life and sets machine operand kill flags. | /// variable is life and sets machine operand kill flags. | |||
extern char &LiveVariablesID; | extern char &LiveVariablesID; | |||
skipping to change at line 423 | skipping to change at line 480 | |||
/// MachineBlockPlacement - This pass places basic blocks based on branch | /// MachineBlockPlacement - This pass places basic blocks based on branch | |||
/// probabilities. | /// probabilities. | |||
extern char &MachineBlockPlacementID; | extern char &MachineBlockPlacementID; | |||
/// MachineBlockPlacementStats - This pass collects statistics about the | /// MachineBlockPlacementStats - This pass collects statistics about the | |||
/// basic block placement using branch probabilities and block frequency | /// basic block placement using branch probabilities and block frequency | |||
/// information. | /// information. | |||
extern char &MachineBlockPlacementStatsID; | extern char &MachineBlockPlacementStatsID; | |||
/// Code Placement - This pass optimize code placement and aligns loop | ||||
/// headers to target specific alignment boundary. | ||||
extern char &CodePlacementOptID; | ||||
/// GCLowering Pass - Performs target-independent LLVM IR transformations for | /// GCLowering Pass - Performs target-independent LLVM IR transformations for | |||
/// highly portable strategies. | /// highly portable strategies. | |||
/// | /// | |||
FunctionPass *createGCLoweringPass(); | FunctionPass *createGCLoweringPass(); | |||
/// GCMachineCodeAnalysis - Target-independent pass to mark safe points | /// GCMachineCodeAnalysis - Target-independent pass to mark safe points | |||
/// in machine code. Must be added very late during code generation, just | /// in machine code. Must be added very late during code generation, just | |||
/// prior to output, and importantly after all CFG transformations (such as | /// prior to output, and importantly after all CFG transformations (such as | |||
/// branch folding). | /// branch folding). | |||
extern char &GCMachineCodeAnalysisID; | extern char &GCMachineCodeAnalysisID; | |||
/// Deleter Pass - Releases GC metadata. | ||||
/// | ||||
FunctionPass *createGCInfoDeleter(); | ||||
/// Creates a pass to print GC metadata. | /// Creates a pass to print GC metadata. | |||
/// | /// | |||
FunctionPass *createGCInfoPrinter(raw_ostream &OS); | FunctionPass *createGCInfoPrinter(raw_ostream &OS); | |||
/// MachineCSE - This pass performs global CSE on machine instructions. | /// MachineCSE - This pass performs global CSE on machine instructions. | |||
extern char &MachineCSEID; | extern char &MachineCSEID; | |||
/// MachineLICM - This pass performs LICM on machine instructions. | /// MachineLICM - This pass performs LICM on machine instructions. | |||
extern char &MachineLICMID; | extern char &MachineLICMID; | |||
skipping to change at line 472 | skipping to change at line 521 | |||
/// OptimizePHIs - This pass optimizes machine instruction PHIs | /// OptimizePHIs - This pass optimizes machine instruction PHIs | |||
/// to take advantage of opportunities created during DAG legalization. | /// to take advantage of opportunities created during DAG legalization. | |||
extern char &OptimizePHIsID; | extern char &OptimizePHIsID; | |||
/// StackSlotColoring - This pass performs stack slot coloring. | /// StackSlotColoring - This pass performs stack slot coloring. | |||
extern char &StackSlotColoringID; | extern char &StackSlotColoringID; | |||
/// createStackProtectorPass - This pass adds stack protectors to functio ns. | /// createStackProtectorPass - This pass adds stack protectors to functio ns. | |||
/// | /// | |||
FunctionPass *createStackProtectorPass(const TargetLowering *tli); | FunctionPass *createStackProtectorPass(const TargetLoweringBase *tli); | |||
/// createMachineVerifierPass - This pass verifies cenerated machine code | /// createMachineVerifierPass - This pass verifies cenerated machine code | |||
/// instructions for correctness. | /// instructions for correctness. | |||
/// | /// | |||
FunctionPass *createMachineVerifierPass(const char *Banner = 0); | FunctionPass *createMachineVerifierPass(const char *Banner = 0); | |||
/// createDwarfEHPass - This pass mulches exception handling code into a form | /// createDwarfEHPass - This pass mulches exception handling code into a form | |||
/// adapted to code generation. Required if using dwarf exception handli ng. | /// adapted to code generation. Required if using dwarf exception handli ng. | |||
FunctionPass *createDwarfEHPass(const TargetMachine *tm); | FunctionPass *createDwarfEHPass(const TargetMachine *tm); | |||
/// createSjLjEHPreparePass - This pass adapts exception handling code to use | /// createSjLjEHPreparePass - This pass adapts exception handling code to use | |||
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control fl ow. | /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control fl ow. | |||
/// | /// | |||
FunctionPass *createSjLjEHPreparePass(const TargetLowering *tli); | FunctionPass *createSjLjEHPreparePass(const TargetLoweringBase *tli); | |||
/// LocalStackSlotAllocation - This pass assigns local frame indices to s tack | /// LocalStackSlotAllocation - This pass assigns local frame indices to s tack | |||
/// slots relative to one another and allocates base registers to access them | /// slots relative to one another and allocates base registers to access them | |||
/// when it is estimated by the target to be out of range of normal frame | /// when it is estimated by the target to be out of range of normal frame | |||
/// pointer or stack pointer index addressing. | /// pointer or stack pointer index addressing. | |||
extern char &LocalStackSlotAllocationID; | extern char &LocalStackSlotAllocationID; | |||
/// ExpandISelPseudos - This pass expands pseudo-instructions. | /// ExpandISelPseudos - This pass expands pseudo-instructions. | |||
extern char &ExpandISelPseudosID; | extern char &ExpandISelPseudosID; | |||
End of changes. 16 change blocks. | ||||
32 lines changed or deleted | 89 lines changed or added | |||
PathNumbering.h | PathNumbering.h | |||
---|---|---|---|---|
skipping to change at line 26 | skipping to change at line 26 | |||
// [Ball96] edges can be enumerated such that given a path number by follow ing | // [Ball96] edges can be enumerated such that given a path number by follow ing | |||
// the CFG and updating the path number, the path is obtained. | // the CFG and updating the path number, the path is obtained. | |||
// | // | |||
// [Ball96] | // [Ball96] | |||
// T. Ball and J. R. Larus. "Efficient Path Profiling." | // T. Ball and J. R. Larus. "Efficient Path Profiling." | |||
// International Symposium on Microarchitecture, pages 46-57, 1996. | // International Symposium on Microarchitecture, pages 46-57, 1996. | |||
// http://portal.acm.org/citation.cfm?id=243857 | // http://portal.acm.org/citation.cfm?id=243857 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_PATH_NUMBERING_H | #ifndef LLVM_ANALYSIS_PATHNUMBERING_H | |||
#define LLVM_PATH_NUMBERING_H | #define LLVM_ANALYSIS_PATHNUMBERING_H | |||
#include "llvm/BasicBlock.h" | #include "llvm/Analysis/ProfileInfoTypes.h" | |||
#include "llvm/Instructions.h" | #include "llvm/IR/BasicBlock.h" | |||
#include "llvm/IR/Instructions.h" | ||||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
#include "llvm/Support/CFG.h" | #include "llvm/Support/CFG.h" | |||
#include "llvm/Analysis/ProfileInfoTypes.h" | ||||
#include <map> | #include <map> | |||
#include <stack> | #include <stack> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class BallLarusNode; | class BallLarusNode; | |||
class BallLarusEdge; | class BallLarusEdge; | |||
class BallLarusDag; | class BallLarusDag; | |||
// typedefs for storage/ interators of various DAG components | // typedefs for storage/ interators of various DAG components | |||
End of changes. 3 change blocks. | ||||
5 lines changed or deleted | 5 lines changed or added | |||
PathProfileInfo.h | PathProfileInfo.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file outlines the interface used by optimizers to load path profile s. | // This file outlines the interface used by optimizers to load path profile s. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_PATHPROFILEINFO_H | #ifndef LLVM_ANALYSIS_PATHPROFILEINFO_H | |||
#define LLVM_PATHPROFILEINFO_H | #define LLVM_ANALYSIS_PATHPROFILEINFO_H | |||
#include "llvm/BasicBlock.h" | ||||
#include "llvm/Analysis/PathNumbering.h" | #include "llvm/Analysis/PathNumbering.h" | |||
#include "llvm/IR/BasicBlock.h" | ||||
namespace llvm { | namespace llvm { | |||
class ProfilePath; | class ProfilePath; | |||
class ProfilePathEdge; | class ProfilePathEdge; | |||
class PathProfileInfo; | class PathProfileInfo; | |||
typedef std::vector<ProfilePathEdge> ProfilePathEdgeVector; | typedef std::vector<ProfilePathEdge> ProfilePathEdgeVector; | |||
typedef std::vector<ProfilePathEdge>::iterator ProfilePathEdgeIterator; | typedef std::vector<ProfilePathEdge>::iterator ProfilePathEdgeIterator; | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
PathV1.h | PathV1.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the llvm::sys::Path class. | // This file declares the llvm::sys::Path class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_PATH_H | #ifndef LLVM_SUPPORT_PATHV1_H | |||
#define LLVM_SYSTEM_PATH_H | #define LLVM_SUPPORT_PATHV1_H | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/TimeValue.h" | #include "llvm/Support/TimeValue.h" | |||
#include <set> | #include <set> | |||
#include <string> | #include <string> | |||
#include <vector> | #include <vector> | |||
#define LLVM_PATH_DEPRECATED_MSG(replacement) \ | #define LLVM_PATH_DEPRECATED_MSG(replacement) \ | |||
"PathV1 has been deprecated and will be removed as soon as all LLVM and" \ | "PathV1 has been deprecated and will be removed as soon as all LLVM and" \ | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
PatternMatch.h | PatternMatch.h | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
// } | // } | |||
// | // | |||
// This is primarily useful to things like the instruction combiner, but ca n | // This is primarily useful to things like the instruction combiner, but ca n | |||
// also be useful for static analysis tools or code generators. | // also be useful for static analysis tools or code generators. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_PATTERNMATCH_H | #ifndef LLVM_SUPPORT_PATTERNMATCH_H | |||
#define LLVM_SUPPORT_PATTERNMATCH_H | #define LLVM_SUPPORT_PATTERNMATCH_H | |||
#include "llvm/Constants.h" | #include "llvm/IR/Constants.h" | |||
#include "llvm/Instructions.h" | #include "llvm/IR/Instructions.h" | |||
#include "llvm/Operator.h" | #include "llvm/IR/IntrinsicInst.h" | |||
#include "llvm/IR/Operator.h" | ||||
#include "llvm/Support/CallSite.h" | ||||
namespace llvm { | namespace llvm { | |||
namespace PatternMatch { | namespace PatternMatch { | |||
template<typename Val, typename Pattern> | template<typename Val, typename Pattern> | |||
bool match(Val *V, const Pattern &P) { | bool match(Val *V, const Pattern &P) { | |||
return const_cast<Pattern&>(P).match(V); | return const_cast<Pattern&>(P).match(V); | |||
} | } | |||
template<typename SubPattern_t> | template<typename SubPattern_t> | |||
skipping to change at line 76 | skipping to change at line 78 | |||
inline class_match<Value> m_Value() { return class_match<Value>(); } | inline class_match<Value> m_Value() { return class_match<Value>(); } | |||
/// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it. | /// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it. | |||
inline class_match<ConstantInt> m_ConstantInt() { | inline class_match<ConstantInt> m_ConstantInt() { | |||
return class_match<ConstantInt>(); | return class_match<ConstantInt>(); | |||
} | } | |||
/// m_Undef() - Match an arbitrary undef constant. | /// m_Undef() - Match an arbitrary undef constant. | |||
inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>() ; } | inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>() ; } | |||
inline class_match<Constant> m_Constant() { return class_match<Constant>(); } | inline class_match<Constant> m_Constant() { return class_match<Constant>(); } | |||
/// Matching combinators | ||||
template<typename LTy, typename RTy> | ||||
struct match_combine_or { | ||||
LTy L; | ||||
RTy R; | ||||
match_combine_or(const LTy &Left, const RTy &Right) : L(Left), R(Right) { | ||||
} | ||||
template<typename ITy> | ||||
bool match(ITy *V) { | ||||
if (L.match(V)) | ||||
return true; | ||||
if (R.match(V)) | ||||
return true; | ||||
return false; | ||||
} | ||||
}; | ||||
template<typename LTy, typename RTy> | ||||
struct match_combine_and { | ||||
LTy L; | ||||
RTy R; | ||||
match_combine_and(const LTy &Left, const RTy &Right) : L(Left), R(Right) | ||||
{ } | ||||
template<typename ITy> | ||||
bool match(ITy *V) { | ||||
if (L.match(V)) | ||||
if (R.match(V)) | ||||
return true; | ||||
return false; | ||||
} | ||||
}; | ||||
/// Combine two pattern matchers matching L || R | ||||
template<typename LTy, typename RTy> | ||||
inline match_combine_or<LTy, RTy> m_CombineOr(const LTy &L, const RTy &R) { | ||||
return match_combine_or<LTy, RTy>(L, R); | ||||
} | ||||
/// Combine two pattern matchers matching L && R | ||||
template<typename LTy, typename RTy> | ||||
inline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R) | ||||
{ | ||||
return match_combine_and<LTy, RTy>(L, R); | ||||
} | ||||
struct match_zero { | struct match_zero { | |||
template<typename ITy> | template<typename ITy> | |||
bool match(ITy *V) { | bool match(ITy *V) { | |||
if (const Constant *C = dyn_cast<Constant>(V)) | if (const Constant *C = dyn_cast<Constant>(V)) | |||
return C->isNullValue(); | return C->isNullValue(); | |||
return false; | return false; | |||
} | } | |||
}; | }; | |||
/// m_Zero() - Match an arbitrary zero/null constant. This includes | /// m_Zero() - Match an arbitrary zero/null constant. This includes | |||
/// zero_initializer for vectors and ConstantPointerNull for pointers. | /// zero_initializer for vectors and ConstantPointerNull for pointers. | |||
inline match_zero m_Zero() { return match_zero(); } | inline match_zero m_Zero() { return match_zero(); } | |||
struct match_neg_zero { | ||||
template<typename ITy> | ||||
bool match(ITy *V) { | ||||
if (const Constant *C = dyn_cast<Constant>(V)) | ||||
return C->isNegativeZeroValue(); | ||||
return false; | ||||
} | ||||
}; | ||||
/// m_NegZero() - Match an arbitrary zero/null constant. This includes | ||||
/// zero_initializer for vectors and ConstantPointerNull for pointers. For | ||||
/// floating point constants, this will match negative zero but not positiv | ||||
e | ||||
/// zero | ||||
inline match_neg_zero m_NegZero() { return match_neg_zero(); } | ||||
/// m_AnyZero() - Match an arbitrary zero/null constant. This includes | ||||
/// zero_initializer for vectors and ConstantPointerNull for pointers. For | ||||
/// floating point constants, this will match negative zero and positive ze | ||||
ro | ||||
inline match_combine_or<match_zero, match_neg_zero> m_AnyZero() { | ||||
return m_CombineOr(m_Zero(), m_NegZero()); | ||||
} | ||||
struct apint_match { | struct apint_match { | |||
const APInt *&Res; | const APInt *&Res; | |||
apint_match(const APInt *&R) : Res(R) {} | apint_match(const APInt *&R) : Res(R) {} | |||
template<typename ITy> | template<typename ITy> | |||
bool match(ITy *V) { | bool match(ITy *V) { | |||
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { | if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { | |||
Res = &CI->getValue(); | Res = &CI->getValue(); | |||
return true; | return true; | |||
} | } | |||
// FIXME: Remove this. | if (V->getType()->isVectorTy()) | |||
if (ConstantVector *CV = dyn_cast<ConstantVector>(V)) | if (const Constant *C = dyn_cast<Constant>(V)) | |||
if (ConstantInt *CI = | if (ConstantInt *CI = | |||
dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) { | dyn_cast_or_null<ConstantInt>(C->getSplatValue())) { | |||
Res = &CI->getValue(); | Res = &CI->getValue(); | |||
return true; | return true; | |||
} | } | |||
if (ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V)) | ||||
if (ConstantInt *CI = | ||||
dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) { | ||||
Res = &CI->getValue(); | ||||
return true; | ||||
} | ||||
return false; | return false; | |||
} | } | |||
}; | }; | |||
/// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the | /// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the | |||
/// specified pointer to the contained APInt. | /// specified pointer to the contained APInt. | |||
inline apint_match m_APInt(const APInt *&Res) { return Res; } | inline apint_match m_APInt(const APInt *&Res) { return Res; } | |||
template<int64_t Val> | template<int64_t Val> | |||
struct constantint_match { | struct constantint_match { | |||
skipping to change at line 150 | skipping to change at line 214 | |||
} | } | |||
/// cst_pred_ty - This helper class is used to match scalar and vector cons tants | /// cst_pred_ty - This helper class is used to match scalar and vector cons tants | |||
/// that satisfy a specified predicate. | /// that satisfy a specified predicate. | |||
template<typename Predicate> | template<typename Predicate> | |||
struct cst_pred_ty : public Predicate { | struct cst_pred_ty : public Predicate { | |||
template<typename ITy> | template<typename ITy> | |||
bool match(ITy *V) { | bool match(ITy *V) { | |||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) | if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) | |||
return this->isValue(CI->getValue()); | return this->isValue(CI->getValue()); | |||
// FIXME: Remove this. | if (V->getType()->isVectorTy()) | |||
if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) | if (const Constant *C = dyn_cast<Constant>(V)) | |||
if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue | if (const ConstantInt *CI = | |||
())) | dyn_cast_or_null<ConstantInt>(C->getSplatValue())) | |||
return this->isValue(CI->getValue()); | return this->isValue(CI->getValue()); | |||
if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V)) | ||||
if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue | ||||
())) | ||||
return this->isValue(CI->getValue()); | ||||
return false; | return false; | |||
} | } | |||
}; | }; | |||
/// api_pred_ty - This helper class is used to match scalar and vector cons tants | /// api_pred_ty - This helper class is used to match scalar and vector cons tants | |||
/// that satisfy a specified predicate, and bind them to an APInt. | /// that satisfy a specified predicate, and bind them to an APInt. | |||
template<typename Predicate> | template<typename Predicate> | |||
struct api_pred_ty : public Predicate { | struct api_pred_ty : public Predicate { | |||
const APInt *&Res; | const APInt *&Res; | |||
api_pred_ty(const APInt *&R) : Res(R) {} | api_pred_ty(const APInt *&R) : Res(R) {} | |||
template<typename ITy> | template<typename ITy> | |||
bool match(ITy *V) { | bool match(ITy *V) { | |||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) | if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) | |||
if (this->isValue(CI->getValue())) { | if (this->isValue(CI->getValue())) { | |||
Res = &CI->getValue(); | Res = &CI->getValue(); | |||
return true; | return true; | |||
} | } | |||
if (V->getType()->isVectorTy()) | ||||
// FIXME: remove. | if (const Constant *C = dyn_cast<Constant>(V)) | |||
if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) | if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValu | |||
if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue | e())) | |||
())) | if (this->isValue(CI->getValue())) { | |||
if (this->isValue(CI->getValue())) { | Res = &CI->getValue(); | |||
Res = &CI->getValue(); | return true; | |||
return true; | } | |||
} | ||||
if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V)) | ||||
if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue | ||||
())) | ||||
if (this->isValue(CI->getValue())) { | ||||
Res = &CI->getValue(); | ||||
return true; | ||||
} | ||||
return false; | return false; | |||
} | } | |||
}; | }; | |||
struct is_one { | struct is_one { | |||
bool isValue(const APInt &C) { return C == 1; } | bool isValue(const APInt &C) { return C == 1; } | |||
}; | }; | |||
/// m_One() - Match an integer 1 or a vector with all elements equal to 1. | /// m_One() - Match an integer 1 or a vector with all elements equal to 1. | |||
skipping to change at line 250 | skipping to change at line 304 | |||
/// m_Value - Match a value, capturing it if we match. | /// m_Value - Match a value, capturing it if we match. | |||
inline bind_ty<Value> m_Value(Value *&V) { return V; } | inline bind_ty<Value> m_Value(Value *&V) { return V; } | |||
/// m_ConstantInt - Match a ConstantInt, capturing the value if we match. | /// m_ConstantInt - Match a ConstantInt, capturing the value if we match. | |||
inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; } | inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; } | |||
/// m_Constant - Match a Constant, capturing the value if we match. | /// m_Constant - Match a Constant, capturing the value if we match. | |||
inline bind_ty<Constant> m_Constant(Constant *&C) { return C; } | inline bind_ty<Constant> m_Constant(Constant *&C) { return C; } | |||
/// m_ConstantFP - Match a ConstantFP, capturing the value if we match. | ||||
inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; } | ||||
/// specificval_ty - Match a specified Value*. | /// specificval_ty - Match a specified Value*. | |||
struct specificval_ty { | struct specificval_ty { | |||
const Value *Val; | const Value *Val; | |||
specificval_ty(const Value *V) : Val(V) {} | specificval_ty(const Value *V) : Val(V) {} | |||
template<typename ITy> | template<typename ITy> | |||
bool match(ITy *V) { | bool match(ITy *V) { | |||
return V == Val; | return V == Val; | |||
} | } | |||
}; | }; | |||
/// m_Specific - Match if we have a specific specified value. | /// m_Specific - Match if we have a specific specified value. | |||
inline specificval_ty m_Specific(const Value *V) { return V; } | inline specificval_ty m_Specific(const Value *V) { return V; } | |||
/// Match a specified floating point value or vector of all elements of tha | ||||
t | ||||
/// value. | ||||
struct specific_fpval { | ||||
double Val; | ||||
specific_fpval(double V) : Val(V) {} | ||||
template<typename ITy> | ||||
bool match(ITy *V) { | ||||
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V)) | ||||
return CFP->isExactlyValue(Val); | ||||
if (V->getType()->isVectorTy()) | ||||
if (const Constant *C = dyn_cast<Constant>(V)) | ||||
if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(C->getSplatValue | ||||
())) | ||||
return CFP->isExactlyValue(Val); | ||||
return false; | ||||
} | ||||
}; | ||||
/// Match a specific floating point value or vector with all elements equal | ||||
to | ||||
/// the value. | ||||
inline specific_fpval m_SpecificFP(double V) { return specific_fpval(V); } | ||||
/// Match a float 1.0 or vector with all elements equal to 1.0. | ||||
inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); } | ||||
struct bind_const_intval_ty { | struct bind_const_intval_ty { | |||
uint64_t &VR; | uint64_t &VR; | |||
bind_const_intval_ty(uint64_t &V) : VR(V) {} | bind_const_intval_ty(uint64_t &V) : VR(V) {} | |||
template<typename ITy> | template<typename ITy> | |||
bool match(ITy *V) { | bool match(ITy *V) { | |||
if (ConstantInt *CV = dyn_cast<ConstantInt>(V)) | if (ConstantInt *CV = dyn_cast<ConstantInt>(V)) | |||
if (CV->getBitWidth() <= 64) { | if (CV->getBitWidth() <= 64) { | |||
VR = CV->getZExtValue(); | VR = CV->getZExtValue(); | |||
return true; | return true; | |||
skipping to change at line 609 | skipping to change at line 691 | |||
return CastClass_match<OpTy, Instruction::SExt>(Op); | return CastClass_match<OpTy, Instruction::SExt>(Op); | |||
} | } | |||
/// m_ZExt | /// m_ZExt | |||
template<typename OpTy> | template<typename OpTy> | |||
inline CastClass_match<OpTy, Instruction::ZExt> | inline CastClass_match<OpTy, Instruction::ZExt> | |||
m_ZExt(const OpTy &Op) { | m_ZExt(const OpTy &Op) { | |||
return CastClass_match<OpTy, Instruction::ZExt>(Op); | return CastClass_match<OpTy, Instruction::ZExt>(Op); | |||
} | } | |||
/// m_UIToFP | ||||
template<typename OpTy> | ||||
inline CastClass_match<OpTy, Instruction::UIToFP> | ||||
m_UIToFp(const OpTy &Op) { | ||||
return CastClass_match<OpTy, Instruction::UIToFP>(Op); | ||||
} | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Matchers for unary operators | // Matchers for unary operators | |||
// | // | |||
template<typename LHS_t> | template<typename LHS_t> | |||
struct not_match { | struct not_match { | |||
LHS_t L; | LHS_t L; | |||
not_match(const LHS_t &LHS) : L(LHS) {} | not_match(const LHS_t &LHS) : L(LHS) {} | |||
skipping to change at line 693 | skipping to change at line 782 | |||
}; | }; | |||
/// m_FNeg - Match a floating point negate. | /// m_FNeg - Match a floating point negate. | |||
template<typename LHS> | template<typename LHS> | |||
inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; } | inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; } | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Matchers for control flow. | // Matchers for control flow. | |||
// | // | |||
struct br_match { | ||||
BasicBlock *&Succ; | ||||
br_match(BasicBlock *&Succ) | ||||
: Succ(Succ) { | ||||
} | ||||
template<typename OpTy> | ||||
bool match(OpTy *V) { | ||||
if (BranchInst *BI = dyn_cast<BranchInst>(V)) | ||||
if (BI->isUnconditional()) { | ||||
Succ = BI->getSuccessor(0); | ||||
return true; | ||||
} | ||||
return false; | ||||
} | ||||
}; | ||||
inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ | ||||
); } | ||||
template<typename Cond_t> | template<typename Cond_t> | |||
struct brc_match { | struct brc_match { | |||
Cond_t Cond; | Cond_t Cond; | |||
BasicBlock *&T, *&F; | BasicBlock *&T, *&F; | |||
brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f) | brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f) | |||
: Cond(C), T(t), F(f) { | : Cond(C), T(t), F(f) { | |||
} | } | |||
template<typename OpTy> | template<typename OpTy> | |||
bool match(OpTy *V) { | bool match(OpTy *V) { | |||
skipping to change at line 722 | skipping to change at line 830 | |||
template<typename Cond_t> | template<typename Cond_t> | |||
inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock * &F) { | inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock * &F) { | |||
return brc_match<Cond_t>(C, T, F); | return brc_match<Cond_t>(C, T, F); | |||
} | } | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y). | // Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y). | |||
// | // | |||
template<typename LHS_t, typename RHS_t, typename Pred_t> | template<typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_ t> | |||
struct MaxMin_match { | struct MaxMin_match { | |||
LHS_t L; | LHS_t L; | |||
RHS_t R; | RHS_t R; | |||
MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) | MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) | |||
: L(LHS), R(RHS) {} | : L(LHS), R(RHS) {} | |||
template<typename OpTy> | template<typename OpTy> | |||
bool match(OpTy *V) { | bool match(OpTy *V) { | |||
// Look for "(x pred y) ? x : y" or "(x pred y) ? y : x". | // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x". | |||
SelectInst *SI = dyn_cast<SelectInst>(V); | SelectInst *SI = dyn_cast<SelectInst>(V); | |||
if (!SI) | if (!SI) | |||
return false; | return false; | |||
ICmpInst *Cmp = dyn_cast<ICmpInst>(SI->getCondition()); | CmpInst_t *Cmp = dyn_cast<CmpInst_t>(SI->getCondition()); | |||
if (!Cmp) | if (!Cmp) | |||
return false; | return false; | |||
// At this point we have a select conditioned on a comparison. Check t hat | // At this point we have a select conditioned on a comparison. Check t hat | |||
// it is the values returned by the select that are being compared. | // it is the values returned by the select that are being compared. | |||
Value *TrueVal = SI->getTrueValue(); | Value *TrueVal = SI->getTrueValue(); | |||
Value *FalseVal = SI->getFalseValue(); | Value *FalseVal = SI->getFalseValue(); | |||
Value *LHS = Cmp->getOperand(0); | Value *LHS = Cmp->getOperand(0); | |||
Value *RHS = Cmp->getOperand(1); | Value *RHS = Cmp->getOperand(1); | |||
if ((TrueVal != LHS || FalseVal != RHS) && | if ((TrueVal != LHS || FalseVal != RHS) && | |||
(TrueVal != RHS || FalseVal != LHS)) | (TrueVal != RHS || FalseVal != LHS)) | |||
return false; | return false; | |||
ICmpInst::Predicate Pred = LHS == TrueVal ? | typename CmpInst_t::Predicate Pred = LHS == TrueVal ? | |||
Cmp->getPredicate() : Cmp->getSwappedPredicate(); | Cmp->getPredicate() : Cmp->getSwappedPredicate(); | |||
// Does "(x pred y) ? x : y" represent the desired max/min operation? | // Does "(x pred y) ? x : y" represent the desired max/min operation? | |||
if (!Pred_t::match(Pred)) | if (!Pred_t::match(Pred)) | |||
return false; | return false; | |||
// It does! Bind the operands. | // It does! Bind the operands. | |||
return L.match(LHS) && R.match(RHS); | return L.match(LHS) && R.match(RHS); | |||
} | } | |||
}; | }; | |||
/// smax_pred_ty - Helper class for identifying signed max predicates. | /// smax_pred_ty - Helper class for identifying signed max predicates. | |||
skipping to change at line 786 | skipping to change at line 894 | |||
} | } | |||
}; | }; | |||
/// umin_pred_ty - Helper class for identifying unsigned min predicates. | /// umin_pred_ty - Helper class for identifying unsigned min predicates. | |||
struct umin_pred_ty { | struct umin_pred_ty { | |||
static bool match(ICmpInst::Predicate Pred) { | static bool match(ICmpInst::Predicate Pred) { | |||
return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE; | return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE; | |||
} | } | |||
}; | }; | |||
/// ofmax_pred_ty - Helper class for identifying ordered max predicates. | ||||
struct ofmax_pred_ty { | ||||
static bool match(FCmpInst::Predicate Pred) { | ||||
return Pred == CmpInst::FCMP_OGT || Pred == CmpInst::FCMP_OGE; | ||||
} | ||||
}; | ||||
/// ofmin_pred_ty - Helper class for identifying ordered min predicates. | ||||
struct ofmin_pred_ty { | ||||
static bool match(FCmpInst::Predicate Pred) { | ||||
return Pred == CmpInst::FCMP_OLT || Pred == CmpInst::FCMP_OLE; | ||||
} | ||||
}; | ||||
/// ufmax_pred_ty - Helper class for identifying unordered max predicates. | ||||
struct ufmax_pred_ty { | ||||
static bool match(FCmpInst::Predicate Pred) { | ||||
return Pred == CmpInst::FCMP_UGT || Pred == CmpInst::FCMP_UGE; | ||||
} | ||||
}; | ||||
/// ufmin_pred_ty - Helper class for identifying unordered min predicates. | ||||
struct ufmin_pred_ty { | ||||
static bool match(FCmpInst::Predicate Pred) { | ||||
return Pred == CmpInst::FCMP_ULT || Pred == CmpInst::FCMP_ULE; | ||||
} | ||||
}; | ||||
template<typename LHS, typename RHS> | template<typename LHS, typename RHS> | |||
inline MaxMin_match<LHS, RHS, smax_pred_ty> | inline MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty> | |||
m_SMax(const LHS &L, const RHS &R) { | m_SMax(const LHS &L, const RHS &R) { | |||
return MaxMin_match<LHS, RHS, smax_pred_ty>(L, R); | return MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>(L, R); | |||
} | } | |||
template<typename LHS, typename RHS> | template<typename LHS, typename RHS> | |||
inline MaxMin_match<LHS, RHS, smin_pred_ty> | inline MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty> | |||
m_SMin(const LHS &L, const RHS &R) { | m_SMin(const LHS &L, const RHS &R) { | |||
return MaxMin_match<LHS, RHS, smin_pred_ty>(L, R); | return MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>(L, R); | |||
} | } | |||
template<typename LHS, typename RHS> | template<typename LHS, typename RHS> | |||
inline MaxMin_match<LHS, RHS, umax_pred_ty> | inline MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty> | |||
m_UMax(const LHS &L, const RHS &R) { | m_UMax(const LHS &L, const RHS &R) { | |||
return MaxMin_match<LHS, RHS, umax_pred_ty>(L, R); | return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>(L, R); | |||
} | } | |||
template<typename LHS, typename RHS> | template<typename LHS, typename RHS> | |||
inline MaxMin_match<LHS, RHS, umin_pred_ty> | inline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty> | |||
m_UMin(const LHS &L, const RHS &R) { | m_UMin(const LHS &L, const RHS &R) { | |||
return MaxMin_match<LHS, RHS, umin_pred_ty>(L, R); | return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>(L, R); | |||
} | ||||
/// \brief Match an 'ordered' floating point maximum function. | ||||
/// Floating point has one special value 'NaN'. Therefore, there is no tota | ||||
l | ||||
/// order. However, if we can ignore the 'NaN' value (for example, because | ||||
of a | ||||
/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maxi | ||||
mum' | ||||
/// semantics. In the presence of 'NaN' we have to preserve the original | ||||
/// select(fcmp(ogt/ge, L, R), L, R) semantics matched by this predicate. | ||||
/// | ||||
/// max(L, R) iff L and R are not NaN | ||||
/// m_OrdFMax(L, R) = R iff L or R are NaN | ||||
template<typename LHS, typename RHS> | ||||
inline MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty> | ||||
m_OrdFMax(const LHS &L, const RHS &R) { | ||||
return MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty>(L, R); | ||||
} | ||||
/// \brief Match an 'ordered' floating point minimum function. | ||||
/// Floating point has one special value 'NaN'. Therefore, there is no tota | ||||
l | ||||
/// order. However, if we can ignore the 'NaN' value (for example, because | ||||
of a | ||||
/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'mini | ||||
mum' | ||||
/// semantics. In the presence of 'NaN' we have to preserve the original | ||||
/// select(fcmp(olt/le, L, R), L, R) semantics matched by this predicate. | ||||
/// | ||||
/// max(L, R) iff L and R are not NaN | ||||
/// m_OrdFMin(L, R) = R iff L or R are NaN | ||||
template<typename LHS, typename RHS> | ||||
inline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty> | ||||
m_OrdFMin(const LHS &L, const RHS &R) { | ||||
return MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty>(L, R); | ||||
} | ||||
/// \brief Match an 'unordered' floating point maximum function. | ||||
/// Floating point has one special value 'NaN'. Therefore, there is no tota | ||||
l | ||||
/// order. However, if we can ignore the 'NaN' value (for example, because | ||||
of a | ||||
/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maxi | ||||
mum' | ||||
/// semantics. In the presence of 'NaN' we have to preserve the original | ||||
/// select(fcmp(ugt/ge, L, R), L, R) semantics matched by this predicate. | ||||
/// | ||||
/// max(L, R) iff L and R are not NaN | ||||
/// m_UnordFMin(L, R) = L iff L or R are NaN | ||||
template<typename LHS, typename RHS> | ||||
inline MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty> | ||||
m_UnordFMax(const LHS &L, const RHS &R) { | ||||
return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R); | ||||
} | ||||
/// \brief Match an 'unordered' floating point minimum function. | ||||
/// Floating point has one special value 'NaN'. Therefore, there is no tota | ||||
l | ||||
/// order. However, if we can ignore the 'NaN' value (for example, because | ||||
of a | ||||
/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'mini | ||||
mum' | ||||
/// semantics. In the presence of 'NaN' we have to preserve the original | ||||
/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate. | ||||
/// | ||||
/// max(L, R) iff L and R are not NaN | ||||
/// m_UnordFMin(L, R) = L iff L or R are NaN | ||||
template<typename LHS, typename RHS> | ||||
inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty> | ||||
m_UnordFMin(const LHS &L, const RHS &R) { | ||||
return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R); | ||||
} | ||||
template<typename Opnd_t> | ||||
struct Argument_match { | ||||
unsigned OpI; | ||||
Opnd_t Val; | ||||
Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) { } | ||||
template<typename OpTy> | ||||
bool match(OpTy *V) { | ||||
CallSite CS(V); | ||||
return CS.isCall() && Val.match(CS.getArgument(OpI)); | ||||
} | ||||
}; | ||||
/// Match an argument | ||||
template<unsigned OpI, typename Opnd_t> | ||||
inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) { | ||||
return Argument_match<Opnd_t>(OpI, Op); | ||||
} | ||||
/// Intrinsic matchers. | ||||
struct IntrinsicID_match { | ||||
unsigned ID; | ||||
IntrinsicID_match(unsigned IntrID) : ID(IntrID) { } | ||||
template<typename OpTy> | ||||
bool match(OpTy *V) { | ||||
IntrinsicInst *II = dyn_cast<IntrinsicInst>(V); | ||||
return II && II->getIntrinsicID() == ID; | ||||
} | ||||
}; | ||||
/// Intrinsic matches are combinations of ID matchers, and argument | ||||
/// matchers. Higher arity matcher are defined recursively in terms of and- | ||||
ing | ||||
/// them with lower arity matchers. Here's some convenient typedefs for up | ||||
to | ||||
/// several arguments, and more can be added as needed | ||||
template <typename T0 = void, typename T1 = void, typename T2 = void, | ||||
typename T3 = void, typename T4 = void, typename T5 = void, | ||||
typename T6 = void, typename T7 = void, typename T8 = void, | ||||
typename T9 = void, typename T10 = void> struct m_Intrinsic_Ty; | ||||
template <typename T0> | ||||
struct m_Intrinsic_Ty<T0> { | ||||
typedef match_combine_and<IntrinsicID_match, Argument_match<T0> > Ty; | ||||
}; | ||||
template <typename T0, typename T1> | ||||
struct m_Intrinsic_Ty<T0, T1> { | ||||
typedef match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, | ||||
Argument_match<T1> > Ty; | ||||
}; | ||||
template <typename T0, typename T1, typename T2> | ||||
struct m_Intrinsic_Ty<T0, T1, T2> { | ||||
typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty, | ||||
Argument_match<T2> > Ty; | ||||
}; | ||||
template <typename T0, typename T1, typename T2, typename T3> | ||||
struct m_Intrinsic_Ty<T0, T1, T2, T3> { | ||||
typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty, | ||||
Argument_match<T3> > Ty; | ||||
}; | ||||
/// Match intrinsic calls like this: | ||||
/// m_Intrinsic<Intrinsic::fabs>(m_Value(X)) | ||||
template <unsigned IntrID> | ||||
inline IntrinsicID_match | ||||
m_Intrinsic() { return IntrinsicID_match(IntrID); } | ||||
template<unsigned IntrID, typename T0> | ||||
inline typename m_Intrinsic_Ty<T0>::Ty | ||||
m_Intrinsic(const T0 &Op0) { | ||||
return m_CombineAnd(m_Intrinsic<IntrID>(), m_Argument<0>(Op0)); | ||||
} | ||||
template<unsigned IntrID, typename T0, typename T1> | ||||
inline typename m_Intrinsic_Ty<T0, T1>::Ty | ||||
m_Intrinsic(const T0 &Op0, const T1 &Op1) { | ||||
return m_CombineAnd(m_Intrinsic<IntrID>(Op0), m_Argument<1>(Op1)); | ||||
} | ||||
template<unsigned IntrID, typename T0, typename T1, typename T2> | ||||
inline typename m_Intrinsic_Ty<T0, T1, T2>::Ty | ||||
m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) { | ||||
return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1), m_Argument<2>(Op2)); | ||||
} | ||||
template<unsigned IntrID, typename T0, typename T1, typename T2, typename T | ||||
3> | ||||
inline typename m_Intrinsic_Ty<T0, T1, T2, T3>::Ty | ||||
m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) { | ||||
return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3 | ||||
)); | ||||
} | ||||
// Helper intrinsic matching specializations | ||||
template<typename Opnd0> | ||||
inline typename m_Intrinsic_Ty<Opnd0>::Ty | ||||
m_BSwap(const Opnd0 &Op0) { | ||||
return m_Intrinsic<Intrinsic::bswap>(Op0); | ||||
} | } | |||
} // end namespace PatternMatch | } // end namespace PatternMatch | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 22 change blocks. | ||||
53 lines changed or deleted | 367 lines changed or added | |||
PointerIntPair.h | PointerIntPair.h | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
template<typename T> | template<typename T> | |||
struct DenseMapInfo; | struct DenseMapInfo; | |||
/// PointerIntPair - This class implements a pair of a pointer and small | /// PointerIntPair - This class implements a pair of a pointer and small | |||
/// integer. It is designed to represent this in the space required by one | /// integer. It is designed to represent this in the space required by one | |||
/// pointer by bitmangling the integer into the low part of the pointer. T his | /// pointer by bitmangling the integer into the low part of the pointer. T his | |||
/// can only be done for small integers: typically up to 3 bits, but it dep ends | /// can only be done for small integers: typically up to 3 bits, but it dep ends | |||
/// on the number of bits available according to PointerLikeTypeTraits for the | /// on the number of bits available according to PointerLikeTypeTraits for the | |||
/// type. | /// type. | |||
/// | /// | |||
/// Note that PointerIntPair always puts the Int part in the highest bits | /// Note that PointerIntPair always puts the IntVal part in the highest bit s | |||
/// possible. For example, PointerIntPair<void*, 1, bool> will put the bit for | /// possible. For example, PointerIntPair<void*, 1, bool> will put the bit for | |||
/// the bool into bit #2, not bit #0, which allows the low two bits to be u sed | /// the bool into bit #2, not bit #0, which allows the low two bits to be u sed | |||
/// for something else. For example, this allows: | /// for something else. For example, this allows: | |||
/// PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool> | /// PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool> | |||
/// ... and the two bools will land in different bits. | /// ... and the two bools will land in different bits. | |||
/// | /// | |||
template <typename PointerTy, unsigned IntBits, typename IntType=unsigned, | template <typename PointerTy, unsigned IntBits, typename IntType=unsigned, | |||
typename PtrTraits = PointerLikeTypeTraits<PointerTy> > | typename PtrTraits = PointerLikeTypeTraits<PointerTy> > | |||
class PointerIntPair { | class PointerIntPair { | |||
intptr_t Value; | intptr_t Value; | |||
skipping to change at line 60 | skipping to change at line 60 | |||
IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits, | IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits, | |||
/// IntMask - This is the unshifted mask for valid bits of the int type . | /// IntMask - This is the unshifted mask for valid bits of the int type . | |||
IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1), | IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1), | |||
// ShiftedIntMask - This is the bits for the integer shifted in place. | // ShiftedIntMask - This is the bits for the integer shifted in place. | |||
ShiftedIntMask = (uintptr_t)(IntMask << IntShift) | ShiftedIntMask = (uintptr_t)(IntMask << IntShift) | |||
}; | }; | |||
public: | public: | |||
PointerIntPair() : Value(0) {} | PointerIntPair() : Value(0) {} | |||
PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) { | PointerIntPair(PointerTy PtrVal, IntType IntVal) { | |||
assert(IntBits <= PtrTraits::NumLowBitsAvailable && | assert(IntBits <= PtrTraits::NumLowBitsAvailable && | |||
"PointerIntPair formed with integer size too large for pointer") ; | "PointerIntPair formed with integer size too large for pointer") ; | |||
setPointer(Ptr); | setPointerAndInt(PtrVal, IntVal); | |||
setInt(Int); | } | |||
explicit PointerIntPair(PointerTy PtrVal) { | ||||
initWithPointer(PtrVal); | ||||
} | } | |||
PointerTy getPointer() const { | PointerTy getPointer() const { | |||
return PtrTraits::getFromVoidPointer( | return PtrTraits::getFromVoidPointer( | |||
reinterpret_cast<void*>(Value & PointerBitMask)); | reinterpret_cast<void*>(Value & PointerBitMask)); | |||
} | } | |||
IntType getInt() const { | IntType getInt() const { | |||
return (IntType)((Value >> IntShift) & IntMask); | return (IntType)((Value >> IntShift) & IntMask); | |||
} | } | |||
void setPointer(PointerTy Ptr) { | void setPointer(PointerTy PtrVal) { | |||
intptr_t PtrVal | intptr_t PtrWord | |||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr)); | = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal)); | |||
assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && | assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && | |||
"Pointer is not sufficiently aligned"); | "Pointer is not sufficiently aligned"); | |||
// Preserve all low bits, just update the pointer. | // Preserve all low bits, just update the pointer. | |||
Value = PtrVal | (Value & ~PointerBitMask); | Value = PtrWord | (Value & ~PointerBitMask); | |||
} | } | |||
void setInt(IntType Int) { | void setInt(IntType IntVal) { | |||
intptr_t IntVal = Int; | intptr_t IntWord = static_cast<intptr_t>(IntVal); | |||
assert(IntVal < (1 << IntBits) && "Integer too large for field"); | assert(IntWord < (1 << IntBits) && "Integer too large for field"); | |||
// Preserve all bits other than the ones we are updating. | // Preserve all bits other than the ones we are updating. | |||
Value &= ~ShiftedIntMask; // Remove integer field. | Value &= ~ShiftedIntMask; // Remove integer field. | |||
Value |= IntVal << IntShift; // Set new integer. | Value |= IntWord << IntShift; // Set new integer. | |||
} | ||||
void initWithPointer(PointerTy PtrVal) { | ||||
intptr_t PtrWord | ||||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal)); | ||||
assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && | ||||
"Pointer is not sufficiently aligned"); | ||||
Value = PtrWord; | ||||
} | ||||
void setPointerAndInt(PointerTy PtrVal, IntType IntVal) { | ||||
intptr_t PtrWord | ||||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal)); | ||||
assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && | ||||
"Pointer is not sufficiently aligned"); | ||||
intptr_t IntWord = static_cast<intptr_t>(IntVal); | ||||
assert(IntWord < (1 << IntBits) && "Integer too large for field"); | ||||
Value = PtrWord | (IntWord << IntShift); | ||||
} | } | |||
PointerTy const *getAddrOfPointer() const { | PointerTy const *getAddrOfPointer() const { | |||
return const_cast<PointerIntPair *>(this)->getAddrOfPointer(); | return const_cast<PointerIntPair *>(this)->getAddrOfPointer(); | |||
} | } | |||
PointerTy *getAddrOfPointer() { | PointerTy *getAddrOfPointer() { | |||
assert(Value == reinterpret_cast<intptr_t>(getPointer()) && | assert(Value == reinterpret_cast<intptr_t>(getPointer()) && | |||
"Can only return the address if IntBits is cleared and " | "Can only return the address if IntBits is cleared and " | |||
"PtrTraits doesn't change the pointer"); | "PtrTraits doesn't change the pointer"); | |||
End of changes. 7 change blocks. | ||||
13 lines changed or deleted | 34 lines changed or added | |||
PointerUnion.h | PointerUnion.h | |||
---|---|---|---|---|
skipping to change at line 98 | skipping to change at line 98 | |||
}; | }; | |||
struct IsPT2 { | struct IsPT2 { | |||
static const int Num = 1; | static const int Num = 1; | |||
}; | }; | |||
template <typename T> | template <typename T> | |||
struct UNION_DOESNT_CONTAIN_TYPE { }; | struct UNION_DOESNT_CONTAIN_TYPE { }; | |||
public: | public: | |||
PointerUnion() {} | PointerUnion() {} | |||
PointerUnion(PT1 V) { | PointerUnion(PT1 V) : Val( | |||
Val.setPointer( | const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) | |||
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V) | { | |||
)); | } | |||
Val.setInt(0); | PointerUnion(PT2 V) : Val( | |||
} | const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), | |||
PointerUnion(PT2 V) { | 1) { | |||
Val.setPointer( | ||||
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V) | ||||
)); | ||||
Val.setInt(1); | ||||
} | } | |||
/// isNull - Return true if the pointer held in the union is null, | /// isNull - Return true if the pointer held in the union is null, | |||
/// regardless of which type it is. | /// regardless of which type it is. | |||
bool isNull() const { | bool isNull() const { | |||
// Convert from the void* to one of the pointer types, to make sure t hat | // Convert from the void* to one of the pointer types, to make sure t hat | |||
// we recursively strip off low bits if we have a nested PointerUnion . | // we recursively strip off low bits if we have a nested PointerUnion . | |||
return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer ()); | return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer ()); | |||
} | } | |||
operator bool() const { return !isNull(); } | operator bool() const { return !isNull(); } | |||
skipping to change at line 163 | skipping to change at line 159 | |||
PT1 *getAddrOfPtr1() { | PT1 *getAddrOfPtr1() { | |||
assert(is<PT1>() && "Val is not the first pointer"); | assert(is<PT1>() && "Val is not the first pointer"); | |||
assert(get<PT1>() == Val.getPointer() && | assert(get<PT1>() == Val.getPointer() && | |||
"Can't get the address because PointerLikeTypeTraits changes the p tr"); | "Can't get the address because PointerLikeTypeTraits changes the p tr"); | |||
return (PT1 *)Val.getAddrOfPointer(); | return (PT1 *)Val.getAddrOfPointer(); | |||
} | } | |||
/// Assignment operators - Allow assigning into this union from either | /// Assignment operators - Allow assigning into this union from either | |||
/// pointer type, setting the discriminator to remember what it came fr om. | /// pointer type, setting the discriminator to remember what it came fr om. | |||
const PointerUnion &operator=(const PT1 &RHS) { | const PointerUnion &operator=(const PT1 &RHS) { | |||
Val.setPointer( | Val.initWithPointer( | |||
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RH S))); | const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RH S))); | |||
Val.setInt(0); | ||||
return *this; | return *this; | |||
} | } | |||
const PointerUnion &operator=(const PT2 &RHS) { | const PointerUnion &operator=(const PT2 &RHS) { | |||
Val.setPointer( | Val.setPointerAndInt( | |||
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS | const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS | |||
))); | )), | |||
Val.setInt(1); | 1); | |||
return *this; | return *this; | |||
} | } | |||
void *getOpaqueValue() const { return Val.getOpaqueValue(); } | void *getOpaqueValue() const { return Val.getOpaqueValue(); } | |||
static inline PointerUnion getFromOpaqueValue(void *VP) { | static inline PointerUnion getFromOpaqueValue(void *VP) { | |||
PointerUnion V; | PointerUnion V; | |||
V.Val = ValTy::getFromOpaqueValue(VP); | V.Val = ValTy::getFromOpaqueValue(VP); | |||
return V; | return V; | |||
} | } | |||
}; | }; | |||
End of changes. 4 change blocks. | ||||
17 lines changed or deleted | 12 lines changed or added | |||
PostDominators.h | PostDominators.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file exposes interfaces to post dominance information. | // This file exposes interfaces to post dominance information. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_POST_DOMINATORS_H | #ifndef LLVM_ANALYSIS_POSTDOMINATORS_H | |||
#define LLVM_ANALYSIS_POST_DOMINATORS_H | #define LLVM_ANALYSIS_POSTDOMINATORS_H | |||
#include "llvm/Analysis/Dominators.h" | #include "llvm/Analysis/Dominators.h" | |||
namespace llvm { | namespace llvm { | |||
/// PostDominatorTree Class - Concrete subclass of DominatorTree that is us ed to | /// PostDominatorTree Class - Concrete subclass of DominatorTree that is us ed to | |||
/// compute the a post-dominator tree. | /// compute the a post-dominator tree. | |||
/// | /// | |||
struct PostDominatorTree : public FunctionPass { | struct PostDominatorTree : public FunctionPass { | |||
static char ID; // Pass identification, replacement for typeid | static char ID; // Pass identification, replacement for typeid | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
PostOrderIterator.h | PostOrderIterator.h | |||
---|---|---|---|---|
skipping to change at line 263 | skipping to change at line 263 | |||
// ... | // ... | |||
// } | // } | |||
// } | // } | |||
// | // | |||
template<class GraphT, class GT = GraphTraits<GraphT> > | template<class GraphT, class GT = GraphTraits<GraphT> > | |||
class ReversePostOrderTraversal { | class ReversePostOrderTraversal { | |||
typedef typename GT::NodeType NodeType; | typedef typename GT::NodeType NodeType; | |||
std::vector<NodeType*> Blocks; // Block list in normal PO order | std::vector<NodeType*> Blocks; // Block list in normal PO order | |||
inline void Initialize(NodeType *BB) { | inline void Initialize(NodeType *BB) { | |||
copy(po_begin(BB), po_end(BB), back_inserter(Blocks)); | std::copy(po_begin(BB), po_end(BB), std::back_inserter(Blocks)); | |||
} | } | |||
public: | public: | |||
typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator; | typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator; | |||
inline ReversePostOrderTraversal(GraphT G) { | inline ReversePostOrderTraversal(GraphT G) { | |||
Initialize(GT::getEntryNode(G)); | Initialize(GT::getEntryNode(G)); | |||
} | } | |||
// Because we want a reverse post order, use reverse iterators from the v ector | // Because we want a reverse post order, use reverse iterators from the v ector | |||
inline rpo_iterator begin() { return Blocks.rbegin(); } | inline rpo_iterator begin() { return Blocks.rbegin(); } | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
PredIteratorCache.h | PredIteratorCache.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the PredIteratorCache class. | // This file defines the PredIteratorCache class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#include "llvm/Support/Allocator.h" | ||||
#include "llvm/Support/CFG.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/Support/Allocator.h" | ||||
#include "llvm/Support/CFG.h" | ||||
#ifndef LLVM_SUPPORT_PREDITERATORCACHE_H | #ifndef LLVM_SUPPORT_PREDITERATORCACHE_H | |||
#define LLVM_SUPPORT_PREDITERATORCACHE_H | #define LLVM_SUPPORT_PREDITERATORCACHE_H | |||
namespace llvm { | namespace llvm { | |||
/// PredIteratorCache - This class is an extremely trivial cache for | /// PredIteratorCache - This class is an extremely trivial cache for | |||
/// predecessor iterator queries. This is useful for code that repeatedl y | /// predecessor iterator queries. This is useful for code that repeatedl y | |||
/// wants the predecessor list for the same blocks. | /// wants the predecessor list for the same blocks. | |||
class PredIteratorCache { | class PredIteratorCache { | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
PrintModulePass.h | PrintModulePass.h | |||
---|---|---|---|---|
skipping to change at line 26 | skipping to change at line 26 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ASSEMBLY_PRINTMODULEPASS_H | #ifndef LLVM_ASSEMBLY_PRINTMODULEPASS_H | |||
#define LLVM_ASSEMBLY_PRINTMODULEPASS_H | #define LLVM_ASSEMBLY_PRINTMODULEPASS_H | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class FunctionPass; | class FunctionPass; | |||
class ModulePass; | class ModulePass; | |||
class BasicBlockPass; | ||||
class raw_ostream; | class raw_ostream; | |||
/// createPrintModulePass - Create and return a pass that writes the | /// createPrintModulePass - Create and return a pass that writes the | |||
/// module to the specified raw_ostream. | /// module to the specified raw_ostream. | |||
ModulePass *createPrintModulePass(raw_ostream *OS, | ModulePass *createPrintModulePass(raw_ostream *OS, | |||
bool DeleteStream=false, | bool DeleteStream=false, | |||
const std::string &Banner = ""); | const std::string &Banner = ""); | |||
/// createPrintFunctionPass - Create and return a pass that prints | /// createPrintFunctionPass - Create and return a pass that prints | |||
/// functions to the specified raw_ostream as they are processed. | /// functions to the specified raw_ostream as they are processed. | |||
FunctionPass *createPrintFunctionPass(const std::string &Banner, | FunctionPass *createPrintFunctionPass(const std::string &Banner, | |||
raw_ostream *OS, | raw_ostream *OS, | |||
bool DeleteStream=false); | bool DeleteStream=false); | |||
/// createPrintBasicBlockPass - Create and return a pass that writes the | ||||
/// BB to the specified raw_ostream. | ||||
BasicBlockPass *createPrintBasicBlockPass(raw_ostream *OS, | ||||
bool DeleteStream=false, | ||||
const std::string &Banner = "") | ||||
; | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 7 lines changed or added | |||
PriorityQueue.h | PriorityQueue.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the PriorityQueue class. | // This file defines the PriorityQueue class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_PRIORITY_QUEUE_H | #ifndef LLVM_ADT_PRIORITYQUEUE_H | |||
#define LLVM_ADT_PRIORITY_QUEUE_H | #define LLVM_ADT_PRIORITYQUEUE_H | |||
#include <algorithm> | #include <algorithm> | |||
#include <queue> | #include <queue> | |||
namespace llvm { | namespace llvm { | |||
/// PriorityQueue - This class behaves like std::priority_queue and | /// PriorityQueue - This class behaves like std::priority_queue and | |||
/// provides a few additional convenience functions. | /// provides a few additional convenience functions. | |||
/// | /// | |||
template<class T, | template<class T, | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Process.h | Process.h | |||
---|---|---|---|---|
//===- llvm/Support/Process.h -----------------------------------*- C++ -*- ===// | //===- llvm/Support/Process.h -----------------------------------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | /// \file | |||
// This file declares the llvm::sys::Process class. | /// | |||
// | /// Provides a library for accessing information about this process and oth | |||
er | ||||
/// processes on the operating system. Also provides means of spawning | ||||
/// subprocess for commands. The design of this library is modeled after th | ||||
e | ||||
/// proposed design of the Boost.Process library, and is design specificall | ||||
y to | ||||
/// follow the style of standard libraries and potentially become a proposa | ||||
l | ||||
/// for a standard library. | ||||
/// | ||||
/// This file declares the llvm::sys::Process class which contains a collec | ||||
tion | ||||
/// of legacy static interfaces for extracting various information about th | ||||
e | ||||
/// current process. The goal is to migrate users of this API over to the n | ||||
ew | ||||
/// interfaces. | ||||
/// | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_PROCESS_H | #ifndef LLVM_SUPPORT_PROCESS_H | |||
#define LLVM_SYSTEM_PROCESS_H | #define LLVM_SUPPORT_PROCESS_H | |||
#include "llvm/Config/llvm-config.h" | ||||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/Support/TimeValue.h" | #include "llvm/Support/TimeValue.h" | |||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
/// This class provides an abstraction for getting information about the | class self_process; | |||
/// currently executing process. | ||||
/// @since 1.4 | /// \brief Generic base class which exposes information about an operating | |||
/// @brief An abstraction for operating system processes. | /// system process. | |||
class Process { | /// | |||
/// @name Accessors | /// This base class is the core interface behind any OS process. It exposes | |||
/// @{ | /// methods to query for generic information about a particular process. | |||
public: | /// | |||
/// This static function will return the operating system's virtual m | /// Subclasses implement this interface based on the mechanisms available, | |||
emory | and | |||
/// page size. | /// can optionally expose more interfaces unique to certain process kinds. | |||
/// @returns The number of bytes in a virtual memory page. | class process { | |||
/// @brief Get the virtual memory page size | protected: | |||
static unsigned GetPageSize(); | /// \brief Only specific subclasses of process objects can be destroyed. | |||
virtual ~process(); | ||||
/// This static function will return the total amount of memory alloc | ||||
ated | public: | |||
/// by the process. This only counts the memory allocated via the mal | /// \brief Operating system specific type to identify a process. | |||
loc, | /// | |||
/// calloc and realloc functions and includes any "free" holes in the | /// Note that the windows one is defined to 'void *' as this is the | |||
/// allocated space. | /// documented type for HANDLE on windows, and we don't want to pull in t | |||
/// @brief Return process memory usage. | he | |||
static size_t GetMallocUsage(); | /// Windows headers here. | |||
#if defined(LLVM_ON_UNIX) | ||||
/// This static function will return the total memory usage of the | typedef pid_t id_type; | |||
/// process. This includes code, data, stack and mapped pages usage. | #elif defined(LLVM_ON_WIN32) | |||
Notei | typedef void *id_type; // Must match the type of HANDLE. | |||
/// that the value returned here is not necessarily the Running Set S | #else | |||
ize, | #error Unsupported operating system. | |||
/// it is the total virtual memory usage, regardless of mapped state | #endif | |||
of | ||||
/// that memory. | /// \brief Get the operating system specific identifier for this process. | |||
static size_t GetTotalMemoryUsage(); | virtual id_type get_id() = 0; | |||
/// This static function will set \p user_time to the amount of CPU t | /// \brief Get the user time consumed by this process. | |||
ime | /// | |||
/// spent in user (non-kernel) mode and \p sys_time to the amount of | /// Note that this is often an approximation and may be zero on platforms | |||
CPU | /// where we don't have good support for the functionality. | |||
/// time spent in system (kernel) mode. If the operating system does | virtual TimeValue get_user_time() const = 0; | |||
not | ||||
/// support collection of these metrics, a zero TimeValue will be for | /// \brief Get the system time consumed by this process. | |||
both | /// | |||
/// values. | /// Note that this is often an approximation and may be zero on platforms | |||
static void GetTimeUsage( | /// where we don't have good support for the functionality. | |||
TimeValue& elapsed, | virtual TimeValue get_system_time() const = 0; | |||
///< Returns the TimeValue::now() giving current time | ||||
TimeValue& user_time, | /// \brief Get the wall time consumed by this process. | |||
///< Returns the current amount of user time for the process | /// | |||
TimeValue& sys_time | /// Note that this is often an approximation and may be zero on platforms | |||
///< Returns the current amount of system time for the process | /// where we don't have good support for the functionality. | |||
); | virtual TimeValue get_wall_time() const = 0; | |||
/// This static function will return the process' current user id num | /// \name Static factory routines for processes. | |||
ber. | /// @{ | |||
/// Not all operating systems support this feature. Where it is not | ||||
/// supported, the function should return 65536 as the value. | /// \brief Get the process object for the current process. | |||
static int GetCurrentUserId(); | static self_process *get_self(); | |||
/// This static function will return the process' current group id nu | /// @} | |||
mber. | ||||
/// Not all operating systems support this feature. Where it is not | }; | |||
/// supported, the function should return 65536 as the value. | ||||
static int GetCurrentGroupId(); | /// \brief The specific class representing the current process. | |||
/// | ||||
/// This function makes the necessary calls to the operating system t | /// The current process can both specialize the implementation of the routi | |||
o | nes | |||
/// prevent core files or any other kind of large memory dumps that c | /// and can expose certain information not available for other OS processes | |||
an | . | |||
/// occur when a program fails. | class self_process : public process { | |||
/// @brief Prevent core file generation. | friend class process; | |||
static void PreventCoreFiles(); | ||||
/// \brief Private destructor, as users shouldn't create objects of this | ||||
/// This function determines if the standard input is connected direc | /// type. | |||
tly | virtual ~self_process(); | |||
/// to a user's input (keyboard probably), rather than coming from a | ||||
file | public: | |||
/// or pipe. | virtual id_type get_id(); | |||
static bool StandardInIsUserInput(); | virtual TimeValue get_user_time() const; | |||
virtual TimeValue get_system_time() const; | ||||
/// This function determines if the standard output is connected to a | virtual TimeValue get_wall_time() const; | |||
/// "tty" or "console" window. That is, the output would be displayed | ||||
to | /// \name Process configuration (sysconf on POSIX) | |||
/// the user rather than being put on a pipe or stored in a file. | /// @{ | |||
static bool StandardOutIsDisplayed(); | ||||
/// \brief Get the virtual memory page size. | ||||
/// This function determines if the standard error is connected to a | /// | |||
/// "tty" or "console" window. That is, the output would be displayed | /// Query the operating system for this process's page size. | |||
to | size_t page_size() const { return PageSize; }; | |||
/// the user rather than being put on a pipe or stored in a file. | ||||
static bool StandardErrIsDisplayed(); | /// @} | |||
/// This function determines if the given file descriptor is connecte | private: | |||
d to | /// \name Cached process state. | |||
/// a "tty" or "console" window. That is, the output would be display | /// @{ | |||
ed to | ||||
/// the user rather than being put on a pipe or stored in a file. | /// \brief Cached page size, this cannot vary during the life of the proc | |||
static bool FileDescriptorIsDisplayed(int fd); | ess. | |||
size_t PageSize; | ||||
/// This function determines if the given file descriptor is displayd | ||||
and | /// @} | |||
/// supports colors. | ||||
static bool FileDescriptorHasColors(int fd); | /// \brief Constructor, used by \c process::get_self() only. | |||
self_process(); | ||||
/// This function determines the number of columns in the window | }; | |||
/// if standard output is connected to a "tty" or "console" | ||||
/// window. If standard output is not connected to a tty or | /// \brief A collection of legacy interfaces for querying information about | |||
/// console, or if the number of columns cannot be determined, | the | |||
/// this routine returns zero. | /// current executing process. | |||
static unsigned StandardOutColumns(); | class Process { | |||
public: | ||||
/// This function determines the number of columns in the window | /// \brief Return process memory usage. | |||
/// if standard error is connected to a "tty" or "console" | /// This static function will return the total amount of memory allocated | |||
/// window. If standard error is not connected to a tty or | /// by the process. This only counts the memory allocated via the malloc, | |||
/// console, or if the number of columns cannot be determined, | /// calloc and realloc functions and includes any "free" holes in the | |||
/// this routine returns zero. | /// allocated space. | |||
static unsigned StandardErrColumns(); | static size_t GetMallocUsage(); | |||
/// This function determines whether the terminal connected to standa | /// This static function will set \p user_time to the amount of CPU time | |||
rd | /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU | |||
/// output supports colors. If standard output is not connected to a | /// time spent in system (kernel) mode. If the operating system does not | |||
/// terminal, this function returns false. | /// support collection of these metrics, a zero TimeValue will be for bot | |||
static bool StandardOutHasColors(); | h | |||
/// values. | ||||
/// This function determines whether the terminal connected to standa | /// \param elapsed Returns the TimeValue::now() giving current time | |||
rd | /// \param user_time Returns the current amount of user time for the proc | |||
/// error supports colors. If standard error is not connected to a | ess | |||
/// terminal, this function returns false. | /// \param sys_time Returns the current amount of system time for the pro | |||
static bool StandardErrHasColors(); | cess | |||
static void GetTimeUsage(TimeValue &elapsed, TimeValue &user_time, | ||||
/// Whether changing colors requires the output to be flushed. | TimeValue &sys_time); | |||
/// This is needed on systems that don't support escape sequences for | ||||
/// changing colors. | /// This static function will return the process' current user id number. | |||
static bool ColorNeedsFlush(); | /// Not all operating systems support this feature. Where it is not | |||
/// supported, the function should return 65536 as the value. | ||||
/// This function returns the colorcode escape sequences. | static int GetCurrentUserId(); | |||
/// If ColorNeedsFlush() is true then this function will change the c | ||||
olors | /// This static function will return the process' current group id number | |||
/// and return an empty escape sequence. In that case it is the | . | |||
/// responsibility of the client to flush the output stream prior to | /// Not all operating systems support this feature. Where it is not | |||
/// calling this function. | /// supported, the function should return 65536 as the value. | |||
static const char *OutputColor(char c, bool bold, bool bg); | static int GetCurrentGroupId(); | |||
/// Same as OutputColor, but only enables the bold attribute. | /// This function makes the necessary calls to the operating system to | |||
static const char *OutputBold(bool bg); | /// prevent core files or any other kind of large memory dumps that can | |||
/// occur when a program fails. | ||||
/// This function returns the escape sequence to reverse forground an | /// @brief Prevent core file generation. | |||
d | static void PreventCoreFiles(); | |||
/// background colors. | ||||
static const char *OutputReverse(); | /// This function determines if the standard input is connected directly | |||
/// to a user's input (keyboard probably), rather than coming from a file | ||||
/// Resets the terminals colors, or returns an escape sequence to do | /// or pipe. | |||
so. | static bool StandardInIsUserInput(); | |||
static const char *ResetColor(); | ||||
/// This function determines if the standard output is connected to a | ||||
/// Get the result of a process wide random number generator. The | /// "tty" or "console" window. That is, the output would be displayed to | |||
/// generator will be automatically seeded in non-deterministic fashi | /// the user rather than being put on a pipe or stored in a file. | |||
on. | static bool StandardOutIsDisplayed(); | |||
static unsigned GetRandomNumber(); | ||||
/// @} | /// This function determines if the standard error is connected to a | |||
}; | /// "tty" or "console" window. That is, the output would be displayed to | |||
/// the user rather than being put on a pipe or stored in a file. | ||||
static bool StandardErrIsDisplayed(); | ||||
/// This function determines if the given file descriptor is connected to | ||||
/// a "tty" or "console" window. That is, the output would be displayed t | ||||
o | ||||
/// the user rather than being put on a pipe or stored in a file. | ||||
static bool FileDescriptorIsDisplayed(int fd); | ||||
/// This function determines if the given file descriptor is displayd and | ||||
/// supports colors. | ||||
static bool FileDescriptorHasColors(int fd); | ||||
/// This function determines the number of columns in the window | ||||
/// if standard output is connected to a "tty" or "console" | ||||
/// window. If standard output is not connected to a tty or | ||||
/// console, or if the number of columns cannot be determined, | ||||
/// this routine returns zero. | ||||
static unsigned StandardOutColumns(); | ||||
/// This function determines the number of columns in the window | ||||
/// if standard error is connected to a "tty" or "console" | ||||
/// window. If standard error is not connected to a tty or | ||||
/// console, or if the number of columns cannot be determined, | ||||
/// this routine returns zero. | ||||
static unsigned StandardErrColumns(); | ||||
/// This function determines whether the terminal connected to standard | ||||
/// output supports colors. If standard output is not connected to a | ||||
/// terminal, this function returns false. | ||||
static bool StandardOutHasColors(); | ||||
/// This function determines whether the terminal connected to standard | ||||
/// error supports colors. If standard error is not connected to a | ||||
/// terminal, this function returns false. | ||||
static bool StandardErrHasColors(); | ||||
/// Whether changing colors requires the output to be flushed. | ||||
/// This is needed on systems that don't support escape sequences for | ||||
/// changing colors. | ||||
static bool ColorNeedsFlush(); | ||||
/// This function returns the colorcode escape sequences. | ||||
/// If ColorNeedsFlush() is true then this function will change the color | ||||
s | ||||
/// and return an empty escape sequence. In that case it is the | ||||
/// responsibility of the client to flush the output stream prior to | ||||
/// calling this function. | ||||
static const char *OutputColor(char c, bool bold, bool bg); | ||||
/// Same as OutputColor, but only enables the bold attribute. | ||||
static const char *OutputBold(bool bg); | ||||
/// This function returns the escape sequence to reverse forground and | ||||
/// background colors. | ||||
static const char *OutputReverse(); | ||||
/// Resets the terminals colors, or returns an escape sequence to do so. | ||||
static const char *ResetColor(); | ||||
/// Get the result of a process wide random number generator. The | ||||
/// generator will be automatically seeded in non-deterministic fashion. | ||||
static unsigned GetRandomNumber(); | ||||
}; | ||||
} | } | |||
} | } | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
165 lines changed or deleted | 250 lines changed or added | |||
ProfileDataLoader.h | ProfileDataLoader.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// The ProfileDataLoader class is used to load profiling data from a dump f ile. | // The ProfileDataLoader class is used to load profiling data from a dump f ile. | |||
// The ProfileDataT<FType, BType> class is used to store the mapping of thi s | // The ProfileDataT<FType, BType> class is used to store the mapping of thi s | |||
// data to control flow edges. | // data to control flow edges. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H | #ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H | |||
#define LLVM_ANALYSIS_PROFILEDATALOADER_H | #define LLVM_ANALYSIS_PROFILEDATALOADER_H | |||
#include "llvm/ADT/ArrayRef.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/Support/Debug.h" | #include "llvm/Support/Debug.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class ModulePass; | class ModulePass; | |||
class Function; | class Function; | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 1 lines changed or added | |||
ProfileInfo.h | ProfileInfo.h | |||
---|---|---|---|---|
skipping to change at line 29 | skipping to change at line 29 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_PROFILEINFO_H | #ifndef LLVM_ANALYSIS_PROFILEINFO_H | |||
#define LLVM_ANALYSIS_PROFILEINFO_H | #define LLVM_ANALYSIS_PROFILEINFO_H | |||
#include "llvm/Support/Debug.h" | #include "llvm/Support/Debug.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include "llvm/Support/Format.h" | #include "llvm/Support/Format.h" | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
#include <cassert> | #include <cassert> | |||
#include <string> | ||||
#include <map> | #include <map> | |||
#include <set> | #include <set> | |||
#include <string> | ||||
namespace llvm { | namespace llvm { | |||
class Pass; | class Pass; | |||
class raw_ostream; | class raw_ostream; | |||
class BasicBlock; | class BasicBlock; | |||
class Function; | class Function; | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
class MachineFunction; | class MachineFunction; | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
ProfileInfoLoader.h | ProfileInfoLoader.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// The ProfileInfoLoader class is used to load and represent profiling | // The ProfileInfoLoader class is used to load and represent profiling | |||
// information read in from the dump file. If conversions between formats are | // information read in from the dump file. If conversions between formats are | |||
// needed, it can also do this. | // needed, it can also do this. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H | #ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H | |||
#define LLVM_ANALYSIS_PROFILEINFOLOADER_H | #define LLVM_ANALYSIS_PROFILEINFOLOADER_H | |||
#include <vector> | ||||
#include <string> | #include <string> | |||
#include <utility> | #include <utility> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
class Module; | class Module; | |||
class Function; | class Function; | |||
class BasicBlock; | class BasicBlock; | |||
class ProfileInfoLoader { | class ProfileInfoLoader { | |||
const std::string &Filename; | const std::string &Filename; | |||
std::vector<std::string> CommandLines; | std::vector<std::string> CommandLines; | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Program.h | Program.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the llvm::sys::Program class. | // This file declares the llvm::sys::Program class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_PROGRAM_H | #ifndef LLVM_SUPPORT_PROGRAM_H | |||
#define LLVM_SYSTEM_PROGRAM_H | #define LLVM_SUPPORT_PROGRAM_H | |||
#include "llvm/ADT/ArrayRef.h" | ||||
#include "llvm/Support/Path.h" | #include "llvm/Support/Path.h" | |||
namespace llvm { | namespace llvm { | |||
class error_code; | class error_code; | |||
namespace sys { | namespace sys { | |||
// TODO: Add operations to communicate with the process, redirect its I/O , | // TODO: Add operations to communicate with the process, redirect its I/O , | |||
// etc. | // etc. | |||
/// This class provides an abstraction for programs that are executable b y the | /// This class provides an abstraction for programs that are executable b y the | |||
skipping to change at line 42 | skipping to change at line 43 | |||
class Program { | class Program { | |||
/// Opaque handle for target specific data. | /// Opaque handle for target specific data. | |||
void *Data_; | void *Data_; | |||
// Noncopyable. | // Noncopyable. | |||
Program(const Program& other) LLVM_DELETED_FUNCTION; | Program(const Program& other) LLVM_DELETED_FUNCTION; | |||
Program& operator=(const Program& other) LLVM_DELETED_FUNCTION; | Program& operator=(const Program& other) LLVM_DELETED_FUNCTION; | |||
/// @name Methods | /// @name Methods | |||
/// @{ | /// @{ | |||
public: | ||||
Program(); | Program(); | |||
~Program(); | ~Program(); | |||
/// Return process ID of this program. | ||||
unsigned GetPid() const; | ||||
/// This function executes the program using the \p arguments provided. The | /// This function executes the program using the \p arguments provided. The | |||
/// invoked program will inherit the stdin, stdout, and stderr file | /// invoked program will inherit the stdin, stdout, and stderr file | |||
/// descriptors, the environment and other configuration settings of th e | /// descriptors, the environment and other configuration settings of th e | |||
/// invoking program. If Path::executable() does not return true when t his | /// invoking program. If Path::executable() does not return true when t his | |||
/// function is called then a std::string is thrown. | /// function is called then a std::string is thrown. | |||
/// @returns false in case of error, true otherwise. | /// @returns false in case of error, true otherwise. | |||
/// @see FindProgramByName | /// @see FindProgramByName | |||
/// @brief Executes the program with the given set of \p args. | /// @brief Executes the program with the given set of \p args. | |||
bool Execute | bool Execute | |||
( const Path& path, ///< sys::Path object providing the path of the | ( const Path& path, ///< sys::Path object providing the path of the | |||
skipping to change at line 106 | skipping to change at line 103 | |||
unsigned secondsToWait, ///< If non-zero, this specifies the amount | unsigned secondsToWait, ///< If non-zero, this specifies the amount | |||
///< of time to wait for the child process to exit. If the time | ///< of time to wait for the child process to exit. If the time | |||
///< expires, the child is killed and this call returns. If zero, | ///< expires, the child is killed and this call returns. If zero, | |||
///< this function will wait until the child finishes or forever if | ///< this function will wait until the child finishes or forever if | |||
///< it doesn't. | ///< it doesn't. | |||
std::string* ErrMsg ///< If non-zero, provides a pointer to a string | std::string* ErrMsg ///< If non-zero, provides a pointer to a string | |||
///< instance in which error messages will be returned. If the string | ///< instance in which error messages will be returned. If the string | |||
///< is non-empty upon return an error occurred while waiting. | ///< is non-empty upon return an error occurred while waiting. | |||
); | ); | |||
/// This function terminates the program. | public: | |||
/// @returns true if an error occurred. | ||||
/// @see Execute | ||||
/// @brief Terminates the program. | ||||
bool Kill | ||||
( std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a str | ||||
ing | ||||
///< instance in which error messages will be returned. If the string | ||||
///< is non-empty upon return an error occurred while killing the | ||||
///< program. | ||||
); | ||||
/// This static constructor (factory) will attempt to locate a program in | /// This static constructor (factory) will attempt to locate a program in | |||
/// the operating system's file system using some pre-determined set of | /// 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 | /// locations to search (e.g. the PATH on Unix). Paths with slashes are | |||
/// returned unmodified. | /// returned unmodified. | |||
/// @returns A Path object initialized to the path of the program or a | /// @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 fou nd. | /// Path object that is empty (invalid) if the program could not be fou nd. | |||
/// @brief Construct a Program by finding it by name. | /// @brief Construct a Program by finding it by name. | |||
static Path FindProgramByName(const std::string& name); | static Path FindProgramByName(const std::string& name); | |||
// These methods change the specified standard stream (stdin, stdout, o r | // These methods change the specified standard stream (stdin, stdout, o r | |||
skipping to change at line 142 | skipping to change at line 129 | |||
/// A convenience function equivalent to Program prg; prg.Execute(..); | /// A convenience function equivalent to Program prg; prg.Execute(..); | |||
/// prg.Wait(..); | /// prg.Wait(..); | |||
/// @see Execute, Wait | /// @see Execute, Wait | |||
static int ExecuteAndWait(const Path& path, | static int ExecuteAndWait(const Path& path, | |||
const char** args, | const char** args, | |||
const char ** env = 0, | const char ** env = 0, | |||
const sys::Path** redirects = 0, | const sys::Path** redirects = 0, | |||
unsigned secondsToWait = 0, | unsigned secondsToWait = 0, | |||
unsigned memoryLimit = 0, | unsigned memoryLimit = 0, | |||
std::string* ErrMsg = 0); | std::string* ErrMsg = 0, | |||
bool *ExecutionFailed = 0); | ||||
/// A convenience function equivalent to Program prg; prg.Execute(..); | /// A convenience function equivalent to Program prg; prg.Execute(..); | |||
/// @see Execute | /// @see Execute | |||
static void ExecuteNoWait(const Path& path, | static void ExecuteNoWait(const Path& path, | |||
const char** args, | const char** args, | |||
const char ** env = 0, | const char ** env = 0, | |||
const sys::Path** redirects = 0, | const sys::Path** redirects = 0, | |||
unsigned memoryLimit = 0, | unsigned memoryLimit = 0, | |||
std::string* ErrMsg = 0); | std::string* ErrMsg = 0); | |||
/// @} | /// @} | |||
}; | }; | |||
// Return true if the given arguments fit within system-specific | ||||
// argument length limits. | ||||
bool argumentsFitWithinSystemLimits(ArrayRef<const char*> Args); | ||||
} | } | |||
} | } | |||
#endif | #endif | |||
End of changes. 7 change blocks. | ||||
19 lines changed or deleted | 10 lines changed or added | |||
PromoteMemToReg.h | PromoteMemToReg.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file exposes an interface to promote alloca instructions to SSA | // This file exposes an interface to promote alloca instructions to SSA | |||
// registers, by using the SSA construction algorithm. | // registers, by using the SSA construction algorithm. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef TRANSFORMS_UTILS_PROMOTEMEMTOREG_H | #ifndef LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H | |||
#define TRANSFORMS_UTILS_PROMOTEMEMTOREG_H | #define LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class AllocaInst; | class AllocaInst; | |||
class DominatorTree; | class DominatorTree; | |||
class AliasSetTracker; | class AliasSetTracker; | |||
/// isAllocaPromotable - Return true if this alloca is legal for promotion. | /// isAllocaPromotable - Return true if this alloca is legal for promotion. | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
PseudoSourceValue.h | PseudoSourceValue.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the declaration of the PseudoSourceValue class. | // This file contains the declaration of the PseudoSourceValue class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_PSEUDOSOURCEVALUE_H | #ifndef LLVM_CODEGEN_PSEUDOSOURCEVALUE_H | |||
#define LLVM_CODEGEN_PSEUDOSOURCEVALUE_H | #define LLVM_CODEGEN_PSEUDOSOURCEVALUE_H | |||
#include "llvm/Value.h" | #include "llvm/IR/Value.h" | |||
namespace llvm { | namespace llvm { | |||
class MachineFrameInfo; | class MachineFrameInfo; | |||
class raw_ostream; | class raw_ostream; | |||
/// PseudoSourceValue - Special value supplied for machine level alias | /// PseudoSourceValue - Special value supplied for machine level alias | |||
/// analysis. It indicates that a memory access references the functions | /// analysis. It indicates that a memory access references the functions | |||
/// stack frame (e.g., a spill slot), below the stack frame (e.g., argume nt | /// stack frame (e.g., a spill slot), below the stack frame (e.g., argume nt | |||
/// space), or constant pool. | /// space), or constant pool. | |||
class PseudoSourceValue : public Value { | class PseudoSourceValue : public Value { | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
ReaderWriter.h | ReaderWriter.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This header defines interfaces to read and write LLVM bitcode files/stre ams. | // This header defines interfaces to read and write LLVM bitcode files/stre ams. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_BITCODE_H | #ifndef LLVM_BITCODE_READERWRITER_H | |||
#define LLVM_BITCODE_H | #define LLVM_BITCODE_READERWRITER_H | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class BitstreamWriter; | class BitstreamWriter; | |||
class MemoryBuffer; | class MemoryBuffer; | |||
class DataStreamer; | class DataStreamer; | |||
class LLVMContext; | class LLVMContext; | |||
class Module; | class Module; | |||
class ModulePass; | class ModulePass; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Record.h | Record.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TABLEGEN_RECORD_H | #ifndef LLVM_TABLEGEN_RECORD_H | |||
#define LLVM_TABLEGEN_RECORD_H | #define LLVM_TABLEGEN_RECORD_H | |||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/FoldingSet.h" | #include "llvm/ADT/FoldingSet.h" | |||
#include "llvm/Support/Allocator.h" | #include "llvm/Support/Allocator.h" | |||
#include "llvm/Support/Casting.h" | #include "llvm/Support/Casting.h" | |||
#include "llvm/Support/SourceMgr.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include "llvm/Support/SourceMgr.h" | ||||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
#include <map> | #include <map> | |||
namespace llvm { | namespace llvm { | |||
class raw_ostream; | class raw_ostream; | |||
// RecTy subclasses. | // RecTy subclasses. | |||
class BitRecTy; | class BitRecTy; | |||
class BitsRecTy; | class BitsRecTy; | |||
class IntRecTy; | class IntRecTy; | |||
skipping to change at line 131 | skipping to change at line 131 | |||
virtual Init *convertValue( DefInit *DI) { return 0; } | virtual Init *convertValue( DefInit *DI) { return 0; } | |||
virtual Init *convertValue( DagInit *DI) { return 0; } | virtual Init *convertValue( DagInit *DI) { return 0; } | |||
virtual Init *convertValue( TypedInit *TI) { return 0; } | virtual Init *convertValue( TypedInit *TI) { return 0; } | |||
virtual Init *convertValue( VarInit *VI) { | virtual Init *convertValue( VarInit *VI) { | |||
return convertValue((TypedInit*)VI); | return convertValue((TypedInit*)VI); | |||
} | } | |||
virtual Init *convertValue( FieldInit *FI) { | virtual Init *convertValue( FieldInit *FI) { | |||
return convertValue((TypedInit*)FI); | return convertValue((TypedInit*)FI); | |||
} | } | |||
public: // These methods should only be called by subclasses of RecTy. | public: | |||
// baseClassOf - These virtual methods should be overloaded to return tru | virtual bool baseClassOf(const RecTy*) const; | |||
e iff | ||||
// all values of type 'RHS' can be converted to the 'this' type. | ||||
virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } | ||||
}; | }; | |||
inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { | inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { | |||
Ty.print(OS); | Ty.print(OS); | |||
return OS; | return OS; | |||
} | } | |||
/// BitRecTy - 'bit' - Represent a single bit | /// BitRecTy - 'bit' - Represent a single bit | |||
/// | /// | |||
class BitRecTy : public RecTy { | class BitRecTy : public RecTy { | |||
skipping to change at line 181 | skipping to change at line 173 | |||
virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue( UI);} | virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue( UI);} | |||
virtual Init *convertValue( TypedInit *TI); | virtual Init *convertValue( TypedInit *TI); | |||
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | |||
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | |||
virtual std::string getAsString() const { return "bit"; } | virtual std::string getAsString() const { return "bit"; } | |||
virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | |||
return RHS->baseClassOf(this); | return RHS->baseClassOf(this); | |||
} | } | |||
virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } | virtual bool baseClassOf(const RecTy*) const; | |||
virtual bool baseClassOf(const BitsRecTy *RHS) const; | ||||
virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } | ||||
virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } | ||||
}; | }; | |||
// BitsRecTy - 'bits<n>' - Represent a fixed number of bits | /// BitsRecTy - 'bits<n>' - Represent a fixed number of bits | |||
/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits | ||||
/// | /// | |||
class BitsRecTy : public RecTy { | class BitsRecTy : public RecTy { | |||
unsigned Size; | unsigned Size; | |||
explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {} | explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {} | |||
public: | public: | |||
static bool classof(const RecTy *RT) { | static bool classof(const RecTy *RT) { | |||
return RT->getRecTyKind() == BitsRecTyKind; | return RT->getRecTyKind() == BitsRecTyKind; | |||
} | } | |||
static BitsRecTy *get(unsigned Sz); | static BitsRecTy *get(unsigned Sz); | |||
skipping to change at line 227 | skipping to change at line 211 | |||
virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue( UI);} | virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue( UI);} | |||
virtual Init *convertValue( TypedInit *TI); | virtual Init *convertValue( TypedInit *TI); | |||
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | |||
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | |||
virtual std::string getAsString() const; | virtual std::string getAsString() const; | |||
virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | |||
return RHS->baseClassOf(this); | return RHS->baseClassOf(this); | |||
} | } | |||
virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1 | virtual bool baseClassOf(const RecTy*) const; | |||
; } | ||||
virtual bool baseClassOf(const BitsRecTy *RHS) const { | ||||
return RHS->Size == Size; | ||||
} | ||||
virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } | ||||
virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } | ||||
}; | }; | |||
/// IntRecTy - 'int' - Represent an integer value of no particular size | /// IntRecTy - 'int' - Represent an integer value of no particular size | |||
/// | /// | |||
class IntRecTy : public RecTy { | class IntRecTy : public RecTy { | |||
static IntRecTy Shared; | static IntRecTy Shared; | |||
IntRecTy() : RecTy(IntRecTyKind) {} | IntRecTy() : RecTy(IntRecTyKind) {} | |||
public: | public: | |||
static bool classof(const RecTy *RT) { | static bool classof(const RecTy *RT) { | |||
return RT->getRecTyKind() == IntRecTyKind; | return RT->getRecTyKind() == IntRecTyKind; | |||
skipping to change at line 273 | skipping to change at line 248 | |||
virtual Init *convertValue( TypedInit *TI); | virtual Init *convertValue( TypedInit *TI); | |||
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | |||
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | |||
virtual std::string getAsString() const { return "int"; } | virtual std::string getAsString() const { return "int"; } | |||
virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | |||
return RHS->baseClassOf(this); | return RHS->baseClassOf(this); | |||
} | } | |||
virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } | virtual bool baseClassOf(const RecTy*) const; | |||
virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; } | ||||
virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } | ||||
virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } | ||||
}; | }; | |||
/// StringRecTy - 'string' - Represent an string value | /// StringRecTy - 'string' - Represent an string value | |||
/// | /// | |||
class StringRecTy : public RecTy { | class StringRecTy : public RecTy { | |||
static StringRecTy Shared; | static StringRecTy Shared; | |||
StringRecTy() : RecTy(StringRecTyKind) {} | StringRecTy() : RecTy(StringRecTyKind) {} | |||
public: | public: | |||
static bool classof(const RecTy *RT) { | static bool classof(const RecTy *RT) { | |||
return RT->getRecTyKind() == StringRecTyKind; | return RT->getRecTyKind() == StringRecTyKind; | |||
skipping to change at line 317 | skipping to change at line 285 | |||
virtual Init *convertValue( DagInit *DI) { return 0; } | virtual Init *convertValue( DagInit *DI) { return 0; } | |||
virtual Init *convertValue( TypedInit *TI); | virtual Init *convertValue( TypedInit *TI); | |||
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | |||
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | |||
virtual std::string getAsString() const { return "string"; } | virtual std::string getAsString() const { return "string"; } | |||
virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | |||
return RHS->baseClassOf(this); | return RHS->baseClassOf(this); | |||
} | } | |||
virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const StringRecTy *RHS) const { return true; } | ||||
virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } | ||||
}; | }; | |||
// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must b | /// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must | |||
e of | be of | |||
// the specified type. | /// the specified type. | |||
/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which | ||||
must | ||||
/// be of the specified type. | ||||
/// | /// | |||
class ListRecTy : public RecTy { | class ListRecTy : public RecTy { | |||
RecTy *Ty; | RecTy *Ty; | |||
explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {} | explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {} | |||
friend ListRecTy *RecTy::getListTy(); | friend ListRecTy *RecTy::getListTy(); | |||
public: | public: | |||
static bool classof(const RecTy *RT) { | static bool classof(const RecTy *RT) { | |||
return RT->getRecTyKind() == ListRecTyKind; | return RT->getRecTyKind() == ListRecTyKind; | |||
} | } | |||
skipping to change at line 366 | skipping to change at line 324 | |||
virtual Init *convertValue( TypedInit *TI); | virtual Init *convertValue( TypedInit *TI); | |||
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | |||
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | |||
virtual std::string getAsString() const; | virtual std::string getAsString() const; | |||
virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | |||
return RHS->baseClassOf(this); | return RHS->baseClassOf(this); | |||
} | } | |||
virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } | virtual bool baseClassOf(const RecTy*) const; | |||
virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const ListRecTy *RHS) const { | ||||
return RHS->getElementType()->typeIsConvertibleTo(Ty); | ||||
} | ||||
virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } | ||||
}; | }; | |||
/// DagRecTy - 'dag' - Represent a dag fragment | /// DagRecTy - 'dag' - Represent a dag fragment | |||
/// | /// | |||
class DagRecTy : public RecTy { | class DagRecTy : public RecTy { | |||
static DagRecTy Shared; | static DagRecTy Shared; | |||
DagRecTy() : RecTy(DagRecTyKind) {} | DagRecTy() : RecTy(DagRecTyKind) {} | |||
public: | public: | |||
static bool classof(const RecTy *RT) { | static bool classof(const RecTy *RT) { | |||
return RT->getRecTyKind() == DagRecTyKind; | return RT->getRecTyKind() == DagRecTyKind; | |||
skipping to change at line 410 | skipping to change at line 360 | |||
virtual Init *convertValue( DagInit *CI) { return (Init*)CI; } | virtual Init *convertValue( DagInit *CI) { return (Init*)CI; } | |||
virtual Init *convertValue( TypedInit *TI); | virtual Init *convertValue( TypedInit *TI); | |||
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | |||
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | |||
virtual std::string getAsString() const { return "dag"; } | virtual std::string getAsString() const { return "dag"; } | |||
virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | |||
return RHS->baseClassOf(this); | return RHS->baseClassOf(this); | |||
} | } | |||
virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const DagRecTy *RHS) const { return true; } | ||||
virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } | ||||
}; | }; | |||
/// RecordRecTy - '[classname]' - Represent an instance of a class, such as : | /// RecordRecTy - '[classname]' - Represent an instance of a class, such as : | |||
/// (R32 X = EAX). | /// (R32 X = EAX). | |||
/// | /// | |||
class RecordRecTy : public RecTy { | class RecordRecTy : public RecTy { | |||
Record *Rec; | Record *Rec; | |||
explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {} | explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {} | |||
friend class Record; | friend class Record; | |||
public: | public: | |||
skipping to change at line 457 | skipping to change at line 399 | |||
virtual Init *convertValue( DagInit *DI) { return 0; } | virtual Init *convertValue( DagInit *DI) { return 0; } | |||
virtual Init *convertValue( TypedInit *VI); | virtual Init *convertValue( TypedInit *VI); | |||
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(V I);} | |||
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(F I);} | |||
virtual std::string getAsString() const; | virtual std::string getAsString() const; | |||
virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | virtual bool typeIsConvertibleTo(const RecTy *RHS) const { | |||
return RHS->baseClassOf(this); | return RHS->baseClassOf(this); | |||
} | } | |||
virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } | virtual bool baseClassOf(const RecTy*) const; | |||
virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } | ||||
virtual bool baseClassOf(const RecordRecTy *RHS) const; | ||||
}; | }; | |||
/// resolveTypes - Find a common type that T1 and T2 convert to. | /// resolveTypes - Find a common type that T1 and T2 convert to. | |||
/// Return 0 if no such type exists. | /// Return 0 if no such type exists. | |||
/// | /// | |||
RecTy *resolveTypes(RecTy *T1, RecTy *T2); | RecTy *resolveTypes(RecTy *T1, RecTy *T2); | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Initializer Classes | // Initializer Classes | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
skipping to change at line 984 | skipping to change at line 920 | |||
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; | virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; | |||
virtual std::string getAsString() const; | virtual std::string getAsString() const; | |||
}; | }; | |||
/// BinOpInit - !op (X, Y) - Combine two inits. | /// BinOpInit - !op (X, Y) - Combine two inits. | |||
/// | /// | |||
class BinOpInit : public OpInit { | class BinOpInit : public OpInit { | |||
public: | public: | |||
enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, EQ }; | enum BinaryOp { ADD, SHL, SRA, SRL, STRCONCAT, CONCAT, EQ }; | |||
private: | private: | |||
BinaryOp Opc; | BinaryOp Opc; | |||
Init *LHS, *RHS; | Init *LHS, *RHS; | |||
BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) : | BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) : | |||
OpInit(IK_BinOpInit, Type), Opc(opc), LHS(lhs), RHS(rhs) {} | OpInit(IK_BinOpInit, Type), Opc(opc), LHS(lhs), RHS(rhs) {} | |||
BinOpInit(const BinOpInit &Other) LLVM_DELETED_FUNCTION; | BinOpInit(const BinOpInit &Other) LLVM_DELETED_FUNCTION; | |||
BinOpInit &operator=(const BinOpInit &Other) LLVM_DELETED_FUNCTION; | BinOpInit &operator=(const BinOpInit &Other) LLVM_DELETED_FUNCTION; | |||
skipping to change at line 1438 | skipping to change at line 1374 | |||
static unsigned LastID; | static unsigned LastID; | |||
// Unique record ID. | // Unique record ID. | |||
unsigned ID; | unsigned ID; | |||
Init *Name; | Init *Name; | |||
// Location where record was instantiated, followed by the location of | // Location where record was instantiated, followed by the location of | |||
// multiclass prototypes used. | // multiclass prototypes used. | |||
SmallVector<SMLoc, 4> Locs; | SmallVector<SMLoc, 4> Locs; | |||
std::vector<Init *> TemplateArgs; | std::vector<Init *> TemplateArgs; | |||
std::vector<RecordVal> Values; | std::vector<RecordVal> Values; | |||
std::vector<Record*> SuperClasses; | std::vector<Record *> SuperClasses; | |||
std::vector<SMRange> SuperClassRanges; | ||||
// Tracks Record instances. Not owned by Record. | // Tracks Record instances. Not owned by Record. | |||
RecordKeeper &TrackedRecords; | RecordKeeper &TrackedRecords; | |||
DefInit *TheInit; | DefInit *TheInit; | |||
bool IsAnonymous; | ||||
void init(); | void init(); | |||
void checkName(); | void checkName(); | |||
public: | public: | |||
// Constructs a record. | // Constructs a record. | |||
explicit Record(const std::string &N, ArrayRef<SMLoc> locs, | explicit Record(const std::string &N, ArrayRef<SMLoc> locs, | |||
RecordKeeper &records) : | RecordKeeper &records, bool Anonymous = false) : | |||
ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()), | ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()), | |||
TrackedRecords(records), TheInit(0) { | TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) { | |||
init(); | init(); | |||
} | } | |||
explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records) : | explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records, | |||
bool Anonymous = false) : | ||||
ID(LastID++), Name(N), Locs(locs.begin(), locs.end()), | ID(LastID++), Name(N), Locs(locs.begin(), locs.end()), | |||
TrackedRecords(records), TheInit(0) { | TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) { | |||
init(); | init(); | |||
} | } | |||
// When copy-constructing a Record, we must still guarantee a globally un ique | // When copy-constructing a Record, we must still guarantee a globally un ique | |||
// ID number. All other fields can be copied normally. | // ID number. All other fields can be copied normally. | |||
Record(const Record &O) : | Record(const Record &O) : | |||
ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), | ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), | |||
Values(O.Values), SuperClasses(O.SuperClasses), | Values(O.Values), SuperClasses(O.SuperClasses), | |||
TrackedRecords(O.TrackedRecords), TheInit(O.TheInit) { } | SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords), | |||
TheInit(O.TheInit), IsAnonymous(O.IsAnonymous) { } | ||||
~Record() {} | ~Record() {} | |||
static unsigned getNewUID() { return LastID++; } | static unsigned getNewUID() { return LastID++; } | |||
unsigned getID() const { return ID; } | unsigned getID() const { return ID; } | |||
const std::string &getName() const; | const std::string &getName() const; | |||
Init *getNameInit() const { | Init *getNameInit() const { | |||
return Name; | return Name; | |||
skipping to change at line 1497 | skipping to change at line 1437 | |||
ArrayRef<SMLoc> getLoc() const { return Locs; } | ArrayRef<SMLoc> getLoc() const { return Locs; } | |||
/// get the corresponding DefInit. | /// get the corresponding DefInit. | |||
DefInit *getDefInit(); | DefInit *getDefInit(); | |||
const std::vector<Init *> &getTemplateArgs() const { | const std::vector<Init *> &getTemplateArgs() const { | |||
return TemplateArgs; | return TemplateArgs; | |||
} | } | |||
const std::vector<RecordVal> &getValues() const { return Values; } | const std::vector<RecordVal> &getValues() const { return Values; } | |||
const std::vector<Record*> &getSuperClasses() const { return SuperClass es; } | const std::vector<Record*> &getSuperClasses() const { return SuperClass es; } | |||
ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; } | ||||
bool isTemplateArg(Init *Name) const { | bool isTemplateArg(Init *Name) const { | |||
for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i) | for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i) | |||
if (TemplateArgs[i] == Name) return true; | if (TemplateArgs[i] == Name) return true; | |||
return false; | return false; | |||
} | } | |||
bool isTemplateArg(StringRef Name) const { | bool isTemplateArg(StringRef Name) const { | |||
return isTemplateArg(StringInit::get(Name.str())); | return isTemplateArg(StringInit::get(Name.str())); | |||
} | } | |||
skipping to change at line 1571 | skipping to change at line 1512 | |||
return false; | return false; | |||
} | } | |||
bool isSubClassOf(StringRef Name) const { | bool isSubClassOf(StringRef Name) const { | |||
for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) | for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) | |||
if (SuperClasses[i]->getNameInitAsString() == Name) | if (SuperClasses[i]->getNameInitAsString() == Name) | |||
return true; | return true; | |||
return false; | return false; | |||
} | } | |||
void addSuperClass(Record *R) { | void addSuperClass(Record *R, SMRange Range) { | |||
assert(!isSubClassOf(R) && "Already subclassing record!"); | assert(!isSubClassOf(R) && "Already subclassing record!"); | |||
SuperClasses.push_back(R); | SuperClasses.push_back(R); | |||
SuperClassRanges.push_back(Range); | ||||
} | } | |||
/// resolveReferences - If there are any field references that refer to f ields | /// resolveReferences - If there are any field references that refer to f ields | |||
/// that have been filled in, we can propagate the values now. | /// that have been filled in, we can propagate the values now. | |||
/// | /// | |||
void resolveReferences() { resolveReferencesTo(0); } | void resolveReferences() { resolveReferencesTo(0); } | |||
/// resolveReferencesTo - If anything in this record refers to RV, replac e the | /// resolveReferencesTo - If anything in this record refers to RV, replac e the | |||
/// reference to RV with the RHS of RV. If RV is null, we resolve all | /// reference to RV with the RHS of RV. If RV is null, we resolve all | |||
/// possible references. | /// possible references. | |||
void resolveReferencesTo(const RecordVal *RV); | void resolveReferencesTo(const RecordVal *RV); | |||
RecordKeeper &getRecords() const { | RecordKeeper &getRecords() const { | |||
return TrackedRecords; | return TrackedRecords; | |||
} | } | |||
bool isAnonymous() const { | ||||
return IsAnonymous; | ||||
} | ||||
void dump() const; | void dump() const; | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// High-level methods useful to tablegen back-ends | // High-level methods useful to tablegen back-ends | |||
// | // | |||
/// getValueInit - Return the initializer for a value with the specified name, | /// getValueInit - Return the initializer for a value with the specified name, | |||
/// or throw an exception if the field does not exist. | /// or throw an exception if the field does not exist. | |||
/// | /// | |||
Init *getValueInit(StringRef FieldName) const; | Init *getValueInit(StringRef FieldName) const; | |||
/// Return true if the named field is unset. | ||||
bool isValueUnset(StringRef FieldName) const { | ||||
return getValueInit(FieldName) == UnsetInit::get(); | ||||
} | ||||
/// getValueAsString - This method looks up the specified field and retur ns | /// getValueAsString - This method looks up the specified field and retur ns | |||
/// its value as a string, throwing an exception if the field does not ex ist | /// its value as a string, throwing an exception if the field does not ex ist | |||
/// or if the value is not a string. | /// or if the value is not a string. | |||
/// | /// | |||
std::string getValueAsString(StringRef FieldName) const; | std::string getValueAsString(StringRef FieldName) const; | |||
/// getValueAsBitsInit - This method looks up the specified field and ret urns | /// getValueAsBitsInit - This method looks up the specified field and ret urns | |||
/// its value as a BitsInit, throwing an exception if the field does not exist | /// its value as a BitsInit, throwing an exception if the field does not exist | |||
/// or if the value is not the right type. | /// or if the value is not the right type. | |||
/// | /// | |||
End of changes. 25 change blocks. | ||||
87 lines changed or deleted | 35 lines changed or added | |||
Recycler.h | Recycler.h | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
#ifndef LLVM_SUPPORT_RECYCLER_H | #ifndef LLVM_SUPPORT_RECYCLER_H | |||
#define LLVM_SUPPORT_RECYCLER_H | #define LLVM_SUPPORT_RECYCLER_H | |||
#include "llvm/ADT/ilist.h" | #include "llvm/ADT/ilist.h" | |||
#include "llvm/Support/AlignOf.h" | #include "llvm/Support/AlignOf.h" | |||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
class BumpPtrAllocator; | ||||
/// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for | /// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for | |||
/// printing statistics. | /// printing statistics. | |||
/// | /// | |||
void PrintRecyclerStats(size_t Size, size_t Align, size_t FreeListSize); | void PrintRecyclerStats(size_t Size, size_t Align, size_t FreeListSize); | |||
/// RecyclerStruct - Implementation detail for Recycler. This is a | /// RecyclerStruct - Implementation detail for Recycler. This is a | |||
/// class that the recycler imposes on free'd memory to carve out | /// class that the recycler imposes on free'd memory to carve out | |||
/// next/prev pointers. | /// next/prev pointers. | |||
struct RecyclerStruct { | struct RecyclerStruct { | |||
RecyclerStruct *Prev, *Next; | RecyclerStruct *Prev, *Next; | |||
skipping to change at line 90 | skipping to change at line 92 | |||
/// recycler must be free of any tracked allocations before being | /// recycler must be free of any tracked allocations before being | |||
/// deleted; calling clear is one way to ensure this. | /// deleted; calling clear is one way to ensure this. | |||
template<class AllocatorType> | template<class AllocatorType> | |||
void clear(AllocatorType &Allocator) { | void clear(AllocatorType &Allocator) { | |||
while (!FreeList.empty()) { | while (!FreeList.empty()) { | |||
T *t = reinterpret_cast<T *>(FreeList.remove(FreeList.begin())); | T *t = reinterpret_cast<T *>(FreeList.remove(FreeList.begin())); | |||
Allocator.Deallocate(t); | Allocator.Deallocate(t); | |||
} | } | |||
} | } | |||
/// Special case for BumpPtrAllocator which has an empty Deallocate() | ||||
/// function. | ||||
/// | ||||
/// There is no need to traverse the free list, pulling all the objects i | ||||
nto | ||||
/// cache. | ||||
void clear(BumpPtrAllocator&) { | ||||
FreeList.clearAndLeakNodesUnsafely(); | ||||
} | ||||
template<class SubClass, class AllocatorType> | template<class SubClass, class AllocatorType> | |||
SubClass *Allocate(AllocatorType &Allocator) { | SubClass *Allocate(AllocatorType &Allocator) { | |||
assert(sizeof(SubClass) <= Size && | assert(sizeof(SubClass) <= Size && | |||
"Recycler allocation size is less than object size!"); | "Recycler allocation size is less than object size!"); | |||
assert(AlignOf<SubClass>::Alignment <= Align && | assert(AlignOf<SubClass>::Alignment <= Align && | |||
"Recycler allocation alignment is less than object alignment!"); | "Recycler allocation alignment is less than object alignment!"); | |||
return !FreeList.empty() ? | return !FreeList.empty() ? | |||
reinterpret_cast<SubClass *>(FreeList.remove(FreeList.begin())) : | reinterpret_cast<SubClass *>(FreeList.remove(FreeList.begin())) : | |||
static_cast<SubClass *>(Allocator.Allocate(Size, Align)); | static_cast<SubClass *>(Allocator.Allocate(Size, Align)); | |||
} | } | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 12 lines changed or added | |||
RegAllocPBQP.h | RegAllocPBQP.h | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_REGALLOCPBQP_H | #ifndef LLVM_CODEGEN_REGALLOCPBQP_H | |||
#define LLVM_CODEGEN_REGALLOCPBQP_H | #define LLVM_CODEGEN_REGALLOCPBQP_H | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | #include "llvm/CodeGen/MachineFunctionPass.h" | |||
#include "llvm/CodeGen/PBQP/Graph.h" | #include "llvm/CodeGen/PBQP/Graph.h" | |||
#include "llvm/CodeGen/PBQP/Solution.h" | #include "llvm/CodeGen/PBQP/Solution.h" | |||
#include <map> | #include <map> | |||
#include <set> | #include <set> | |||
namespace llvm { | namespace llvm { | |||
class LiveIntervals; | class LiveIntervals; | |||
class MachineFunction; | class MachineFunction; | |||
class MachineLoopInfo; | class MachineLoopInfo; | |||
class TargetRegisterInfo; | ||||
template<class T> class OwningPtr; | ||||
/// This class wraps up a PBQP instance representing a register allocatio n | /// This class wraps up a PBQP instance representing a register allocatio n | |||
/// problem, plus the structures necessary to map back from the PBQP solu tion | /// problem, plus the structures necessary to map back from the PBQP solu tion | |||
/// to a register allocation solution. (i.e. The PBQP-node <--> vreg map, | /// to a register allocation solution. (i.e. The PBQP-node <--> vreg map, | |||
/// and the PBQP option <--> storage location map). | /// and the PBQP option <--> storage location map). | |||
class PBQPRAProblem { | class PBQPRAProblem { | |||
public: | public: | |||
typedef SmallVector<unsigned, 16> AllowedSet; | typedef SmallVector<unsigned, 16> AllowedSet; | |||
skipping to change at line 126 | skipping to change at line 127 | |||
typedef std::set<unsigned> RegSet; | typedef std::set<unsigned> RegSet; | |||
/// Default constructor. | /// Default constructor. | |||
PBQPBuilder() {} | PBQPBuilder() {} | |||
/// Clean up a PBQPBuilder. | /// Clean up a PBQPBuilder. | |||
virtual ~PBQPBuilder() {} | virtual ~PBQPBuilder() {} | |||
/// Build a PBQP instance to represent the register allocation problem for | /// Build a PBQP instance to represent the register allocation problem for | |||
/// the given MachineFunction. | /// the given MachineFunction. | |||
virtual std::auto_ptr<PBQPRAProblem> build( | virtual PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals * | |||
MachineFunction *mf, | lis, | |||
const LiveIntervals *lis, | const MachineLoopInfo *loopInfo, | |||
const MachineLoopInfo *loopIn | const RegSet &vregs); | |||
fo, | ||||
const RegSet &vregs); | ||||
private: | private: | |||
void addSpillCosts(PBQP::Vector &costVec, PBQP::PBQPNum spillCost); | void addSpillCosts(PBQP::Vector &costVec, PBQP::PBQPNum spillCost); | |||
void addInterferenceCosts(PBQP::Matrix &costMat, | void addInterferenceCosts(PBQP::Matrix &costMat, | |||
const PBQPRAProblem::AllowedSet &vr1Allowed, | const PBQPRAProblem::AllowedSet &vr1Allowed, | |||
const PBQPRAProblem::AllowedSet &vr2Allowed, | const PBQPRAProblem::AllowedSet &vr2Allowed, | |||
const TargetRegisterInfo *tri); | const TargetRegisterInfo *tri); | |||
}; | }; | |||
/// Extended builder which adds coalescing constraints to a problem. | /// Extended builder which adds coalescing constraints to a problem. | |||
class PBQPBuilderWithCoalescing : public PBQPBuilder { | class PBQPBuilderWithCoalescing : public PBQPBuilder { | |||
public: | public: | |||
/// Build a PBQP instance to represent the register allocation problem for | /// Build a PBQP instance to represent the register allocation problem for | |||
/// the given MachineFunction. | /// the given MachineFunction. | |||
virtual std::auto_ptr<PBQPRAProblem> build( | virtual PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals * | |||
MachineFunction *mf, | lis, | |||
const LiveIntervals *lis, | const MachineLoopInfo *loopInfo, | |||
const MachineLoopInfo *loopIn | const RegSet &vregs); | |||
fo, | ||||
const RegSet &vregs); | ||||
private: | private: | |||
void addPhysRegCoalesce(PBQP::Vector &costVec, unsigned pregOption, | void addPhysRegCoalesce(PBQP::Vector &costVec, unsigned pregOption, | |||
PBQP::PBQPNum benefit); | PBQP::PBQPNum benefit); | |||
void addVirtRegCoalesce(PBQP::Matrix &costMat, | void addVirtRegCoalesce(PBQP::Matrix &costMat, | |||
const PBQPRAProblem::AllowedSet &vr1Allowed, | const PBQPRAProblem::AllowedSet &vr1Allowed, | |||
const PBQPRAProblem::AllowedSet &vr2Allowed, | const PBQPRAProblem::AllowedSet &vr2Allowed, | |||
PBQP::PBQPNum benefit); | PBQP::PBQPNum benefit); | |||
}; | }; | |||
FunctionPass* createPBQPRegisterAllocator(std::auto_ptr<PBQPBuilder> buil der, | FunctionPass* createPBQPRegisterAllocator(OwningPtr<PBQPBuilder> &builder , | |||
char *customPassID=0); | char *customPassID=0); | |||
} | } | |||
#endif /* LLVM_CODEGEN_REGALLOCPBQP_H */ | #endif /* LLVM_CODEGEN_REGALLOCPBQP_H */ | |||
End of changes. 5 change blocks. | ||||
14 lines changed or deleted | 11 lines changed or added | |||
RegAllocRegistry.h | RegAllocRegistry.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the implementation for register allocator function | // This file contains the implementation for register allocator function | |||
// pass registry (RegisterRegAlloc). | // pass registry (RegisterRegAlloc). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGENREGALLOCREGISTRY_H | #ifndef LLVM_CODEGEN_REGALLOCREGISTRY_H | |||
#define LLVM_CODEGENREGALLOCREGISTRY_H | #define LLVM_CODEGEN_REGALLOCREGISTRY_H | |||
#include "llvm/CodeGen/MachinePassRegistry.h" | #include "llvm/CodeGen/MachinePassRegistry.h" | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// | /// | |||
/// RegisterRegAlloc class - Track the registration of register allocators. | /// RegisterRegAlloc class - Track the registration of register allocators. | |||
/// | /// | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Regex.h | Regex.h | |||
---|---|---|---|---|
//===-- Regex.h - Regular Expression matcher implementation -*- C++ -*----- ===// | //===-- Regex.h - Regular Expression matcher implementation -*- C++ -*----- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements a POSIX regular expression matcher. | // This file implements a POSIX regular expression matcher. Both Basic and | |||
// Extended POSIX regular expressions (ERE) are supported. EREs were exten | ||||
ded | ||||
// to support backreferences in matches. | ||||
// This implementation also supports matching strings with embedded NUL cha | ||||
rs. | ||||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_REGEX_H | #ifndef LLVM_SUPPORT_REGEX_H | |||
#define LLVM_SUPPORT_REGEX_H | #define LLVM_SUPPORT_REGEX_H | |||
#include <string> | #include <string> | |||
struct llvm_regex; | struct llvm_regex; | |||
skipping to change at line 36 | skipping to change at line 39 | |||
public: | public: | |||
enum { | enum { | |||
NoFlags=0, | NoFlags=0, | |||
/// Compile for matching that ignores upper/lower case distinctions. | /// Compile for matching that ignores upper/lower case distinctions. | |||
IgnoreCase=1, | IgnoreCase=1, | |||
/// Compile for newline-sensitive matching. With this flag '[^' brack et | /// Compile for newline-sensitive matching. With this flag '[^' brack et | |||
/// expressions and '.' never match newline. A ^ anchor matches the | /// expressions and '.' never match newline. A ^ anchor matches the | |||
/// null string after any newline in the string in addition to its no rmal | /// null string after any newline in the string in addition to its no rmal | |||
/// function, and the $ anchor matches the null string before any | /// function, and the $ anchor matches the null string before any | |||
/// newline in the string in addition to its normal function. | /// newline in the string in addition to its normal function. | |||
Newline=2 | Newline=2, | |||
/// By default, the POSIX extended regular expression (ERE) syntax is | ||||
/// assumed. Pass this flag to turn on basic regular expressions (BRE | ||||
) | ||||
/// instead. | ||||
BasicRegex=4 | ||||
}; | }; | |||
/// Compiles the given POSIX Extended Regular Expression \p Regex. | /// Compiles the given regular expression \p Regex. | |||
/// This implementation supports regexes and matching strings with embe | ||||
dded | ||||
/// NUL characters. | ||||
Regex(StringRef Regex, unsigned Flags = NoFlags); | Regex(StringRef Regex, unsigned Flags = NoFlags); | |||
~Regex(); | ~Regex(); | |||
/// isValid - returns the error encountered during regex compilation, o r | /// isValid - returns the error encountered during regex compilation, o r | |||
/// matching, if any. | /// matching, if any. | |||
bool isValid(std::string &Error); | bool isValid(std::string &Error); | |||
/// getNumMatches - In a valid regex, return the number of parenthesize d | /// getNumMatches - In a valid regex, return the number of parenthesize d | |||
/// matches it contains. The number filled in by match will include th is | /// matches it contains. The number filled in by match will include th is | |||
/// many entries plus one for the whole regex (as element 0). | /// many entries plus one for the whole regex (as element 0). | |||
End of changes. 3 change blocks. | ||||
6 lines changed or deleted | 13 lines changed or added | |||
RegionInfo.h | RegionInfo.h | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
// different, as it takes advantage of existing information already availab le | // different, as it takes advantage of existing information already availab le | |||
// in (Post)dominace tree and dominance frontier passes. This leads to a si mpler | // in (Post)dominace tree and dominance frontier passes. This leads to a si mpler | |||
// and in practice hopefully better performing algorithm. The runtime of th e | // and in practice hopefully better performing algorithm. The runtime of th e | |||
// algorithms described in the papers above are both linear in graph size, | // algorithms described in the papers above are both linear in graph size, | |||
// O(V+E), whereas this algorithm is not, as the dominance frontier informa tion | // O(V+E), whereas this algorithm is not, as the dominance frontier informa tion | |||
// itself is not, but in practice runtime seems to be in the order of magni tude | // itself is not, but in practice runtime seems to be in the order of magni tude | |||
// of dominance tree calculation. | // of dominance tree calculation. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_REGION_INFO_H | #ifndef LLVM_ANALYSIS_REGIONINFO_H | |||
#define LLVM_ANALYSIS_REGION_INFO_H | #define LLVM_ANALYSIS_REGIONINFO_H | |||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/Analysis/DominanceFrontier.h" | #include "llvm/Analysis/DominanceFrontier.h" | |||
#include "llvm/Analysis/PostDominators.h" | #include "llvm/Analysis/PostDominators.h" | |||
#include "llvm/Support/Allocator.h" | #include "llvm/Support/Allocator.h" | |||
#include <map> | #include <map> | |||
namespace llvm { | namespace llvm { | |||
class Region; | class Region; | |||
skipping to change at line 269 | skipping to change at line 269 | |||
/// | /// | |||
/// @param BB The new entry basic block of the region. | /// @param BB The new entry basic block of the region. | |||
void replaceEntry(BasicBlock *BB); | void replaceEntry(BasicBlock *BB); | |||
/// @brief Replace the exit basic block of the region with the new basic | /// @brief Replace the exit basic block of the region with the new basic | |||
/// block. | /// block. | |||
/// | /// | |||
/// @param BB The new exit basic block of the region. | /// @param BB The new exit basic block of the region. | |||
void replaceExit(BasicBlock *BB); | void replaceExit(BasicBlock *BB); | |||
/// @brief Recursively replace the entry basic block of the region. | ||||
/// | ||||
/// This function replaces the entry basic block with a new basic block. | ||||
It | ||||
/// also updates all child regions that have the same entry basic block a | ||||
s | ||||
/// this region. | ||||
/// | ||||
/// @param NewEntry The new entry basic block. | ||||
void replaceEntryRecursive(BasicBlock *NewEntry); | ||||
/// @brief Recursively replace the exit basic block of the region. | ||||
/// | ||||
/// This function replaces the exit basic block with a new basic block. I | ||||
t | ||||
/// also updates all child regions that have the same exit basic block as | ||||
/// this region. | ||||
/// | ||||
/// @param NewExit The new exit basic block. | ||||
void replaceExitRecursive(BasicBlock *NewExit); | ||||
/// @brief Get the exit BasicBlock of the Region. | /// @brief Get the exit BasicBlock of the Region. | |||
/// @return The exit BasicBlock of the Region, NULL if this is the TopLev el | /// @return The exit BasicBlock of the Region, NULL if this is the TopLev el | |||
/// Region. | /// Region. | |||
BasicBlock *getExit() const { return exit; } | BasicBlock *getExit() const { return exit; } | |||
/// @brief Get the parent of the Region. | /// @brief Get the parent of the Region. | |||
/// @return The parent of the Region or NULL if this is a top level | /// @return The parent of the Region or NULL if this is a top level | |||
/// Region. | /// Region. | |||
Region *getParent() const { return RegionNode::getParent(); } | Region *getParent() const { return RegionNode::getParent(); } | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 23 lines changed or added | |||
RegionIterator.h | RegionIterator.h | |||
---|---|---|---|---|
//===- RegionIterator.h - Iterators to iteratate over Regions ---*- C++ -*- ===// | //===- RegionIterator.h - Iterators to iteratate over Regions ---*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// This file defines the iterators to iterate over the elements of a Region . | // This file defines the iterators to iterate over the elements of a Region . | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_REGION_ITERATOR_H | #ifndef LLVM_ANALYSIS_REGIONITERATOR_H | |||
#define LLVM_ANALYSIS_REGION_ITERATOR_H | #define LLVM_ANALYSIS_REGIONITERATOR_H | |||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | ||||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | ||||
#include "llvm/Analysis/RegionInfo.h" | #include "llvm/Analysis/RegionInfo.h" | |||
#include "llvm/Support/CFG.h" | #include "llvm/Support/CFG.h" | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// @brief Hierarchical RegionNode successor iterator. | /// @brief Hierarchical RegionNode successor iterator. | |||
/// | /// | |||
/// This iterator iterates over all successors of a RegionNode. | /// This iterator iterates over all successors of a RegionNode. | |||
/// | /// | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
RegionPass.h | RegionPass.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the RegionPass class. All region based analysis, | // This file defines the RegionPass class. All region based analysis, | |||
// optimization and transformation passes are derived from RegionPass. | // optimization and transformation passes are derived from RegionPass. | |||
// This class is implemented following the some ideas of the LoopPass.h cla ss. | // This class is implemented following the some ideas of the LoopPass.h cla ss. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_REGION_PASS_H | #ifndef LLVM_ANALYSIS_REGIONPASS_H | |||
#define LLVM_REGION_PASS_H | #define LLVM_ANALYSIS_REGIONPASS_H | |||
#include "llvm/Analysis/RegionInfo.h" | #include "llvm/Analysis/RegionInfo.h" | |||
#include "llvm/IR/Function.h" | ||||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
#include "llvm/PassManagers.h" | #include "llvm/PassManagers.h" | |||
#include "llvm/Function.h" | ||||
#include <deque> | #include <deque> | |||
namespace llvm { | namespace llvm { | |||
class RGPassManager; | class RGPassManager; | |||
class Function; | class Function; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// @brief A pass that runs on each Region in a function. | /// @brief A pass that runs on each Region in a function. | |||
/// | /// | |||
skipping to change at line 62 | skipping to change at line 60 | |||
virtual bool runOnRegion(Region *R, RGPassManager &RGM) = 0; | virtual bool runOnRegion(Region *R, RGPassManager &RGM) = 0; | |||
/// @brief Get a pass to print the LLVM IR in the region. | /// @brief Get a pass to print the LLVM IR in the region. | |||
/// | /// | |||
/// @param O The ouput stream to print the Region. | /// @param O The ouput stream to print the Region. | |||
/// @param Banner The banner to separate different printed passes. | /// @param Banner The banner to separate different printed passes. | |||
/// | /// | |||
/// @return The pass to print the LLVM IR in the region. | /// @return The pass to print the LLVM IR in the region. | |||
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; | Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; | |||
using llvm::Pass::doInitialization; | ||||
using llvm::Pass::doFinalization; | ||||
virtual bool doInitialization(Region *R, RGPassManager &RGM) { return fal se; } | virtual bool doInitialization(Region *R, RGPassManager &RGM) { return fal se; } | |||
virtual bool doFinalization() { return false; } | virtual bool doFinalization() { return false; } | |||
//@} | //@} | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// @name PassManager API | /// @name PassManager API | |||
/// | /// | |||
//@{ | //@{ | |||
void preparePassManager(PMStack &PMS); | void preparePassManager(PMStack &PMS); | |||
End of changes. 4 change blocks. | ||||
5 lines changed or deleted | 6 lines changed or added | |||
RegisterClassInfo.h | RegisterClassInfo.h | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
#include "llvm/ADT/OwningPtr.h" | #include "llvm/ADT/OwningPtr.h" | |||
#include "llvm/Target/TargetRegisterInfo.h" | #include "llvm/Target/TargetRegisterInfo.h" | |||
namespace llvm { | namespace llvm { | |||
class RegisterClassInfo { | class RegisterClassInfo { | |||
struct RCInfo { | struct RCInfo { | |||
unsigned Tag; | unsigned Tag; | |||
unsigned NumRegs; | unsigned NumRegs; | |||
bool ProperSubClass; | bool ProperSubClass; | |||
OwningArrayPtr<unsigned> Order; | uint8_t MinCost; | |||
uint16_t LastCostChange; | ||||
OwningArrayPtr<MCPhysReg> Order; | ||||
RCInfo() | ||||
: Tag(0), NumRegs(0), ProperSubClass(false), MinCost(0), | ||||
LastCostChange(0) {} | ||||
RCInfo() : Tag(0), NumRegs(0), ProperSubClass(false) {} | operator ArrayRef<MCPhysReg>() const { | |||
operator ArrayRef<unsigned>() const { | ||||
return makeArrayRef(Order.get(), NumRegs); | return makeArrayRef(Order.get(), NumRegs); | |||
} | } | |||
}; | }; | |||
// Brief cached information for each register class. | // Brief cached information for each register class. | |||
OwningArrayPtr<RCInfo> RegClass; | OwningArrayPtr<RCInfo> RegClass; | |||
// Tag changes whenever cached information needs to be recomputed. An RCI nfo | // Tag changes whenever cached information needs to be recomputed. An RCI nfo | |||
// entry is valid when its tag matches. | // entry is valid when its tag matches. | |||
unsigned Tag; | unsigned Tag; | |||
skipping to change at line 87 | skipping to change at line 92 | |||
/// getNumAllocatableRegs - Returns the number of actually allocatable | /// getNumAllocatableRegs - Returns the number of actually allocatable | |||
/// registers in RC in the current function. | /// registers in RC in the current function. | |||
unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const { | unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const { | |||
return get(RC).NumRegs; | return get(RC).NumRegs; | |||
} | } | |||
/// getOrder - Returns the preferred allocation order for RC. The order | /// getOrder - Returns the preferred allocation order for RC. The order | |||
/// contains no reserved registers, and registers that alias callee saved | /// contains no reserved registers, and registers that alias callee saved | |||
/// registers come last. | /// registers come last. | |||
ArrayRef<unsigned> getOrder(const TargetRegisterClass *RC) const { | ArrayRef<MCPhysReg> getOrder(const TargetRegisterClass *RC) const { | |||
return get(RC); | return get(RC); | |||
} | } | |||
/// isProperSubClass - Returns true if RC has a legal super-class with mo re | /// isProperSubClass - Returns true if RC has a legal super-class with mo re | |||
/// allocatable registers. | /// allocatable registers. | |||
/// | /// | |||
/// Register classes like GR32_NOSP are not proper sub-classes because %e sp | /// Register classes like GR32_NOSP are not proper sub-classes because %e sp | |||
/// is not allocatable. Similarly, tGPR is not a proper sub-class in Thu mb | /// is not allocatable. Similarly, tGPR is not a proper sub-class in Thu mb | |||
/// mode because the GPR super-class is not legal. | /// mode because the GPR super-class is not legal. | |||
bool isProperSubClass(const TargetRegisterClass *RC) const { | bool isProperSubClass(const TargetRegisterClass *RC) const { | |||
skipping to change at line 109 | skipping to change at line 114 | |||
} | } | |||
/// getLastCalleeSavedAlias - Returns the last callee saved register that | /// getLastCalleeSavedAlias - Returns the last callee saved register that | |||
/// overlaps PhysReg, or 0 if Reg doesn't overlap a CSR. | /// overlaps PhysReg, or 0 if Reg doesn't overlap a CSR. | |||
unsigned getLastCalleeSavedAlias(unsigned PhysReg) const { | unsigned getLastCalleeSavedAlias(unsigned PhysReg) const { | |||
assert(TargetRegisterInfo::isPhysicalRegister(PhysReg)); | assert(TargetRegisterInfo::isPhysicalRegister(PhysReg)); | |||
if (unsigned N = CSRNum[PhysReg]) | if (unsigned N = CSRNum[PhysReg]) | |||
return CalleeSaved[N-1]; | return CalleeSaved[N-1]; | |||
return 0; | return 0; | |||
} | } | |||
/// Get the minimum register cost in RC's allocation order. | ||||
/// This is the smallest value returned by TRI->getCostPerUse(Reg) for al | ||||
l | ||||
/// the registers in getOrder(RC). | ||||
unsigned getMinCost(const TargetRegisterClass *RC) { | ||||
return get(RC).MinCost; | ||||
} | ||||
/// Get the position of the last cost change in getOrder(RC). | ||||
/// | ||||
/// All registers in getOrder(RC).slice(getLastCostChange(RC)) will have | ||||
the | ||||
/// same cost according to TRI->getCostPerUse(). | ||||
unsigned getLastCostChange(const TargetRegisterClass *RC) { | ||||
return get(RC).LastCostChange; | ||||
} | ||||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
4 lines changed or deleted | 26 lines changed or added | |||
RegisterPressure.h | RegisterPressure.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the RegisterPressure class which can be used to track | // This file defines the RegisterPressure class which can be used to track | |||
// MachineInstr level register pressure. | // MachineInstr level register pressure. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_REGISTERPRESSURE_H | #ifndef LLVM_CODEGEN_REGISTERPRESSURE_H | |||
#define LLVM_CODEGEN_REGISTERPRESSURE_H | #define LLVM_CODEGEN_REGISTERPRESSURE_H | |||
#include "llvm/ADT/SparseSet.h" | ||||
#include "llvm/CodeGen/SlotIndexes.h" | #include "llvm/CodeGen/SlotIndexes.h" | |||
#include "llvm/Target/TargetRegisterInfo.h" | #include "llvm/Target/TargetRegisterInfo.h" | |||
#include "llvm/ADT/SparseSet.h" | ||||
namespace llvm { | namespace llvm { | |||
class LiveIntervals; | class LiveIntervals; | |||
class LiveInterval; | ||||
class RegisterClassInfo; | class RegisterClassInfo; | |||
class MachineInstr; | class MachineInstr; | |||
/// Base class for register pressure results. | /// Base class for register pressure results. | |||
struct RegisterPressure { | struct RegisterPressure { | |||
/// Map of max reg pressure indexed by pressure set ID, not class ID. | /// Map of max reg pressure indexed by pressure set ID, not class ID. | |||
std::vector<unsigned> MaxSetPressure; | std::vector<unsigned> MaxSetPressure; | |||
/// List of live in registers. | /// List of live in virtual registers or physical register units. | |||
SmallVector<unsigned,8> LiveInRegs; | SmallVector<unsigned,8> LiveInRegs; | |||
SmallVector<unsigned,8> LiveOutRegs; | SmallVector<unsigned,8> LiveOutRegs; | |||
/// Increase register pressure for each pressure set impacted by this reg ister | /// Increase register pressure for each pressure set impacted by this reg ister | |||
/// class. Normally called by RegPressureTracker, but may be called manua lly | /// class. Normally called by RegPressureTracker, but may be called manua lly | |||
/// to account for live through (global liveness). | /// to account for live through (global liveness). | |||
void increase(const TargetRegisterClass *RC, const TargetRegisterInfo *TR | /// | |||
I); | /// \param Reg is either a virtual register number or register unit numbe | |||
r. | ||||
void increase(unsigned Reg, const TargetRegisterInfo *TRI, | ||||
const MachineRegisterInfo *MRI); | ||||
/// Decrease register pressure for each pressure set impacted by this reg ister | /// Decrease register pressure for each pressure set impacted by this reg ister | |||
/// class. This is only useful to account for spilling or rematerializati on. | /// class. This is only useful to account for spilling or rematerializati on. | |||
void decrease(const TargetRegisterClass *RC, const TargetRegisterInfo *TR | /// | |||
I); | /// \param Reg is either a virtual register number or register unit numbe | |||
r. | ||||
void decrease(unsigned Reg, const TargetRegisterInfo *TRI, | ||||
const MachineRegisterInfo *MRI); | ||||
void dump(const TargetRegisterInfo *TRI) const; | void dump(const TargetRegisterInfo *TRI) const; | |||
}; | }; | |||
/// RegisterPressure computed within a region of instructions delimited by | /// RegisterPressure computed within a region of instructions delimited by | |||
/// TopIdx and BottomIdx. During pressure computation, the maximum pressur e per | /// TopIdx and BottomIdx. During pressure computation, the maximum pressur e per | |||
/// register pressure set is increased. Once pressure within a region is fu lly | /// register pressure set is increased. Once pressure within a region is fu lly | |||
/// computed, the live-in and live-out sets are recorded. | /// computed, the live-in and live-out sets are recorded. | |||
/// | /// | |||
/// This is preferable to RegionPressure when LiveIntervals are available, | /// This is preferable to RegionPressure when LiveIntervals are available, | |||
skipping to change at line 119 | skipping to change at line 126 | |||
/// CurrentMax records the largest increase in the tracker's max pressure t hat | /// CurrentMax records the largest increase in the tracker's max pressure t hat | |||
/// exceeds the current limit for some pressure set determined by the clien t. | /// exceeds the current limit for some pressure set determined by the clien t. | |||
struct RegPressureDelta { | struct RegPressureDelta { | |||
PressureElement Excess; | PressureElement Excess; | |||
PressureElement CriticalMax; | PressureElement CriticalMax; | |||
PressureElement CurrentMax; | PressureElement CurrentMax; | |||
RegPressureDelta() {} | RegPressureDelta() {} | |||
}; | }; | |||
/// \brief A set of live virtual registers and physical register units. | ||||
/// | ||||
/// Virtual and physical register numbers require separate sparse sets, but | ||||
most | ||||
/// of the RegisterPressureTracker handles them uniformly. | ||||
struct LiveRegSet { | ||||
SparseSet<unsigned> PhysRegs; | ||||
SparseSet<unsigned, VirtReg2IndexFunctor> VirtRegs; | ||||
bool contains(unsigned Reg) { | ||||
if (TargetRegisterInfo::isVirtualRegister(Reg)) | ||||
return VirtRegs.count(Reg); | ||||
return PhysRegs.count(Reg); | ||||
} | ||||
bool insert(unsigned Reg) { | ||||
if (TargetRegisterInfo::isVirtualRegister(Reg)) | ||||
return VirtRegs.insert(Reg).second; | ||||
return PhysRegs.insert(Reg).second; | ||||
} | ||||
bool erase(unsigned Reg) { | ||||
if (TargetRegisterInfo::isVirtualRegister(Reg)) | ||||
return VirtRegs.erase(Reg); | ||||
return PhysRegs.erase(Reg); | ||||
} | ||||
}; | ||||
/// Track the current register pressure at some position in the instruction | /// Track the current register pressure at some position in the instruction | |||
/// stream, and remember the high water mark within the region traversed. T his | /// stream, and remember the high water mark within the region traversed. T his | |||
/// does not automatically consider live-through ranges. The client may | /// does not automatically consider live-through ranges. The client may | |||
/// independently adjust for global liveness. | /// independently adjust for global liveness. | |||
/// | /// | |||
/// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can | /// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can | |||
/// be tracked across a larger region by storing a RegisterPressure result at | /// be tracked across a larger region by storing a RegisterPressure result at | |||
/// each block boundary and explicitly adjusting pressure to account for bl ock | /// each block boundary and explicitly adjusting pressure to account for bl ock | |||
/// live-in and live-out register sets. | /// live-in and live-out register sets. | |||
/// | /// | |||
skipping to change at line 153 | skipping to change at line 187 | |||
const MachineBasicBlock *MBB; | const MachineBasicBlock *MBB; | |||
/// Track the max pressure within the region traversed so far. | /// Track the max pressure within the region traversed so far. | |||
RegisterPressure &P; | RegisterPressure &P; | |||
/// Run in two modes dependending on whether constructed with IntervalPre ssure | /// Run in two modes dependending on whether constructed with IntervalPre ssure | |||
/// or RegisterPressure. If requireIntervals is false, LIS are ignored. | /// or RegisterPressure. If requireIntervals is false, LIS are ignored. | |||
bool RequireIntervals; | bool RequireIntervals; | |||
/// Register pressure corresponds to liveness before this instruction | /// Register pressure corresponds to liveness before this instruction | |||
/// iterator. It may point to the end of the block rather than an instruc | /// iterator. It may point to the end of the block or a DebugValue rather | |||
tion. | than | |||
/// an instruction. | ||||
MachineBasicBlock::const_iterator CurrPos; | MachineBasicBlock::const_iterator CurrPos; | |||
/// Pressure map indexed by pressure set ID, not class ID. | /// Pressure map indexed by pressure set ID, not class ID. | |||
std::vector<unsigned> CurrSetPressure; | std::vector<unsigned> CurrSetPressure; | |||
/// List of live registers. | /// Set of live registers. | |||
SparseSet<unsigned> LivePhysRegs; | LiveRegSet LiveRegs; | |||
SparseSet<unsigned, VirtReg2IndexFunctor> LiveVirtRegs; | ||||
public: | public: | |||
RegPressureTracker(IntervalPressure &rp) : | 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) {} | |||
RegPressureTracker(RegionPressure &rp) : | 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) { } | |||
void init(const MachineFunction *mf, const RegisterClassInfo *rci, | void init(const MachineFunction *mf, const RegisterClassInfo *rci, | |||
const LiveIntervals *lis, const MachineBasicBlock *mbb, | const LiveIntervals *lis, const MachineBasicBlock *mbb, | |||
MachineBasicBlock::const_iterator pos); | MachineBasicBlock::const_iterator pos); | |||
/// Force liveness of registers. Particularly useful to initialize the | /// Force liveness of virtual registers or physical register | |||
/// livein/out state of the tracker before the first call to advance/rece | /// units. Particularly useful to initialize the livein/out state of the | |||
de. | /// tracker before the first call to advance/recede. | |||
void addLiveRegs(ArrayRef<unsigned> Regs); | void addLiveRegs(ArrayRef<unsigned> Regs); | |||
/// Get the MI position corresponding to this register pressure. | /// Get the MI position corresponding to this register pressure. | |||
MachineBasicBlock::const_iterator getPos() const { return CurrPos; } | MachineBasicBlock::const_iterator getPos() const { return CurrPos; } | |||
// Reset the MI position corresponding to the register pressure. This all ows | // Reset the MI position corresponding to the register pressure. This all ows | |||
// schedulers to move instructions above the RegPressureTracker's | // schedulers to move instructions above the RegPressureTracker's | |||
// CurrPos. Since the pressure is computed before CurrPos, the iterator | // CurrPos. Since the pressure is computed before CurrPos, the iterator | |||
// position changes while pressure does not. | // position changes while pressure does not. | |||
void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; } | void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; } | |||
/// \brief Get the SlotIndex for the first nondebug instruction including | ||||
or | ||||
/// after the current position. | ||||
SlotIndex getCurrSlot() const; | ||||
/// Recede across the previous instruction. | /// Recede across the previous instruction. | |||
bool recede(); | bool recede(); | |||
/// Advance across the current instruction. | /// Advance across the current instruction. | |||
bool advance(); | bool advance(); | |||
/// Finalize the region boundaries and recored live ins and live outs. | /// Finalize the region boundaries and recored live ins and live outs. | |||
void closeRegion(); | void closeRegion(); | |||
/// Get the resulting register pressure over the traversed region. | /// Get the resulting register pressure over the traversed region. | |||
/// This result is complete if either advance() or recede() has returned true, | /// This result is complete if either advance() or recede() has returned true, | |||
/// or if closeRegion() was explicitly invoked. | /// or if closeRegion() was explicitly invoked. | |||
RegisterPressure &getPressure() { return P; } | RegisterPressure &getPressure() { return P; } | |||
const RegisterPressure &getPressure() const { return P; } | const RegisterPressure &getPressure() const { return P; } | |||
/// Get the register set pressure at the current position, which may be l ess | /// Get the register set pressure at the current position, which may be l ess | |||
/// than the pressure across the traversed region. | /// than the pressure across the traversed region. | |||
std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; } | std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; } | |||
void discoverPhysLiveIn(unsigned Reg); | void discoverLiveOut(unsigned Reg); | |||
void discoverPhysLiveOut(unsigned Reg); | void discoverLiveIn(unsigned Reg); | |||
void discoverVirtLiveIn(unsigned Reg); | ||||
void discoverVirtLiveOut(unsigned Reg); | ||||
bool isTopClosed() const; | bool isTopClosed() const; | |||
bool isBottomClosed() const; | bool isBottomClosed() const; | |||
void closeTop(); | void closeTop(); | |||
void closeBottom(); | void closeBottom(); | |||
/// Consider the pressure increase caused by traversing this instruction | /// Consider the pressure increase caused by traversing this instruction | |||
/// bottom-up. Find the pressure set with the most change beyond its pres sure | /// bottom-up. Find the pressure set with the most change beyond its pres sure | |||
/// limit based on the tracker's current pressure, and record the number of | /// limit based on the tracker's current pressure, and record the number of | |||
skipping to change at line 271 | skipping to change at line 307 | |||
void getPressureAfterInst(const MachineInstr *MI, | void getPressureAfterInst(const MachineInstr *MI, | |||
std::vector<unsigned> &PressureResult, | std::vector<unsigned> &PressureResult, | |||
std::vector<unsigned> &MaxPressureResult) { | std::vector<unsigned> &MaxPressureResult) { | |||
if (isTopClosed()) | if (isTopClosed()) | |||
return getUpwardPressure(MI, PressureResult, MaxPressureResult); | return getUpwardPressure(MI, PressureResult, MaxPressureResult); | |||
assert(isBottomClosed() && "Uninitialized pressure tracker"); | assert(isBottomClosed() && "Uninitialized pressure tracker"); | |||
return getDownwardPressure(MI, PressureResult, MaxPressureResult); | return getDownwardPressure(MI, PressureResult, MaxPressureResult); | |||
} | } | |||
void dump() const; | ||||
protected: | protected: | |||
void increasePhysRegPressure(ArrayRef<unsigned> Regs); | const LiveInterval *getInterval(unsigned Reg) const; | |||
void decreasePhysRegPressure(ArrayRef<unsigned> Regs); | ||||
void increaseVirtRegPressure(ArrayRef<unsigned> Regs); | void increaseRegPressure(ArrayRef<unsigned> Regs); | |||
void decreaseVirtRegPressure(ArrayRef<unsigned> Regs); | void decreaseRegPressure(ArrayRef<unsigned> Regs); | |||
void bumpUpwardPressure(const MachineInstr *MI); | void bumpUpwardPressure(const MachineInstr *MI); | |||
void bumpDownwardPressure(const MachineInstr *MI); | void bumpDownwardPressure(const MachineInstr *MI); | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 15 change blocks. | ||||
23 lines changed or deleted | 61 lines changed or added | |||
RegisterScavenging.h | RegisterScavenging.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the machine register scavenger class. It can provide | // This file declares the machine register scavenger class. It can provide | |||
// information such as unused register at any point in a machine basic bloc k. | // information such as unused register at any point in a machine basic bloc k. | |||
// It also provides a mechanism to make registers availbale by evicting the m | // It also provides a mechanism to make registers availbale by evicting the m | |||
// to spill slots. | // to spill slots. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H | #ifndef LLVM_CODEGEN_REGISTERSCAVENGING_H | |||
#define LLVM_CODEGEN_REGISTER_SCAVENGING_H | #define LLVM_CODEGEN_REGISTERSCAVENGING_H | |||
#include "llvm/ADT/BitVector.h" | ||||
#include "llvm/CodeGen/MachineBasicBlock.h" | #include "llvm/CodeGen/MachineBasicBlock.h" | |||
#include "llvm/CodeGen/MachineRegisterInfo.h" | #include "llvm/CodeGen/MachineRegisterInfo.h" | |||
#include "llvm/ADT/BitVector.h" | ||||
namespace llvm { | namespace llvm { | |||
class MachineRegisterInfo; | class MachineRegisterInfo; | |||
class TargetRegisterInfo; | class TargetRegisterInfo; | |||
class TargetInstrInfo; | class TargetInstrInfo; | |||
class TargetRegisterClass; | class TargetRegisterClass; | |||
class RegScavenger { | class RegScavenger { | |||
const TargetRegisterInfo *TRI; | const TargetRegisterInfo *TRI; | |||
const TargetInstrInfo *TII; | const TargetInstrInfo *TII; | |||
MachineRegisterInfo* MRI; | MachineRegisterInfo* MRI; | |||
MachineBasicBlock *MBB; | MachineBasicBlock *MBB; | |||
MachineBasicBlock::iterator MBBI; | MachineBasicBlock::iterator MBBI; | |||
unsigned NumPhysRegs; | unsigned NumPhysRegs; | |||
/// Tracking - True if RegScavenger is currently tracking the liveness of | /// Tracking - True if RegScavenger is currently tracking the liveness of | |||
/// registers. | /// registers. | |||
bool Tracking; | bool Tracking; | |||
/// ScavengingFrameIndex - Special spill slot used for scavenging a regis | /// Information on scavenged registers (held in a spill slot). | |||
ter | struct ScavengedInfo { | |||
/// post register allocation. | ScavengedInfo(int FI = -1) : FrameIndex(FI), Reg(0), Restore(NULL) {} | |||
int ScavengingFrameIndex; | ||||
/// A spill slot used for scavenging a register post register allocatio | ||||
/// ScavengedReg - If none zero, the specific register is currently being | n. | |||
/// scavenged. That is, it is spilled to the special scavenging stack slo | int FrameIndex; | |||
t. | ||||
unsigned ScavengedReg; | /// If non-zero, the specific register is currently being | |||
/// scavenged. That is, it is spilled to this scavenging stack slot. | ||||
unsigned Reg; | ||||
/// The instruction that restores the scavenged register from stack. | ||||
const MachineInstr *Restore; | ||||
}; | ||||
/// ScavengedRC - Register class of the scavenged register. | /// A vector of information on scavenged registers. | |||
/// | SmallVector<ScavengedInfo, 2> Scavenged; | |||
const TargetRegisterClass *ScavengedRC; | ||||
/// ScavengeRestore - Instruction that restores the scavenged register fr | ||||
om | ||||
/// stack. | ||||
const MachineInstr *ScavengeRestore; | ||||
/// CalleeSavedrRegs - A bitvector of callee saved registers for the targ et. | /// CalleeSavedrRegs - A bitvector of callee saved registers for the targ et. | |||
/// | /// | |||
BitVector CalleeSavedRegs; | BitVector CalleeSavedRegs; | |||
/// RegsAvailable - The current state of all the physical registers immed iately | /// RegsAvailable - The current state of all the physical registers immed iately | |||
/// before MBBI. One bit per physical register. If bit is set that means it's | /// before MBBI. One bit per physical register. If bit is set that means it's | |||
/// available, unset means the register is currently being used. | /// available, unset means the register is currently being used. | |||
BitVector RegsAvailable; | BitVector RegsAvailable; | |||
// These BitVectors are only used internally to forward(). They are membe rs | // These BitVectors are only used internally to forward(). They are membe rs | |||
// to avoid frequent reallocations. | // to avoid frequent reallocations. | |||
BitVector KillRegs, DefRegs; | BitVector KillRegs, DefRegs; | |||
public: | public: | |||
RegScavenger() | RegScavenger() | |||
: MBB(NULL), NumPhysRegs(0), Tracking(false), | : MBB(NULL), NumPhysRegs(0), Tracking(false) {} | |||
ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {} | ||||
/// enterBasicBlock - Start tracking liveness from the begin of the speci fic | /// enterBasicBlock - Start tracking liveness from the begin of the speci fic | |||
/// basic block. | /// basic block. | |||
void enterBasicBlock(MachineBasicBlock *mbb); | void enterBasicBlock(MachineBasicBlock *mbb); | |||
/// initRegState - allow resetting register state info for multiple | /// initRegState - allow resetting register state info for multiple | |||
/// passes over/within the same function. | /// passes over/within the same function. | |||
void initRegState(); | void initRegState(); | |||
/// forward - Move the internal MBB iterator and update register states. | /// forward - Move the internal MBB iterator and update register states. | |||
void forward(); | void forward(); | |||
/// forward - Move the internal MBB iterator and update register states u ntil | /// forward - Move the internal MBB iterator and update register states u ntil | |||
/// it has processed the specific iterator. | /// it has processed the specific iterator. | |||
void forward(MachineBasicBlock::iterator I) { | void forward(MachineBasicBlock::iterator I) { | |||
if (!Tracking && MBB->begin() != I) forward(); | if (!Tracking && MBB->begin() != I) forward(); | |||
while (MBBI != I) forward(); | while (MBBI != I) forward(); | |||
} | } | |||
/// Invert the behavior of forward() on the current instruction (undo the | ||||
/// changes to the available registers made by forward()). | ||||
void unprocess(); | ||||
/// Unprocess instructions until you reach the provided iterator. | ||||
void unprocess(MachineBasicBlock::iterator I) { | ||||
while (MBBI != I) unprocess(); | ||||
} | ||||
/// skipTo - Move the internal MBB iterator but do not update register st ates. | /// skipTo - Move the internal MBB iterator but do not update register st ates. | |||
/// | void skipTo(MachineBasicBlock::iterator I) { | |||
void skipTo(MachineBasicBlock::iterator I) { MBBI = I; } | if (I == MachineBasicBlock::iterator(NULL)) | |||
Tracking = false; | ||||
MBBI = I; | ||||
} | ||||
MachineBasicBlock::iterator getCurrentPosition() const { | ||||
return MBBI; | ||||
} | ||||
/// getRegsUsed - return all registers currently in use in used. | /// getRegsUsed - return all registers currently in use in used. | |||
void getRegsUsed(BitVector &used, bool includeReserved); | void getRegsUsed(BitVector &used, bool includeReserved); | |||
/// getRegsAvailable - Return all available registers in the register cla ss | /// getRegsAvailable - Return all available registers in the register cla ss | |||
/// in Mask. | /// in Mask. | |||
BitVector getRegsAvailable(const TargetRegisterClass *RC); | BitVector getRegsAvailable(const TargetRegisterClass *RC); | |||
/// FindUnusedReg - Find a unused register of the specified register clas s. | /// FindUnusedReg - Find a unused register of the specified register clas s. | |||
/// Return 0 if none is found. | /// Return 0 if none is found. | |||
unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const; | unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const; | |||
/// setScavengingFrameIndex / getScavengingFrameIndex - accessor and sett | /// Add a scavenging frame index. | |||
er of | void addScavengingFrameIndex(int FI) { | |||
/// ScavengingFrameIndex. | Scavenged.push_back(ScavengedInfo(FI)); | |||
void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; } | } | |||
int getScavengingFrameIndex() const { return ScavengingFrameIndex; } | ||||
/// Query whether a frame index is a scavenging frame index. | ||||
bool isScavengingFrameIndex(int FI) const { | ||||
for (SmallVector<ScavengedInfo, 2>::const_iterator I = Scavenged.begin( | ||||
), | ||||
IE = Scavenged.end(); I != IE; ++I) | ||||
if (I->FrameIndex == FI) | ||||
return true; | ||||
return false; | ||||
} | ||||
/// Get an array of scavenging frame indices. | ||||
void getScavengingFrameIndices(SmallVectorImpl<int> &A) const { | ||||
for (SmallVector<ScavengedInfo, 2>::const_iterator I = Scavenged.begin( | ||||
), | ||||
IE = Scavenged.end(); I != IE; ++I) | ||||
if (I->FrameIndex >= 0) | ||||
A.push_back(I->FrameIndex); | ||||
} | ||||
/// scavengeRegister - Make a register of the specific register class | /// scavengeRegister - Make a register of the specific register class | |||
/// available and do the appropriate bookkeeping. SPAdj is the stack | /// available and do the appropriate bookkeeping. SPAdj is the stack | |||
/// adjustment due to call frame, it's passed along to eliminateFrameInde x(). | /// adjustment due to call frame, it's passed along to eliminateFrameInde x(). | |||
/// Returns the scavenged register. | /// Returns the scavenged register. | |||
unsigned scavengeRegister(const TargetRegisterClass *RegClass, | unsigned scavengeRegister(const TargetRegisterClass *RegClass, | |||
MachineBasicBlock::iterator I, int SPAdj); | MachineBasicBlock::iterator I, int SPAdj); | |||
unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) { | unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) { | |||
return scavengeRegister(RegClass, MBBI, SPAdj); | return scavengeRegister(RegClass, MBBI, SPAdj); | |||
} | } | |||
/// setUsed - Tell the scavenger a register is used. | /// setUsed - Tell the scavenger a register is used. | |||
/// | /// | |||
void setUsed(unsigned Reg); | void setUsed(unsigned Reg); | |||
private: | private: | |||
/// isReserved - Returns true if a register is reserved. It is never "unu sed". | /// isReserved - Returns true if a register is reserved. It is never "unu sed". | |||
bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); } | bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); } | |||
/// isUsed / isUnused - Test if a register is currently being used. | /// isUsed - Test if a register is currently being used. When called by | |||
the | ||||
/// isAliasUsed function, we only check isReserved if this is the origina | ||||
l | ||||
/// register, not an alias register. | ||||
/// | /// | |||
bool isUsed(unsigned Reg) const { | bool isUsed(unsigned Reg, bool CheckReserved = true) const { | |||
return !RegsAvailable.test(Reg) || isReserved(Reg); | return !RegsAvailable.test(Reg) || (CheckReserved && isReserved(Reg)); | |||
} | } | |||
/// isAliasUsed - Is Reg or an alias currently in use? | /// isAliasUsed - Is Reg or an alias currently in use? | |||
bool isAliasUsed(unsigned Reg) const; | bool isAliasUsed(unsigned Reg) const; | |||
/// setUsed / setUnused - Mark the state of one or a number of registers. | /// setUsed / setUnused - Mark the state of one or a number of registers. | |||
/// | /// | |||
void setUsed(BitVector &Regs) { | void setUsed(BitVector &Regs) { | |||
RegsAvailable.reset(Regs); | RegsAvailable.reset(Regs); | |||
} | } | |||
void setUnused(BitVector &Regs) { | void setUnused(BitVector &Regs) { | |||
RegsAvailable |= Regs; | RegsAvailable |= Regs; | |||
} | } | |||
/// Processes the current instruction and fill the KillRegs and DefRegs b | ||||
it | ||||
/// vectors. | ||||
void determineKillsAndDefs(); | ||||
/// Add Reg and all its sub-registers to BV. | /// Add Reg and all its sub-registers to BV. | |||
void addRegWithSubRegs(BitVector &BV, unsigned Reg); | void addRegWithSubRegs(BitVector &BV, unsigned Reg); | |||
/// findSurvivorReg - Return the candidate register that is unused for th e | /// findSurvivorReg - Return the candidate register that is unused for th e | |||
/// longest after StartMI. UseMI is set to the instruction where the sear ch | /// longest after StartMI. UseMI is set to the instruction where the sear ch | |||
/// stopped. | /// stopped. | |||
/// | /// | |||
/// No more than InstrLimit instructions are inspected. | /// No more than InstrLimit instructions are inspected. | |||
unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI, | unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI, | |||
BitVector &Candidates, | BitVector &Candidates, | |||
End of changes. 12 change blocks. | ||||
32 lines changed or deleted | 75 lines changed or added | |||
RegistryParser.h | RegistryParser.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// Defines a command-line parser for a registry. | // Defines a command-line parser for a registry. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_REGISTRY_PARSER_H | #ifndef LLVM_SUPPORT_REGISTRYPARSER_H | |||
#define LLVM_SUPPORT_REGISTRY_PARSER_H | #define LLVM_SUPPORT_REGISTRYPARSER_H | |||
#include "llvm/Support/CommandLine.h" | #include "llvm/Support/CommandLine.h" | |||
#include "llvm/Support/Registry.h" | #include "llvm/Support/Registry.h" | |||
namespace llvm { | namespace llvm { | |||
/// A command-line parser for a registry. Use like such: | /// A command-line parser for a registry. Use like such: | |||
/// | /// | |||
/// static cl::opt<Registry<Collector>::entry, false, | /// static cl::opt<Registry<Collector>::entry, false, | |||
/// RegistryParser<Collector> > | /// RegistryParser<Collector> > | |||
skipping to change at line 55 | skipping to change at line 55 | |||
public: | public: | |||
void initialize(cl::Option &O) { | void initialize(cl::Option &O) { | |||
listener::init(); | listener::init(); | |||
cl::parser<const typename U::entry*>::initialize(O); | cl::parser<const typename U::entry*>::initialize(O); | |||
} | } | |||
}; | }; | |||
} | } | |||
#endif // LLVM_SUPPORT_REGISTRY_PARSER_H | #endif // LLVM_SUPPORT_REGISTRYPARSER_H | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
RelocVisitor.h | RelocVisitor.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file provides a wrapper around all the different types of relocatio ns | // This file provides a wrapper around all the different types of relocatio ns | |||
// in different file formats, such that a client can handle them in a unifi ed | // in different file formats, such that a client can handle them in a unifi ed | |||
// manner by only implementing a minimal number of functions. | // manner by only implementing a minimal number of functions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef _LLVM_OBJECT_RELOCVISITOR | #ifndef LLVM_OBJECT_RELOCVISITOR_H | |||
#define _LLVM_OBJECT_RELOCVISITOR | #define LLVM_OBJECT_RELOCVISITOR_H | |||
#include "llvm/ADT/StringRef.h" | ||||
#include "llvm/Object/ObjectFile.h" | ||||
#include "llvm/Support/Debug.h" | #include "llvm/Support/Debug.h" | |||
#include "llvm/Support/ELF.h" | ||||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
#include "llvm/Object/ObjectFile.h" | ||||
#include "llvm/Object/ELF.h" | ||||
#include "llvm/ADT/StringRef.h" | ||||
namespace llvm { | namespace llvm { | |||
namespace object { | namespace object { | |||
struct RelocToApply { | struct RelocToApply { | |||
// The computed value after applying the relevant relocations. | // The computed value after applying the relevant relocations. | |||
int64_t Value; | int64_t Value; | |||
// The width of the value; how many bytes to touch when applying the | // The width of the value; how many bytes to touch when applying the | |||
// relocation. | // relocation. | |||
char Width; | char Width; | |||
RelocToApply(const RelocToApply &In) : Value(In.Value), Width(In.Width) { } | RelocToApply(const RelocToApply &In) : Value(In.Value), Width(In.Width) { } | |||
RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {} | RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {} | |||
RelocToApply() : Value(0), Width(0) {} | RelocToApply() : Value(0), Width(0) {} | |||
}; | }; | |||
/// @brief Base class for object file relocation visitors. | /// @brief Base class for object file relocation visitors. | |||
class RelocVisitor { | class RelocVisitor { | |||
public: | public: | |||
explicit RelocVisitor(llvm::StringRef FileFormat) | explicit RelocVisitor(StringRef FileFormat) | |||
: FileFormat(FileFormat), HasError(false) {} | : FileFormat(FileFormat), HasError(false) {} | |||
// TODO: Should handle multiple applied relocations via either passing in the | // TODO: Should handle multiple applied relocations via either passing in the | |||
// previously computed value or just count paired relocations as a single | // previously computed value or just count paired relocations as a single | |||
// visit. | // visit. | |||
RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0, | RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0, | |||
uint64_t Value = 0) { | uint64_t Value = 0) { | |||
if (FileFormat == "ELF64-x86-64") { | if (FileFormat == "ELF64-x86-64") { | |||
switch (RelocType) { | switch (RelocType) { | |||
case llvm::ELF::R_X86_64_NONE: | case llvm::ELF::R_X86_64_NONE: | |||
skipping to change at line 67 | skipping to change at line 67 | |||
case llvm::ELF::R_X86_64_PC32: | case llvm::ELF::R_X86_64_PC32: | |||
return visitELF_X86_64_PC32(R, Value, SecAddr); | return visitELF_X86_64_PC32(R, Value, SecAddr); | |||
case llvm::ELF::R_X86_64_32: | case llvm::ELF::R_X86_64_32: | |||
return visitELF_X86_64_32(R, Value); | return visitELF_X86_64_32(R, Value); | |||
case llvm::ELF::R_X86_64_32S: | case llvm::ELF::R_X86_64_32S: | |||
return visitELF_X86_64_32S(R, Value); | return visitELF_X86_64_32S(R, Value); | |||
default: | default: | |||
HasError = true; | HasError = true; | |||
return RelocToApply(); | return RelocToApply(); | |||
} | } | |||
} else if (FileFormat == "ELF32-i386") { | ||||
switch (RelocType) { | ||||
case llvm::ELF::R_386_NONE: | ||||
return visitELF_386_NONE(R); | ||||
case llvm::ELF::R_386_32: | ||||
return visitELF_386_32(R, Value); | ||||
case llvm::ELF::R_386_PC32: | ||||
return visitELF_386_PC32(R, Value, SecAddr); | ||||
default: | ||||
HasError = true; | ||||
return RelocToApply(); | ||||
} | ||||
} else if (FileFormat == "ELF64-ppc64") { | ||||
switch (RelocType) { | ||||
case llvm::ELF::R_PPC64_ADDR32: | ||||
return visitELF_PPC64_ADDR32(R, Value); | ||||
default: | ||||
HasError = true; | ||||
return RelocToApply(); | ||||
} | ||||
} else if (FileFormat == "ELF32-mips") { | ||||
switch (RelocType) { | ||||
case llvm::ELF::R_MIPS_32: | ||||
return visitELF_MIPS_32(R, Value); | ||||
default: | ||||
HasError = true; | ||||
return RelocToApply(); | ||||
} | ||||
} else if (FileFormat == "ELF64-aarch64") { | ||||
switch (RelocType) { | ||||
case llvm::ELF::R_AARCH64_ABS32: | ||||
return visitELF_AARCH64_ABS32(R, Value); | ||||
case llvm::ELF::R_AARCH64_ABS64: | ||||
return visitELF_AARCH64_ABS64(R, Value); | ||||
default: | ||||
HasError = true; | ||||
return RelocToApply(); | ||||
} | ||||
} else if (FileFormat == "ELF64-s390") { | ||||
switch (RelocType) { | ||||
case llvm::ELF::R_390_32: | ||||
return visitELF_390_32(R, Value); | ||||
case llvm::ELF::R_390_64: | ||||
return visitELF_390_64(R, Value); | ||||
default: | ||||
HasError = true; | ||||
return RelocToApply(); | ||||
} | ||||
} | } | |||
HasError = true; | ||||
return RelocToApply(); | return RelocToApply(); | |||
} | } | |||
bool error() { return HasError; } | bool error() { return HasError; } | |||
private: | private: | |||
llvm::StringRef FileFormat; | StringRef FileFormat; | |||
bool HasError; | bool HasError; | |||
/// Operations | /// Operations | |||
// Width is the width in bytes of the extend. | /// 386-ELF | |||
RelocToApply zeroExtend(RelocToApply r, char Width) { | RelocToApply visitELF_386_NONE(RelocationRef R) { | |||
if (Width == r.Width) | return RelocToApply(0, 0); | |||
return r; | } | |||
r.Value &= (1 << ((Width * 8))) - 1; | ||||
return r; | // Ideally the Addend here will be the addend in the data for | |||
} | // the relocation. It's not actually the case for Rel relocations. | |||
RelocToApply signExtend(RelocToApply r, char Width) { | RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) { | |||
if (Width == r.Width) | int64_t Addend; | |||
return r; | R.getAdditionalInfo(Addend); | |||
bool SignBit = r.Value & (1 << ((Width * 8) - 1)); | return RelocToApply(Value + Addend, 4); | |||
if (SignBit) { | } | |||
r.Value |= ~((1 << (Width * 8)) - 1); | ||||
} else { | RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value, | |||
r.Value &= (1 << (Width * 8)) - 1; | uint64_t SecAddr) { | |||
} | int64_t Addend; | |||
return r; | R.getAdditionalInfo(Addend); | |||
uint64_t Address; | ||||
R.getOffset(Address); | ||||
return RelocToApply(Value + Addend - Address, 4); | ||||
} | } | |||
/// X86-64 ELF | /// X86-64 ELF | |||
RelocToApply visitELF_X86_64_NONE(RelocationRef R) { | RelocToApply visitELF_X86_64_NONE(RelocationRef R) { | |||
return RelocToApply(0, 0); | return RelocToApply(0, 0); | |||
} | } | |||
RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) { | RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) { | |||
int64_t Addend; | int64_t Addend; | |||
R.getAdditionalInfo(Addend); | R.getAdditionalInfo(Addend); | |||
return RelocToApply(Value + Addend, 8); | return RelocToApply(Value + Addend, 8); | |||
} | } | |||
RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value, | RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value, | |||
uint64_t SecAddr) { | uint64_t SecAddr) { | |||
int64_t Addend; | int64_t Addend; | |||
R.getAdditionalInfo(Addend); | R.getAdditionalInfo(Addend); | |||
uint64_t Address; | uint64_t Address; | |||
R.getAddress(Address); | R.getOffset(Address); | |||
return RelocToApply(Value + Addend - Address, 4); | return RelocToApply(Value + Addend - Address, 4); | |||
} | } | |||
RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) { | RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) { | |||
int64_t Addend; | int64_t Addend; | |||
R.getAdditionalInfo(Addend); | R.getAdditionalInfo(Addend); | |||
uint32_t Res = (Value + Addend) & 0xFFFFFFFF; | uint32_t Res = (Value + Addend) & 0xFFFFFFFF; | |||
return RelocToApply(Res, 4); | return RelocToApply(Res, 4); | |||
} | } | |||
RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) { | RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) { | |||
int64_t Addend; | int64_t Addend; | |||
R.getAdditionalInfo(Addend); | R.getAdditionalInfo(Addend); | |||
int32_t Res = (Value + Addend) & 0xFFFFFFFF; | int32_t Res = (Value + Addend) & 0xFFFFFFFF; | |||
return RelocToApply(Res, 4); | return RelocToApply(Res, 4); | |||
} | } | |||
/// PPC64 ELF | ||||
RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) { | ||||
int64_t Addend; | ||||
R.getAdditionalInfo(Addend); | ||||
uint32_t Res = (Value + Addend) & 0xFFFFFFFF; | ||||
return RelocToApply(Res, 4); | ||||
} | ||||
/// MIPS ELF | ||||
RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) { | ||||
int64_t Addend; | ||||
R.getAdditionalInfo(Addend); | ||||
uint32_t Res = (Value + Addend) & 0xFFFFFFFF; | ||||
return RelocToApply(Res, 4); | ||||
} | ||||
// AArch64 ELF | ||||
RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) { | ||||
int64_t Addend; | ||||
R.getAdditionalInfo(Addend); | ||||
int64_t Res = Value + Addend; | ||||
// Overflow check allows for both signed and unsigned interpretation. | ||||
if (Res < INT32_MIN || Res > UINT32_MAX) | ||||
HasError = true; | ||||
return RelocToApply(static_cast<uint32_t>(Res), 4); | ||||
} | ||||
RelocToApply visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) { | ||||
int64_t Addend; | ||||
R.getAdditionalInfo(Addend); | ||||
return RelocToApply(Value + Addend, 8); | ||||
} | ||||
// SystemZ ELF | ||||
RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) { | ||||
int64_t Addend; | ||||
R.getAdditionalInfo(Addend); | ||||
int64_t Res = Value + Addend; | ||||
// Overflow check allows for both signed and unsigned interpretation. | ||||
if (Res < INT32_MIN || Res > UINT32_MAX) | ||||
HasError = true; | ||||
return RelocToApply(static_cast<uint32_t>(Res), 4); | ||||
} | ||||
RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) { | ||||
int64_t Addend; | ||||
R.getAdditionalInfo(Addend); | ||||
return RelocToApply(Value + Addend, 8); | ||||
} | ||||
}; | }; | |||
} | } | |||
} | } | |||
#endif | #endif | |||
End of changes. 11 change blocks. | ||||
25 lines changed or deleted | 131 lines changed or added | |||
ResourcePriorityQueue.h | ResourcePriorityQueue.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements the ResourcePriorityQueue class, which is a | // This file implements the ResourcePriorityQueue class, which is a | |||
// SchedulingPriorityQueue that schedules using DFA state to | // SchedulingPriorityQueue that schedules using DFA state to | |||
// reduce the length of the critical path through the basic block | // reduce the length of the critical path through the basic block | |||
// on VLIW platforms. | // on VLIW platforms. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef RESOURCE_PRIORITY_QUEUE_H | #ifndef LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H | |||
#define RESOURCE_PRIORITY_QUEUE_H | #define LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H | |||
#include "llvm/CodeGen/DFAPacketizer.h" | #include "llvm/CodeGen/DFAPacketizer.h" | |||
#include "llvm/CodeGen/SelectionDAGISel.h" | ||||
#include "llvm/CodeGen/ScheduleDAG.h" | #include "llvm/CodeGen/ScheduleDAG.h" | |||
#include "llvm/CodeGen/SelectionDAGISel.h" | ||||
#include "llvm/MC/MCInstrItineraries.h" | #include "llvm/MC/MCInstrItineraries.h" | |||
#include "llvm/Target/TargetInstrInfo.h" | #include "llvm/Target/TargetInstrInfo.h" | |||
#include "llvm/Target/TargetRegisterInfo.h" | #include "llvm/Target/TargetRegisterInfo.h" | |||
namespace llvm { | namespace llvm { | |||
class ResourcePriorityQueue; | class ResourcePriorityQueue; | |||
/// Sorting functions for the Available queue. | /// Sorting functions for the Available queue. | |||
struct resource_sort : public std::binary_function<SUnit*, SUnit*, bool> { | struct resource_sort : public std::binary_function<SUnit*, SUnit*, bool> { | |||
ResourcePriorityQueue *PQ; | ResourcePriorityQueue *PQ; | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
RuntimeDyld.h | RuntimeDyld.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// Interface for the runtime dynamic linker facilities of the MC-JIT. | // Interface for the runtime dynamic linker facilities of the MC-JIT. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_RUNTIME_DYLD_H | #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H | |||
#define LLVM_RUNTIME_DYLD_H | #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/ExecutionEngine/ObjectBuffer.h" | #include "llvm/ExecutionEngine/ObjectBuffer.h" | |||
#include "llvm/Support/Memory.h" | #include "llvm/Support/Memory.h" | |||
namespace llvm { | namespace llvm { | |||
class RuntimeDyldImpl; | class RuntimeDyldImpl; | |||
class ObjectImage; | class ObjectImage; | |||
skipping to change at line 39 | skipping to change at line 39 | |||
// | // | |||
// FIXME: As the RuntimeDyld fills out, additional routines will be needed | // FIXME: As the RuntimeDyld fills out, additional routines will be needed | |||
// for the varying types of objects to be allocated. | // for the varying types of objects to be allocated. | |||
class RTDyldMemoryManager { | class RTDyldMemoryManager { | |||
RTDyldMemoryManager(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION; | RTDyldMemoryManager(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION; | |||
void operator=(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION; | void operator=(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
RTDyldMemoryManager() {} | RTDyldMemoryManager() {} | |||
virtual ~RTDyldMemoryManager(); | virtual ~RTDyldMemoryManager(); | |||
/// allocateCodeSection - Allocate a memory block of (at least) the given | /// Allocate a memory block of (at least) the given size suitable for | |||
/// size suitable for executable code. The SectionID is a unique identifi | /// executable code. The SectionID is a unique identifier assigned by the | |||
er | JIT | |||
/// assigned by the JIT engine, and optionally recorded by the memory man | /// engine, and optionally recorded by the memory manager to access a loa | |||
ager | ded | |||
/// to access a loaded section. | /// section. | |||
virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, | virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, | |||
unsigned SectionID) = 0; | unsigned SectionID) = 0; | |||
/// allocateDataSection - Allocate a memory block of (at least) the given | /// Allocate a memory block of (at least) the given size suitable for dat | |||
/// size suitable for data. The SectionID is a unique identifier | a. | |||
/// assigned by the JIT engine, and optionally recorded by the memory man | /// The SectionID is a unique identifier assigned by the JIT engine, and | |||
ager | /// optionally recorded by the memory manager to access a loaded section. | |||
/// to access a loaded section. | ||||
virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, | virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, | |||
unsigned SectionID) = 0; | unsigned SectionID, bool IsReadOnly) = 0; | |||
/// getPointerToNamedFunction - This method returns the address of the | /// This method returns the address of the specified function. As such it | |||
/// specified function. As such it is only useful for resolving library | is | |||
/// symbols, not code generated symbols. | /// only useful for resolving library symbols, not code generated symbols | |||
. | ||||
/// | /// | |||
/// If AbortOnFailure is false and no function with the given name is | /// If AbortOnFailure is false and no function with the given name is | |||
/// found, this function returns a null pointer. Otherwise, it prints a | /// found, this function returns a null pointer. Otherwise, it prints a | |||
/// message to stderr and aborts. | /// message to stderr and aborts. | |||
virtual void *getPointerToNamedFunction(const std::string &Name, | virtual void *getPointerToNamedFunction(const std::string &Name, | |||
bool AbortOnFailure = true) = 0; | bool AbortOnFailure = true) = 0; | |||
/// This method is called when object loading is complete and section pag | ||||
e | ||||
/// permissions can be applied. It is up to the memory manager implement | ||||
ation | ||||
/// to decide whether or not to act on this method. The memory manager w | ||||
ill | ||||
/// typically allocate all sections as read-write and then apply specific | ||||
/// permissions when this method is called. | ||||
/// | ||||
/// Returns true if an error occurred, false otherwise. | ||||
virtual bool applyPermissions(std::string *ErrMsg = 0) = 0; | ||||
/// Register the EH frames with the runtime so that c++ exceptions work. | ||||
The | ||||
/// default implementation does nothing. Look at SectionMemoryManager for | ||||
one | ||||
/// that uses __register_frame. | ||||
virtual void registerEHFrames(StringRef SectionData); | ||||
}; | }; | |||
class RuntimeDyld { | class RuntimeDyld { | |||
RuntimeDyld(const RuntimeDyld &) LLVM_DELETED_FUNCTION; | RuntimeDyld(const RuntimeDyld &) LLVM_DELETED_FUNCTION; | |||
void operator=(const RuntimeDyld &) LLVM_DELETED_FUNCTION; | void operator=(const RuntimeDyld &) LLVM_DELETED_FUNCTION; | |||
// RuntimeDyldImpl is the actual class. RuntimeDyld is just the public | // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public | |||
// interface. | // interface. | |||
RuntimeDyldImpl *Dyld; | RuntimeDyldImpl *Dyld; | |||
RTDyldMemoryManager *MM; | RTDyldMemoryManager *MM; | |||
protected: | protected: | |||
// Change the address associated with a section when resolving relocation s. | // Change the address associated with a section when resolving relocation s. | |||
// Any relocations already associated with the symbol will be re-resolved . | // Any relocations already associated with the symbol will be re-resolved . | |||
void reassignSectionAddress(unsigned SectionID, uint64_t Addr); | void reassignSectionAddress(unsigned SectionID, uint64_t Addr); | |||
public: | public: | |||
RuntimeDyld(RTDyldMemoryManager *); | RuntimeDyld(RTDyldMemoryManager *); | |||
~RuntimeDyld(); | ~RuntimeDyld(); | |||
/// loadObject - prepare the object contained in the input buffer for | /// Prepare the object contained in the input buffer for execution. | |||
/// execution. Ownership of the input buffer is transferred to the | /// Ownership of the input buffer is transferred to the ObjectImage | |||
/// ObjectImage instance returned from this function if successful. | /// instance returned from this function if successful. In the case of lo | |||
/// In the case of load failure, the input buffer will be deleted. | ad | |||
/// failure, the input buffer will be deleted. | ||||
ObjectImage *loadObject(ObjectBuffer *InputBuffer); | ObjectImage *loadObject(ObjectBuffer *InputBuffer); | |||
/// Get the address of our local copy of the symbol. This may or may not | /// Get the address of our local copy of the symbol. This may or may not | |||
/// be the address used for relocation (clients can copy the data around | /// be the address used for relocation (clients can copy the data around | |||
/// and resolve relocatons based on where they put it). | /// and resolve relocatons based on where they put it). | |||
void *getSymbolAddress(StringRef Name); | void *getSymbolAddress(StringRef Name); | |||
/// Get the address of the target copy of the symbol. This is the address | /// Get the address of the target copy of the symbol. This is the address | |||
/// used for relocation. | /// used for relocation. | |||
uint64_t getSymbolLoadAddress(StringRef Name); | uint64_t getSymbolLoadAddress(StringRef Name); | |||
/// Resolve the relocations for all symbols we currently know about. | /// Resolve the relocations for all symbols we currently know about. | |||
void resolveRelocations(); | void resolveRelocations(); | |||
/// mapSectionAddress - map a section to its target address space value. | /// Map a section to its target address space value. | |||
/// Map the address of a JIT section as returned from the memory manager | /// Map the address of a JIT section as returned from the memory manager | |||
/// to the address in the target process as the running code will see it. | /// to the address in the target process as the running code will see it. | |||
/// This is the address which will be used for relocation resolution. | /// This is the address which will be used for relocation resolution. | |||
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); | void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); | |||
StringRef getErrorString(); | StringRef getErrorString(); | |||
StringRef getEHFrameSection(); | ||||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 9 change blocks. | ||||
22 lines changed or deleted | 44 lines changed or added | |||
RuntimeLibcalls.h | RuntimeLibcalls.h | |||
---|---|---|---|---|
skipping to change at line 89 | skipping to change at line 89 | |||
UDIVREM_I32, | UDIVREM_I32, | |||
UDIVREM_I64, | UDIVREM_I64, | |||
UDIVREM_I128, | UDIVREM_I128, | |||
NEG_I32, | NEG_I32, | |||
NEG_I64, | NEG_I64, | |||
// FLOATING POINT | // FLOATING POINT | |||
ADD_F32, | ADD_F32, | |||
ADD_F64, | ADD_F64, | |||
ADD_F80, | ADD_F80, | |||
ADD_F128, | ||||
ADD_PPCF128, | ADD_PPCF128, | |||
SUB_F32, | SUB_F32, | |||
SUB_F64, | SUB_F64, | |||
SUB_F80, | SUB_F80, | |||
SUB_F128, | ||||
SUB_PPCF128, | SUB_PPCF128, | |||
MUL_F32, | MUL_F32, | |||
MUL_F64, | MUL_F64, | |||
MUL_F80, | MUL_F80, | |||
MUL_F128, | ||||
MUL_PPCF128, | MUL_PPCF128, | |||
DIV_F32, | DIV_F32, | |||
DIV_F64, | DIV_F64, | |||
DIV_F80, | DIV_F80, | |||
DIV_F128, | ||||
DIV_PPCF128, | DIV_PPCF128, | |||
REM_F32, | REM_F32, | |||
REM_F64, | REM_F64, | |||
REM_F80, | REM_F80, | |||
REM_F128, | ||||
REM_PPCF128, | REM_PPCF128, | |||
FMA_F32, | FMA_F32, | |||
FMA_F64, | FMA_F64, | |||
FMA_F80, | FMA_F80, | |||
FMA_F128, | ||||
FMA_PPCF128, | FMA_PPCF128, | |||
POWI_F32, | POWI_F32, | |||
POWI_F64, | POWI_F64, | |||
POWI_F80, | POWI_F80, | |||
POWI_F128, | ||||
POWI_PPCF128, | POWI_PPCF128, | |||
SQRT_F32, | SQRT_F32, | |||
SQRT_F64, | SQRT_F64, | |||
SQRT_F80, | SQRT_F80, | |||
SQRT_F128, | ||||
SQRT_PPCF128, | SQRT_PPCF128, | |||
LOG_F32, | LOG_F32, | |||
LOG_F64, | LOG_F64, | |||
LOG_F80, | LOG_F80, | |||
LOG_F128, | ||||
LOG_PPCF128, | LOG_PPCF128, | |||
LOG2_F32, | LOG2_F32, | |||
LOG2_F64, | LOG2_F64, | |||
LOG2_F80, | LOG2_F80, | |||
LOG2_F128, | ||||
LOG2_PPCF128, | LOG2_PPCF128, | |||
LOG10_F32, | LOG10_F32, | |||
LOG10_F64, | LOG10_F64, | |||
LOG10_F80, | LOG10_F80, | |||
LOG10_F128, | ||||
LOG10_PPCF128, | LOG10_PPCF128, | |||
EXP_F32, | EXP_F32, | |||
EXP_F64, | EXP_F64, | |||
EXP_F80, | EXP_F80, | |||
EXP_F128, | ||||
EXP_PPCF128, | EXP_PPCF128, | |||
EXP2_F32, | EXP2_F32, | |||
EXP2_F64, | EXP2_F64, | |||
EXP2_F80, | EXP2_F80, | |||
EXP2_F128, | ||||
EXP2_PPCF128, | EXP2_PPCF128, | |||
SIN_F32, | SIN_F32, | |||
SIN_F64, | SIN_F64, | |||
SIN_F80, | SIN_F80, | |||
SIN_F128, | ||||
SIN_PPCF128, | SIN_PPCF128, | |||
COS_F32, | COS_F32, | |||
COS_F64, | COS_F64, | |||
COS_F80, | COS_F80, | |||
COS_F128, | ||||
COS_PPCF128, | COS_PPCF128, | |||
SINCOS_F32, | ||||
SINCOS_F64, | ||||
SINCOS_F80, | ||||
SINCOS_F128, | ||||
SINCOS_PPCF128, | ||||
POW_F32, | POW_F32, | |||
POW_F64, | POW_F64, | |||
POW_F80, | POW_F80, | |||
POW_F128, | ||||
POW_PPCF128, | POW_PPCF128, | |||
CEIL_F32, | CEIL_F32, | |||
CEIL_F64, | CEIL_F64, | |||
CEIL_F80, | CEIL_F80, | |||
CEIL_F128, | ||||
CEIL_PPCF128, | CEIL_PPCF128, | |||
TRUNC_F32, | TRUNC_F32, | |||
TRUNC_F64, | TRUNC_F64, | |||
TRUNC_F80, | TRUNC_F80, | |||
TRUNC_F128, | ||||
TRUNC_PPCF128, | TRUNC_PPCF128, | |||
RINT_F32, | RINT_F32, | |||
RINT_F64, | RINT_F64, | |||
RINT_F80, | RINT_F80, | |||
RINT_F128, | ||||
RINT_PPCF128, | RINT_PPCF128, | |||
NEARBYINT_F32, | NEARBYINT_F32, | |||
NEARBYINT_F64, | NEARBYINT_F64, | |||
NEARBYINT_F80, | NEARBYINT_F80, | |||
NEARBYINT_F128, | ||||
NEARBYINT_PPCF128, | NEARBYINT_PPCF128, | |||
FLOOR_F32, | FLOOR_F32, | |||
FLOOR_F64, | FLOOR_F64, | |||
FLOOR_F80, | FLOOR_F80, | |||
FLOOR_F128, | ||||
FLOOR_PPCF128, | FLOOR_PPCF128, | |||
COPYSIGN_F32, | COPYSIGN_F32, | |||
COPYSIGN_F64, | COPYSIGN_F64, | |||
COPYSIGN_F80, | COPYSIGN_F80, | |||
COPYSIGN_F128, | ||||
COPYSIGN_PPCF128, | COPYSIGN_PPCF128, | |||
// CONVERSION | // CONVERSION | |||
FPEXT_F64_F128, | ||||
FPEXT_F32_F128, | ||||
FPEXT_F32_F64, | FPEXT_F32_F64, | |||
FPEXT_F16_F32, | FPEXT_F16_F32, | |||
FPROUND_F32_F16, | FPROUND_F32_F16, | |||
FPROUND_F64_F32, | FPROUND_F64_F32, | |||
FPROUND_F80_F32, | FPROUND_F80_F32, | |||
FPROUND_F128_F32, | ||||
FPROUND_PPCF128_F32, | FPROUND_PPCF128_F32, | |||
FPROUND_F80_F64, | FPROUND_F80_F64, | |||
FPROUND_F128_F64, | ||||
FPROUND_PPCF128_F64, | FPROUND_PPCF128_F64, | |||
FPTOSINT_F32_I8, | FPTOSINT_F32_I8, | |||
FPTOSINT_F32_I16, | FPTOSINT_F32_I16, | |||
FPTOSINT_F32_I32, | FPTOSINT_F32_I32, | |||
FPTOSINT_F32_I64, | FPTOSINT_F32_I64, | |||
FPTOSINT_F32_I128, | FPTOSINT_F32_I128, | |||
FPTOSINT_F64_I8, | FPTOSINT_F64_I8, | |||
FPTOSINT_F64_I16, | FPTOSINT_F64_I16, | |||
FPTOSINT_F64_I32, | FPTOSINT_F64_I32, | |||
FPTOSINT_F64_I64, | FPTOSINT_F64_I64, | |||
FPTOSINT_F64_I128, | FPTOSINT_F64_I128, | |||
FPTOSINT_F80_I32, | FPTOSINT_F80_I32, | |||
FPTOSINT_F80_I64, | FPTOSINT_F80_I64, | |||
FPTOSINT_F80_I128, | FPTOSINT_F80_I128, | |||
FPTOSINT_F128_I32, | ||||
FPTOSINT_F128_I64, | ||||
FPTOSINT_F128_I128, | ||||
FPTOSINT_PPCF128_I32, | FPTOSINT_PPCF128_I32, | |||
FPTOSINT_PPCF128_I64, | FPTOSINT_PPCF128_I64, | |||
FPTOSINT_PPCF128_I128, | FPTOSINT_PPCF128_I128, | |||
FPTOUINT_F32_I8, | FPTOUINT_F32_I8, | |||
FPTOUINT_F32_I16, | FPTOUINT_F32_I16, | |||
FPTOUINT_F32_I32, | FPTOUINT_F32_I32, | |||
FPTOUINT_F32_I64, | FPTOUINT_F32_I64, | |||
FPTOUINT_F32_I128, | FPTOUINT_F32_I128, | |||
FPTOUINT_F64_I8, | FPTOUINT_F64_I8, | |||
FPTOUINT_F64_I16, | FPTOUINT_F64_I16, | |||
FPTOUINT_F64_I32, | FPTOUINT_F64_I32, | |||
FPTOUINT_F64_I64, | FPTOUINT_F64_I64, | |||
FPTOUINT_F64_I128, | FPTOUINT_F64_I128, | |||
FPTOUINT_F80_I32, | FPTOUINT_F80_I32, | |||
FPTOUINT_F80_I64, | FPTOUINT_F80_I64, | |||
FPTOUINT_F80_I128, | FPTOUINT_F80_I128, | |||
FPTOUINT_F128_I32, | ||||
FPTOUINT_F128_I64, | ||||
FPTOUINT_F128_I128, | ||||
FPTOUINT_PPCF128_I32, | FPTOUINT_PPCF128_I32, | |||
FPTOUINT_PPCF128_I64, | FPTOUINT_PPCF128_I64, | |||
FPTOUINT_PPCF128_I128, | FPTOUINT_PPCF128_I128, | |||
SINTTOFP_I32_F32, | SINTTOFP_I32_F32, | |||
SINTTOFP_I32_F64, | SINTTOFP_I32_F64, | |||
SINTTOFP_I32_F80, | SINTTOFP_I32_F80, | |||
SINTTOFP_I32_F128, | ||||
SINTTOFP_I32_PPCF128, | SINTTOFP_I32_PPCF128, | |||
SINTTOFP_I64_F32, | SINTTOFP_I64_F32, | |||
SINTTOFP_I64_F64, | SINTTOFP_I64_F64, | |||
SINTTOFP_I64_F80, | SINTTOFP_I64_F80, | |||
SINTTOFP_I64_F128, | ||||
SINTTOFP_I64_PPCF128, | SINTTOFP_I64_PPCF128, | |||
SINTTOFP_I128_F32, | SINTTOFP_I128_F32, | |||
SINTTOFP_I128_F64, | SINTTOFP_I128_F64, | |||
SINTTOFP_I128_F80, | SINTTOFP_I128_F80, | |||
SINTTOFP_I128_F128, | ||||
SINTTOFP_I128_PPCF128, | SINTTOFP_I128_PPCF128, | |||
UINTTOFP_I32_F32, | UINTTOFP_I32_F32, | |||
UINTTOFP_I32_F64, | UINTTOFP_I32_F64, | |||
UINTTOFP_I32_F80, | UINTTOFP_I32_F80, | |||
UINTTOFP_I32_F128, | ||||
UINTTOFP_I32_PPCF128, | UINTTOFP_I32_PPCF128, | |||
UINTTOFP_I64_F32, | UINTTOFP_I64_F32, | |||
UINTTOFP_I64_F64, | UINTTOFP_I64_F64, | |||
UINTTOFP_I64_F80, | UINTTOFP_I64_F80, | |||
UINTTOFP_I64_F128, | ||||
UINTTOFP_I64_PPCF128, | UINTTOFP_I64_PPCF128, | |||
UINTTOFP_I128_F32, | UINTTOFP_I128_F32, | |||
UINTTOFP_I128_F64, | UINTTOFP_I128_F64, | |||
UINTTOFP_I128_F80, | UINTTOFP_I128_F80, | |||
UINTTOFP_I128_F128, | ||||
UINTTOFP_I128_PPCF128, | UINTTOFP_I128_PPCF128, | |||
// COMPARISON | // COMPARISON | |||
OEQ_F32, | OEQ_F32, | |||
OEQ_F64, | OEQ_F64, | |||
OEQ_F128, | ||||
UNE_F32, | UNE_F32, | |||
UNE_F64, | UNE_F64, | |||
UNE_F128, | ||||
OGE_F32, | OGE_F32, | |||
OGE_F64, | OGE_F64, | |||
OGE_F128, | ||||
OLT_F32, | OLT_F32, | |||
OLT_F64, | OLT_F64, | |||
OLT_F128, | ||||
OLE_F32, | OLE_F32, | |||
OLE_F64, | OLE_F64, | |||
OLE_F128, | ||||
OGT_F32, | OGT_F32, | |||
OGT_F64, | OGT_F64, | |||
OGT_F128, | ||||
UO_F32, | UO_F32, | |||
UO_F64, | UO_F64, | |||
UO_F128, | ||||
O_F32, | O_F32, | |||
O_F64, | O_F64, | |||
O_F128, | ||||
// MEMORY | // MEMORY | |||
MEMCPY, | MEMCPY, | |||
MEMSET, | MEMSET, | |||
MEMMOVE, | MEMMOVE, | |||
// EXCEPTION HANDLING | // EXCEPTION HANDLING | |||
UNWIND_RESUME, | UNWIND_RESUME, | |||
// Family ATOMICs | // Family ATOMICs | |||
End of changes. 42 change blocks. | ||||
0 lines changed or deleted | 51 lines changed or added | |||
SCCIterator.h | SCCIterator.h | |||
---|---|---|---|---|
skipping to change at line 24 | skipping to change at line 24 | |||
// edge to a node in SCC S2, then it visits S1 *after* S2. | // edge to a node in SCC S2, then it visits S1 *after* S2. | |||
// | // | |||
// To visit S1 *before* S2, use the scc_iterator on the Inverse graph. | // To visit S1 *before* S2, use the scc_iterator on the Inverse graph. | |||
// (NOTE: This requires some simple wrappers and is not supported yet.) | // (NOTE: This requires some simple wrappers and is not supported yet.) | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_SCCITERATOR_H | #ifndef LLVM_ADT_SCCITERATOR_H | |||
#define LLVM_ADT_SCCITERATOR_H | #define LLVM_ADT_SCCITERATOR_H | |||
#include "llvm/ADT/GraphTraits.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/GraphTraits.h" | ||||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// | /// | |||
/// scc_iterator - Enumerate the SCCs of a directed graph, in | /// scc_iterator - Enumerate the SCCs of a directed graph, in | |||
/// reverse topological order of the SCC DAG. | /// reverse topological order of the SCC DAG. | |||
/// | /// | |||
template<class GraphT, class GT = GraphTraits<GraphT> > | template<class GraphT, class GT = GraphTraits<GraphT> > | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
SMLoc.h | SMLoc.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the SMLoc class. This class encapsulates a location in | // This file declares the SMLoc class. This class encapsulates a location in | |||
// source code for use in diagnostics. | // source code for use in diagnostics. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef SUPPORT_SMLOC_H | #ifndef LLVM_SUPPORT_SMLOC_H | |||
#define SUPPORT_SMLOC_H | #define LLVM_SUPPORT_SMLOC_H | |||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
/// SMLoc - Represents a location in source code. | /// Represents a location in source code. | |||
class SMLoc { | class SMLoc { | |||
const char *Ptr; | const char *Ptr; | |||
public: | public: | |||
SMLoc() : Ptr(0) {} | SMLoc() : Ptr(0) {} | |||
bool isValid() const { return Ptr != 0; } | bool isValid() const { return Ptr != 0; } | |||
bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; } | bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; } | |||
bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; } | bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; } | |||
const char *getPointer() const { return Ptr; } | const char *getPointer() const { return Ptr; } | |||
static SMLoc getFromPointer(const char *Ptr) { | static SMLoc getFromPointer(const char *Ptr) { | |||
SMLoc L; | SMLoc L; | |||
L.Ptr = Ptr; | L.Ptr = Ptr; | |||
return L; | return L; | |||
} | } | |||
}; | }; | |||
/// SMRange - Represents a range in source code. Note that unlike standard | /// Represents a range in source code. | |||
STL | /// | |||
/// ranges, the locations specified are considered to be *inclusive*. For | /// SMRange is implemented using a half-open range, as is the convention in | |||
/// example, [X,X] *does* include X, it isn't an empty range. | C++. | |||
/// In the string "abc", the range (1,3] represents the substring "bc", and | ||||
the | ||||
/// range (2,2] represents an empty range between the characters "b" and "c | ||||
". | ||||
class SMRange { | class SMRange { | |||
public: | public: | |||
SMLoc Start, End; | SMLoc Start, End; | |||
SMRange() {} | SMRange() {} | |||
SMRange(SMLoc St, SMLoc En) : Start(St), End(En) { | SMRange(SMLoc St, SMLoc En) : Start(St), End(En) { | |||
assert(Start.isValid() == End.isValid() && | assert(Start.isValid() == End.isValid() && | |||
"Start and end should either both be valid or both be invalid!") ; | "Start and end should either both be valid or both be invalid!") ; | |||
} | } | |||
End of changes. 3 change blocks. | ||||
7 lines changed or deleted | 11 lines changed or added | |||
SSAUpdater.h | SSAUpdater.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the SSAUpdater class. | // This file declares the SSAUpdater class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATER_H | #ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATER_H | |||
#define LLVM_TRANSFORMS_UTILS_SSAUPDATER_H | #define LLVM_TRANSFORMS_UTILS_SSAUPDATER_H | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/Compiler.h" | ||||
namespace llvm { | namespace llvm { | |||
class BasicBlock; | class BasicBlock; | |||
class Instruction; | class Instruction; | |||
class LoadInst; | class LoadInst; | |||
template<typename T> class SmallVectorImpl; | template<typename T> class SmallVectorImpl; | |||
template<typename T> class SSAUpdaterTraits; | template<typename T> class SSAUpdaterTraits; | |||
class PHINode; | class PHINode; | |||
class Type; | class Type; | |||
class Use; | class Use; | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 1 lines changed or added | |||
STLExtras.h | STLExtras.h | |||
---|---|---|---|---|
skipping to change at line 245 | skipping to change at line 245 | |||
/// which just uses operator< on T. | /// which just uses operator< on T. | |||
template<typename T> | template<typename T> | |||
inline int array_pod_sort_comparator(const void *P1, const void *P2) { | inline int array_pod_sort_comparator(const void *P1, const void *P2) { | |||
if (*reinterpret_cast<const T*>(P1) < *reinterpret_cast<const T*>(P2)) | if (*reinterpret_cast<const T*>(P1) < *reinterpret_cast<const T*>(P2)) | |||
return -1; | return -1; | |||
if (*reinterpret_cast<const T*>(P2) < *reinterpret_cast<const T*>(P1)) | if (*reinterpret_cast<const T*>(P2) < *reinterpret_cast<const T*>(P1)) | |||
return 1; | return 1; | |||
return 0; | return 0; | |||
} | } | |||
/// get_array_pad_sort_comparator - This is an internal helper function use d to | /// get_array_pod_sort_comparator - This is an internal helper function use d to | |||
/// get type deduction of T right. | /// get type deduction of T right. | |||
template<typename T> | template<typename T> | |||
inline int (*get_array_pad_sort_comparator(const T &)) | inline int (*get_array_pod_sort_comparator(const T &)) | |||
(const void*, const void*) { | (const void*, const void*) { | |||
return array_pod_sort_comparator<T>; | return array_pod_sort_comparator<T>; | |||
} | } | |||
/// array_pod_sort - This sorts an array with the specified start and end | /// array_pod_sort - This sorts an array with the specified start and end | |||
/// extent. This is just like std::sort, except that it calls qsort instea d of | /// extent. This is just like std::sort, except that it calls qsort instea d of | |||
/// using an inlined template. qsort is slightly slower than std::sort, bu t | /// using an inlined template. qsort is slightly slower than std::sort, bu t | |||
/// most sorts are not performance critical in LLVM and std::sort has to be | /// most sorts are not performance critical in LLVM and std::sort has to be | |||
/// template instantiated for each type, leading to significant measured co de | /// template instantiated for each type, leading to significant measured co de | |||
/// bloat. This function should generally be used instead of std::sort whe re | /// bloat. This function should generally be used instead of std::sort whe re | |||
skipping to change at line 272 | skipping to change at line 272 | |||
/// compared with operator< and can be moved with memcpy. If this isn't tr ue, | /// compared with operator< and can be moved with memcpy. If this isn't tr ue, | |||
/// you should use std::sort. | /// you should use std::sort. | |||
/// | /// | |||
/// NOTE: If qsort_r were portable, we could allow a custom comparator and | /// NOTE: If qsort_r were portable, we could allow a custom comparator and | |||
/// default to std::less. | /// default to std::less. | |||
template<class IteratorTy> | template<class IteratorTy> | |||
inline void array_pod_sort(IteratorTy Start, IteratorTy End) { | inline void array_pod_sort(IteratorTy Start, IteratorTy End) { | |||
// Don't dereference start iterator of empty sequence. | // Don't dereference start iterator of empty sequence. | |||
if (Start == End) return; | if (Start == End) return; | |||
qsort(&*Start, End-Start, sizeof(*Start), | qsort(&*Start, End-Start, sizeof(*Start), | |||
get_array_pad_sort_comparator(*Start)); | get_array_pod_sort_comparator(*Start)); | |||
} | } | |||
template<class IteratorTy> | template<class IteratorTy> | |||
inline void array_pod_sort(IteratorTy Start, IteratorTy End, | inline void array_pod_sort(IteratorTy Start, IteratorTy End, | |||
int (*Compare)(const void*, const void*)) { | int (*Compare)(const void*, const void*)) { | |||
// Don't dereference start iterator of empty sequence. | // Don't dereference start iterator of empty sequence. | |||
if (Start == End) return; | if (Start == End) return; | |||
qsort(&*Start, End-Start, sizeof(*Start), Compare); | qsort(&*Start, End-Start, sizeof(*Start), Compare); | |||
} | } | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
SaveAndRestore.h | SaveAndRestore.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file provides utility classes that uses RAII to save and restore | // This file provides utility classes that uses RAII to save and restore | |||
// values. | // values. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_SAVERESTORE | #ifndef LLVM_SUPPORT_SAVEANDRESTORE_H | |||
#define LLVM_ADT_SAVERESTORE | #define LLVM_SUPPORT_SAVEANDRESTORE_H | |||
namespace llvm { | namespace llvm { | |||
// SaveAndRestore - A utility class that uses RAII to save and restore | // SaveAndRestore - A utility class that uses RAII to save and restore | |||
// the value of a variable. | // the value of a variable. | |||
template<typename T> | template<typename T> | |||
struct SaveAndRestore { | struct SaveAndRestore { | |||
SaveAndRestore(T& x) : X(x), old_value(x) {} | SaveAndRestore(T& x) : X(x), old_value(x) {} | |||
SaveAndRestore(T& x, const T &new_value) : X(x), old_value(x) { | SaveAndRestore(T& x, const T &new_value) : X(x), old_value(x) { | |||
X = new_value; | X = new_value; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Scalar.h | Scalar.h | |||
---|---|---|---|---|
skipping to change at line 118 | skipping to change at line 118 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// LICM - This pass is a loop invariant code motion and memory promotion pa ss. | // LICM - This pass is a loop invariant code motion and memory promotion pa ss. | |||
// | // | |||
Pass *createLICMPass(); | Pass *createLICMPass(); | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// LoopStrengthReduce - This pass is strength reduces GEP instructions that use | // LoopStrengthReduce - This pass is strength reduces GEP instructions that use | |||
// a loop's canonical induction variable as one of their indices. It takes | // a loop's canonical induction variable as one of their indices. | |||
an | ||||
// optional parameter used to consult the target machine whether certain | ||||
// transformations are profitable. | ||||
// | // | |||
Pass *createLoopStrengthReducePass(const TargetLowering *TLI = 0); | Pass *createLoopStrengthReducePass(); | |||
Pass *createGlobalMergePass(const TargetLowering *TLI = 0); | Pass *createGlobalMergePass(const TargetLowering *TLI = 0); | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// LoopUnswitch - This pass is a simple loop unswitching pass. | // LoopUnswitch - This pass is a simple loop unswitching pass. | |||
// | // | |||
Pass *createLoopUnswitchPass(bool OptimizeForSize = false); | Pass *createLoopUnswitchPass(bool OptimizeForSize = false); | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
skipping to change at line 339 | skipping to change at line 337 | |||
Pass *createLowerAtomicPass(); | Pass *createLowerAtomicPass(); | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// ValuePropagation - Propagate CFG-derived value information | // ValuePropagation - Propagate CFG-derived value information | |||
// | // | |||
Pass *createCorrelatedValuePropagationPass(); | Pass *createCorrelatedValuePropagationPass(); | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// ObjCARCAPElim - ObjC ARC autorelease pool elimination. | ||||
// | ||||
Pass *createObjCARCAPElimPass(); | ||||
//===---------------------------------------------------------------------- | ||||
===// | ||||
// | ||||
// ObjCARCExpand - ObjC ARC preliminary simplifications. | ||||
// | ||||
Pass *createObjCARCExpandPass(); | ||||
//===---------------------------------------------------------------------- | ||||
===// | ||||
// | ||||
// ObjCARCContract - Late ObjC ARC cleanups. | ||||
// | ||||
Pass *createObjCARCContractPass(); | ||||
//===---------------------------------------------------------------------- | ||||
===// | ||||
// | ||||
// ObjCARCOpt - ObjC ARC optimization. | ||||
// | ||||
Pass *createObjCARCOptPass(); | ||||
//===---------------------------------------------------------------------- | ||||
===// | ||||
// | ||||
// InstructionSimplifier - Remove redundant instructions. | // InstructionSimplifier - Remove redundant instructions. | |||
// | // | |||
FunctionPass *createInstructionSimplifierPass(); | FunctionPass *createInstructionSimplifierPass(); | |||
extern char &InstructionSimplifierID; | extern char &InstructionSimplifierID; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// LowerExpectIntriniscs - Removes llvm.expect intrinsics and creates | // LowerExpectIntrinsics - Removes llvm.expect intrinsics and creates | |||
// "block_weights" metadata. | // "block_weights" metadata. | |||
FunctionPass *createLowerExpectIntrinsicPass(); | FunctionPass *createLowerExpectIntrinsicPass(); | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
34 lines changed or deleted | 3 lines changed or added | |||
ScalarEvolution.h | ScalarEvolution.h | |||
---|---|---|---|---|
skipping to change at line 24 | skipping to change at line 24 | |||
// properties can be obtained. | // properties can be obtained. | |||
// | // | |||
// This analysis is primarily useful for induction variable substitution an d | // This analysis is primarily useful for induction variable substitution an d | |||
// strength reduction. | // strength reduction. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H | #ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H | |||
#define LLVM_ANALYSIS_SCALAREVOLUTION_H | #define LLVM_ANALYSIS_SCALAREVOLUTION_H | |||
#include "llvm/ADT/DenseSet.h" | ||||
#include "llvm/ADT/FoldingSet.h" | ||||
#include "llvm/IR/Function.h" | ||||
#include "llvm/IR/Instructions.h" | ||||
#include "llvm/IR/Operator.h" | ||||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
#include "llvm/Instructions.h" | ||||
#include "llvm/Function.h" | ||||
#include "llvm/Operator.h" | ||||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/Support/ValueHandle.h" | ||||
#include "llvm/Support/Allocator.h" | #include "llvm/Support/Allocator.h" | |||
#include "llvm/Support/ConstantRange.h" | #include "llvm/Support/ConstantRange.h" | |||
#include "llvm/ADT/FoldingSet.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/ADT/DenseSet.h" | #include "llvm/Support/ValueHandle.h" | |||
#include <map> | #include <map> | |||
namespace llvm { | namespace llvm { | |||
class APInt; | class APInt; | |||
class Constant; | class Constant; | |||
class ConstantInt; | class ConstantInt; | |||
class DominatorTree; | class DominatorTree; | |||
class Type; | class Type; | |||
class ScalarEvolution; | class ScalarEvolution; | |||
class DataLayout; | class DataLayout; | |||
skipping to change at line 341 | skipping to change at line 341 | |||
/// getExact - Return the number of times this loop exit may fall thr ough | /// getExact - Return the number of times this loop exit may fall thr ough | |||
/// to the back edge, or SCEVCouldNotCompute. The loop is guaranteed not | /// to the back edge, or SCEVCouldNotCompute. The loop is guaranteed not | |||
/// to exit via this block before this number of iterations, but may exit | /// to exit via this block before this number of iterations, but may exit | |||
/// via another block. | /// via another block. | |||
const SCEV *getExact(BasicBlock *ExitingBlock, ScalarEvolution *SE) c onst; | const SCEV *getExact(BasicBlock *ExitingBlock, ScalarEvolution *SE) c onst; | |||
/// getMax - Get the max backedge taken count for the loop. | /// getMax - Get the max backedge taken count for the loop. | |||
const SCEV *getMax(ScalarEvolution *SE) const; | const SCEV *getMax(ScalarEvolution *SE) const; | |||
/// Return true if any backedge taken count expressions refer to the | ||||
given | ||||
/// subexpression. | ||||
bool hasOperand(const SCEV *S, ScalarEvolution *SE) const; | ||||
/// clear - Invalidate this result and free associated memory. | /// clear - Invalidate this result and free associated memory. | |||
void clear(); | void clear(); | |||
}; | }; | |||
/// BackedgeTakenCounts - Cache the backedge-taken count of the loops f or | /// BackedgeTakenCounts - Cache the backedge-taken count of the loops f or | |||
/// this function as they are computed. | /// this function as they are computed. | |||
DenseMap<const Loop*, BackedgeTakenInfo> BackedgeTakenCounts; | DenseMap<const Loop*, BackedgeTakenInfo> BackedgeTakenCounts; | |||
/// ConstantEvolutionLoopExitValue - This map contains entries for all of | /// ConstantEvolutionLoopExitValue - This map contains entries for all of | |||
/// the PHI instructions that we attempt to compute constant evolutions for. | /// the PHI instructions that we attempt to compute constant evolutions for. | |||
skipping to change at line 452 | skipping to change at line 456 | |||
/// ComputeExitLimit - Compute the number of times the backedge of the | /// ComputeExitLimit - Compute the number of times the backedge of the | |||
/// specified loop will execute if it exits via the specified block. | /// specified loop will execute if it exits via the specified block. | |||
ExitLimit ComputeExitLimit(const Loop *L, BasicBlock *ExitingBlock); | ExitLimit ComputeExitLimit(const Loop *L, BasicBlock *ExitingBlock); | |||
/// ComputeExitLimitFromCond - Compute the number of times the backedge of | /// ComputeExitLimitFromCond - Compute the number of times the backedge of | |||
/// the specified loop will execute if its exit condition were a condit ional | /// the specified loop will execute if its exit condition were a condit ional | |||
/// branch of ExitCond, TBB, and FBB. | /// branch of ExitCond, TBB, and FBB. | |||
ExitLimit ComputeExitLimitFromCond(const Loop *L, | ExitLimit ComputeExitLimitFromCond(const Loop *L, | |||
Value *ExitCond, | Value *ExitCond, | |||
BasicBlock *TBB, | BasicBlock *TBB, | |||
BasicBlock *FBB); | BasicBlock *FBB, | |||
bool IsSubExpr); | ||||
/// ComputeExitLimitFromICmp - Compute the number of times the backedge of | /// ComputeExitLimitFromICmp - Compute the number of times the backedge of | |||
/// the specified loop will execute if its exit condition were a condit ional | /// the specified loop will execute if its exit condition were a condit ional | |||
/// branch of the ICmpInst ExitCond, TBB, and FBB. | /// branch of the ICmpInst ExitCond, TBB, and FBB. | |||
ExitLimit ComputeExitLimitFromICmp(const Loop *L, | ExitLimit ComputeExitLimitFromICmp(const Loop *L, | |||
ICmpInst *ExitCond, | ICmpInst *ExitCond, | |||
BasicBlock *TBB, | BasicBlock *TBB, | |||
BasicBlock *FBB); | BasicBlock *FBB, | |||
bool IsSubExpr); | ||||
/// ComputeLoadConstantCompareExitLimit - Given an exit condition | /// ComputeLoadConstantCompareExitLimit - Given an exit condition | |||
/// of 'icmp op load X, cst', try to see if we can compute the | /// of 'icmp op load X, cst', try to see if we can compute the | |||
/// backedge-taken count. | /// backedge-taken count. | |||
ExitLimit ComputeLoadConstantCompareExitLimit(LoadInst *LI, | ExitLimit ComputeLoadConstantCompareExitLimit(LoadInst *LI, | |||
Constant *RHS, | Constant *RHS, | |||
const Loop *L, | const Loop *L, | |||
ICmpInst::Predicate p); | ICmpInst::Predicate p); | |||
/// ComputeExitCountExhaustively - If the loop is known to execute a | /// ComputeExitCountExhaustively - If the loop is known to execute a | |||
skipping to change at line 482 | skipping to change at line 488 | |||
/// try to evaluate a few iterations of the loop until we get the exit | /// try to evaluate a few iterations of the loop until we get the exit | |||
/// condition gets a value of ExitWhen (true or false). If we cannot | /// condition gets a value of ExitWhen (true or false). If we cannot | |||
/// evaluate the exit count of the loop, return CouldNotCompute. | /// evaluate the exit count of the loop, return CouldNotCompute. | |||
const SCEV *ComputeExitCountExhaustively(const Loop *L, | const SCEV *ComputeExitCountExhaustively(const Loop *L, | |||
Value *Cond, | Value *Cond, | |||
bool ExitWhen); | bool ExitWhen); | |||
/// HowFarToZero - Return the number of times an exit condition compari ng | /// HowFarToZero - Return the number of times an exit condition compari ng | |||
/// the specified value to zero will execute. If not computable, retur n | /// the specified value to zero will execute. If not computable, retur n | |||
/// CouldNotCompute. | /// CouldNotCompute. | |||
ExitLimit HowFarToZero(const SCEV *V, const Loop *L); | ExitLimit HowFarToZero(const SCEV *V, const Loop *L, bool IsSubExpr); | |||
/// HowFarToNonZero - Return the number of times an exit condition chec king | /// HowFarToNonZero - Return the number of times an exit condition chec king | |||
/// the specified value for nonzero will execute. If not computable, r eturn | /// the specified value for nonzero will execute. If not computable, r eturn | |||
/// CouldNotCompute. | /// CouldNotCompute. | |||
ExitLimit HowFarToNonZero(const SCEV *V, const Loop *L); | ExitLimit HowFarToNonZero(const SCEV *V, const Loop *L); | |||
/// HowManyLessThans - Return the number of times an exit condition | /// HowManyLessThans - Return the number of times an exit condition | |||
/// containing the specified less-than comparison will execute. If not | /// containing the specified less-than comparison will execute. If not | |||
/// computable, return CouldNotCompute. isSigned specifies whether the | /// computable, return CouldNotCompute. isSigned specifies whether the | |||
/// less-than is signed. | /// less-than is signed. | |||
ExitLimit HowManyLessThans(const SCEV *LHS, const SCEV *RHS, | ExitLimit HowManyLessThans(const SCEV *LHS, const SCEV *RHS, | |||
const Loop *L, bool isSigned); | const Loop *L, bool isSigned, bool IsSubExpr ); | |||
/// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB | /// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB | |||
/// (which may not be an immediate predecessor) which has exactly one | /// (which may not be an immediate predecessor) which has exactly one | |||
/// successor from which BB is reachable, or null if no such block is | /// successor from which BB is reachable, or null if no such block is | |||
/// found. | /// found. | |||
std::pair<BasicBlock *, BasicBlock *> | std::pair<BasicBlock *, BasicBlock *> | |||
getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB); | getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB); | |||
/// isImpliedCond - Test whether the condition described by Pred, LHS, and | /// isImpliedCond - Test whether the condition described by Pred, LHS, and | |||
/// RHS is true whenever the given FoundCondValue value evaluates to tr ue. | /// RHS is true whenever the given FoundCondValue value evaluates to tr ue. | |||
skipping to change at line 834 | skipping to change at line 840 | |||
bool isKnownNonZero(const SCEV *S); | bool isKnownNonZero(const SCEV *S); | |||
/// isKnownPredicate - Test if the given expression is known to satisfy | /// isKnownPredicate - Test if the given expression is known to satisfy | |||
/// the condition described by Pred, LHS, and RHS. | /// the condition described by Pred, LHS, and RHS. | |||
/// | /// | |||
bool isKnownPredicate(ICmpInst::Predicate Pred, | bool isKnownPredicate(ICmpInst::Predicate Pred, | |||
const SCEV *LHS, const SCEV *RHS); | const SCEV *LHS, const SCEV *RHS); | |||
/// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with | /// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with | |||
/// predicate Pred. Return true iff any changes were made. If the | /// predicate Pred. Return true iff any changes were made. If the | |||
/// operands are provably equal or inequal, LHS and RHS are set to | /// operands are provably equal or unequal, LHS and RHS are set to | |||
/// the same value and Pred is set to either ICMP_EQ or ICMP_NE. | /// the same value and Pred is set to either ICMP_EQ or ICMP_NE. | |||
/// | /// | |||
bool SimplifyICmpOperands(ICmpInst::Predicate &Pred, | bool SimplifyICmpOperands(ICmpInst::Predicate &Pred, | |||
const SCEV *&LHS, | const SCEV *&LHS, | |||
const SCEV *&RHS, | const SCEV *&RHS, | |||
unsigned Depth = 0); | unsigned Depth = 0); | |||
/// getLoopDisposition - Return the "disposition" of the given SCEV wit h | /// getLoopDisposition - Return the "disposition" of the given SCEV wit h | |||
/// respect to the given loop. | /// respect to the given loop. | |||
LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L); | LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L); | |||
End of changes. 9 change blocks. | ||||
12 lines changed or deleted | 19 lines changed or added | |||
ScalarEvolutionExpander.h | ScalarEvolutionExpander.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the classes used to generate code from scalar expressi ons. | // This file defines the classes used to generate code from scalar expressi ons. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H | #ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H | |||
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H | #define LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H | |||
#include "llvm/IRBuilder.h" | ||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h" | #include "llvm/Analysis/ScalarEvolutionExpressions.h" | |||
#include "llvm/Analysis/ScalarEvolutionNormalization.h" | #include "llvm/Analysis/ScalarEvolutionNormalization.h" | |||
#include "llvm/IR/IRBuilder.h" | ||||
#include "llvm/Support/TargetFolder.h" | #include "llvm/Support/TargetFolder.h" | |||
#include "llvm/Support/ValueHandle.h" | #include "llvm/Support/ValueHandle.h" | |||
#include <set> | #include <set> | |||
namespace llvm { | namespace llvm { | |||
class TargetLowering; | class TargetTransformInfo; | |||
/// Return true if the given expression is safe to expand in the sense th at | /// Return true if the given expression is safe to expand in the sense th at | |||
/// all materialized values are safe to speculate. | /// all materialized values are safe to speculate. | |||
bool isSafeToExpand(const SCEV *S); | bool isSafeToExpand(const SCEV *S); | |||
/// SCEVExpander - This class uses information about analyze scalars to | /// SCEVExpander - This class uses information about analyze scalars to | |||
/// rewrite expressions in canonical form. | /// rewrite expressions in canonical form. | |||
/// | /// | |||
/// Clients should create an instance of this class when rewriting is nee ded, | /// Clients should create an instance of this class when rewriting is nee ded, | |||
/// and destroy it when finished to allow the release of the associated | /// and destroy it when finished to allow the release of the associated | |||
/// memory. | /// memory. | |||
class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { | class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { | |||
ScalarEvolution &SE; | ScalarEvolution &SE; | |||
// New instructions receive a name to identifies them with the current pass. | // New instructions receive a name to identifies them with the current pass. | |||
const char* IVName; | const char* IVName; | |||
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> > | // InsertedExpressions caches Values for reuse, so must track RAUW. | |||
std::map<std::pair<const SCEV *, Instruction *>, TrackingVH<Value> > | ||||
InsertedExpressions; | InsertedExpressions; | |||
// InsertedValues only flags inserted instructions so needs no RAUW. | ||||
std::set<AssertingVH<Value> > InsertedValues; | std::set<AssertingVH<Value> > InsertedValues; | |||
std::set<AssertingVH<Value> > InsertedPostIncValues; | std::set<AssertingVH<Value> > InsertedPostIncValues; | |||
/// RelevantLoops - A memoization of the "relevant" loop for a given SC EV. | /// RelevantLoops - A memoization of the "relevant" loop for a given SC EV. | |||
DenseMap<const SCEV *, const Loop *> RelevantLoops; | DenseMap<const SCEV *, const Loop *> RelevantLoops; | |||
/// PostIncLoops - Addrecs referring to any of the given loops are expa nded | /// PostIncLoops - Addrecs referring to any of the given loops are expa nded | |||
/// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mod e | /// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mod e | |||
/// returns the add instruction that adds one to the phi for {0,+,1}<L> , | /// returns the add instruction that adds one to the phi for {0,+,1}<L> , | |||
/// as opposed to a new phi starting at 1. This is only supported in | /// as opposed to a new phi starting at 1. This is only supported in | |||
skipping to change at line 132 | skipping to change at line 134 | |||
Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos, | Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos, | |||
bool allowScale); | bool allowScale); | |||
/// hoistIVInc - Utility for hoisting an IV increment. | /// hoistIVInc - Utility for hoisting an IV increment. | |||
bool hoistIVInc(Instruction *IncV, Instruction *InsertPos); | bool hoistIVInc(Instruction *IncV, Instruction *InsertPos); | |||
/// replaceCongruentIVs - replace congruent phis with their most canoni cal | /// replaceCongruentIVs - replace congruent phis with their most canoni cal | |||
/// representative. Return the number of phis eliminated. | /// representative. Return the number of phis eliminated. | |||
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT, | unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT, | |||
SmallVectorImpl<WeakVH> &DeadInsts, | SmallVectorImpl<WeakVH> &DeadInsts, | |||
const TargetLowering *TLI = NULL); | const TargetTransformInfo *TTI = NULL); | |||
/// expandCodeFor - Insert code to directly compute the specified SCEV | /// expandCodeFor - Insert code to directly compute the specified SCEV | |||
/// expression into the program. The inserted code is inserted into th e | /// expression into the program. The inserted code is inserted into th e | |||
/// specified block. | /// specified block. | |||
Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I); | Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I); | |||
/// setIVIncInsertPos - Set the current IV increment loop and position. | /// setIVIncInsertPos - Set the current IV increment loop and position. | |||
void setIVIncInsertPos(const Loop *L, Instruction *Pos) { | void setIVIncInsertPos(const Loop *L, Instruction *Pos) { | |||
assert(!CanonicalMode && | assert(!CanonicalMode && | |||
"IV increment positions are not supported in CanonicalMode"); | "IV increment positions are not supported in CanonicalMode"); | |||
End of changes. 7 change blocks. | ||||
6 lines changed or deleted | 8 lines changed or added | |||
ScalarEvolutionExpressions.h | ScalarEvolutionExpressions.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the classes used to represent and build scalar express ions. | // This file defines the classes used to represent and build scalar express ions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H | #ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H | |||
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H | #define LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H | |||
#include "llvm/Analysis/ScalarEvolution.h" | ||||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/Analysis/ScalarEvolution.h" | ||||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
namespace llvm { | namespace llvm { | |||
class ConstantInt; | class ConstantInt; | |||
class ConstantRange; | class ConstantRange; | |||
class DominatorTree; | class DominatorTree; | |||
enum SCEVTypes { | enum SCEVTypes { | |||
// These should be ordered in terms of increasing complexity to make th e | // These should be ordered in terms of increasing complexity to make th e | |||
// folders simpler. | // folders simpler. | |||
skipping to change at line 545 | skipping to change at line 545 | |||
} | } | |||
} | } | |||
}; | }; | |||
/// Use SCEVTraversal to visit all nodes in the givien expression tree. | /// Use SCEVTraversal to visit all nodes in the givien expression tree. | |||
template<typename SV> | template<typename SV> | |||
void visitAll(const SCEV *Root, SV& Visitor) { | void visitAll(const SCEV *Root, SV& Visitor) { | |||
SCEVTraversal<SV> T(Visitor); | SCEVTraversal<SV> T(Visitor); | |||
T.visitAll(Root); | T.visitAll(Root); | |||
} | } | |||
/// The SCEVRewriter takes a scalar evolution expression and copies all i | ||||
ts | ||||
/// components. The result after a rewrite is an identical SCEV. | ||||
struct SCEVRewriter | ||||
: public SCEVVisitor<SCEVRewriter, const SCEV*> { | ||||
public: | ||||
SCEVRewriter(ScalarEvolution &S) : SE(S) {} | ||||
virtual ~SCEVRewriter() {} | ||||
virtual const SCEV *visitConstant(const SCEVConstant *Constant) { | ||||
return Constant; | ||||
} | ||||
virtual const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) { | ||||
const SCEV *Operand = visit(Expr->getOperand()); | ||||
return SE.getTruncateExpr(Operand, Expr->getType()); | ||||
} | ||||
virtual const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) | ||||
{ | ||||
const SCEV *Operand = visit(Expr->getOperand()); | ||||
return SE.getZeroExtendExpr(Operand, Expr->getType()); | ||||
} | ||||
virtual const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) | ||||
{ | ||||
const SCEV *Operand = visit(Expr->getOperand()); | ||||
return SE.getSignExtendExpr(Operand, Expr->getType()); | ||||
} | ||||
virtual const SCEV *visitAddExpr(const SCEVAddExpr *Expr) { | ||||
SmallVector<const SCEV *, 2> Operands; | ||||
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) | ||||
Operands.push_back(visit(Expr->getOperand(i))); | ||||
return SE.getAddExpr(Operands); | ||||
} | ||||
virtual const SCEV *visitMulExpr(const SCEVMulExpr *Expr) { | ||||
SmallVector<const SCEV *, 2> Operands; | ||||
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) | ||||
Operands.push_back(visit(Expr->getOperand(i))); | ||||
return SE.getMulExpr(Operands); | ||||
} | ||||
virtual const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) { | ||||
return SE.getUDivExpr(visit(Expr->getLHS()), visit(Expr->getRHS())); | ||||
} | ||||
virtual const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) { | ||||
SmallVector<const SCEV *, 2> Operands; | ||||
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) | ||||
Operands.push_back(visit(Expr->getOperand(i))); | ||||
return SE.getAddRecExpr(Operands, Expr->getLoop(), | ||||
Expr->getNoWrapFlags()); | ||||
} | ||||
virtual const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) { | ||||
SmallVector<const SCEV *, 2> Operands; | ||||
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) | ||||
Operands.push_back(visit(Expr->getOperand(i))); | ||||
return SE.getSMaxExpr(Operands); | ||||
} | ||||
virtual const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) { | ||||
SmallVector<const SCEV *, 2> Operands; | ||||
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) | ||||
Operands.push_back(visit(Expr->getOperand(i))); | ||||
return SE.getUMaxExpr(Operands); | ||||
} | ||||
virtual const SCEV *visitUnknown(const SCEVUnknown *Expr) { | ||||
return Expr; | ||||
} | ||||
virtual const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Exp | ||||
r) { | ||||
return Expr; | ||||
} | ||||
protected: | ||||
ScalarEvolution &SE; | ||||
}; | ||||
typedef DenseMap<const Value*, Value*> ValueToValueMap; | ||||
/// The SCEVParameterRewriter takes a scalar evolution expression and upd | ||||
ates | ||||
/// the SCEVUnknown components following the Map (Value -> Value). | ||||
struct SCEVParameterRewriter: public SCEVRewriter { | ||||
public: | ||||
static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE, | ||||
ValueToValueMap &Map) { | ||||
SCEVParameterRewriter Rewriter(SE, Map); | ||||
return Rewriter.visit(Scev); | ||||
} | ||||
SCEVParameterRewriter(ScalarEvolution &S, ValueToValueMap &M) | ||||
: SCEVRewriter(S), Map(M) {} | ||||
virtual const SCEV *visitUnknown(const SCEVUnknown *Expr) { | ||||
Value *V = Expr->getValue(); | ||||
if (Map.count(V)) | ||||
return SE.getUnknown(Map[V]); | ||||
return Expr; | ||||
} | ||||
private: | ||||
ValueToValueMap ⤅ | ||||
}; | ||||
typedef DenseMap<const Loop*, const SCEV*> LoopToScevMapT; | ||||
/// The SCEVApplyRewriter takes a scalar evolution expression and applies | ||||
/// the Map (Loop -> SCEV) to all AddRecExprs. | ||||
struct SCEVApplyRewriter: public SCEVRewriter { | ||||
public: | ||||
static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map, | ||||
ScalarEvolution &SE) { | ||||
SCEVApplyRewriter Rewriter(SE, Map); | ||||
return Rewriter.visit(Scev); | ||||
} | ||||
SCEVApplyRewriter(ScalarEvolution &S, LoopToScevMapT &M) | ||||
: SCEVRewriter(S), Map(M) {} | ||||
virtual const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) { | ||||
SmallVector<const SCEV *, 2> Operands; | ||||
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) | ||||
Operands.push_back(visit(Expr->getOperand(i))); | ||||
const Loop *L = Expr->getLoop(); | ||||
const SCEV *Res = SE.getAddRecExpr(Operands, L, Expr->getNoWrapFlags( | ||||
)); | ||||
if (0 == Map.count(L)) | ||||
return Res; | ||||
const SCEVAddRecExpr *Rec = (const SCEVAddRecExpr *) Res; | ||||
return Rec->evaluateAtIteration(Map[L], SE); | ||||
} | ||||
private: | ||||
LoopToScevMapT ⤅ | ||||
}; | ||||
/// Applies the Map (Loop -> SCEV) to the given Scev. | ||||
static inline const SCEV *apply(const SCEV *Scev, LoopToScevMapT &Map, | ||||
ScalarEvolution &SE) { | ||||
return SCEVApplyRewriter::rewrite(Scev, Map, SE); | ||||
} | ||||
} | } | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
3 lines changed or deleted | 154 lines changed or added | |||
ScalarEvolutionNormalization.h | ScalarEvolutionNormalization.h | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
// the same induction variable, with uses inside the loop using the | // the same induction variable, with uses inside the loop using the | |||
// "pre-incremented" value, and uses after the loop using the | // "pre-incremented" value, and uses after the loop using the | |||
// "post-incremented" value. | // "post-incremented" value. | |||
// | // | |||
// Expressions for post-incremented uses are represented as an expression | // Expressions for post-incremented uses are represented as an expression | |||
// paired with a set of loops for which the expression is in "post-incremen t" | // paired with a set of loops for which the expression is in "post-incremen t" | |||
// mode (there may be multiple loops). | // mode (there may be multiple loops). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H | #ifndef LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H | |||
#define LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H | #define LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H | |||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
namespace llvm { | namespace llvm { | |||
class Instruction; | class Instruction; | |||
class DominatorTree; | class DominatorTree; | |||
class Loop; | class Loop; | |||
class ScalarEvolution; | class ScalarEvolution; | |||
class SCEV; | class SCEV; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
ScheduleDAG.h | ScheduleDAG.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file implements the ScheduleDAG class, which is used as the common | // This file implements the ScheduleDAG class, which is used as the common | |||
// base class for instruction schedulers. This encapsulates the scheduling DAG, | // base class for instruction schedulers. This encapsulates the scheduling DAG, | |||
// which is shared between SelectionDAG and MachineInstr scheduling. | // which is shared between SelectionDAG and MachineInstr scheduling. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_SCHEDULEDAG_H | #ifndef LLVM_CODEGEN_SCHEDULEDAG_H | |||
#define LLVM_CODEGEN_SCHEDULEDAG_H | #define LLVM_CODEGEN_SCHEDULEDAG_H | |||
#include "llvm/CodeGen/MachineBasicBlock.h" | ||||
#include "llvm/Target/TargetLowering.h" | ||||
#include "llvm/ADT/DenseMap.h" | ||||
#include "llvm/ADT/BitVector.h" | #include "llvm/ADT/BitVector.h" | |||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/CodeGen/MachineInstr.h" | ||||
#include "llvm/Target/TargetLowering.h" | ||||
namespace llvm { | namespace llvm { | |||
class AliasAnalysis; | class AliasAnalysis; | |||
class SUnit; | class SUnit; | |||
class MachineConstantPool; | class MachineConstantPool; | |||
class MachineFunction; | class MachineFunction; | |||
class MachineRegisterInfo; | class MachineRegisterInfo; | |||
class MachineInstr; | class MachineInstr; | |||
struct MCSchedClassDesc; | struct MCSchedClassDesc; | |||
class TargetRegisterInfo; | class TargetRegisterInfo; | |||
skipping to change at line 56 | skipping to change at line 55 | |||
class SDep { | class SDep { | |||
public: | public: | |||
/// Kind - These are the different kinds of scheduling dependencies. | /// Kind - These are the different kinds of scheduling dependencies. | |||
enum Kind { | enum Kind { | |||
Data, ///< Regular data dependence (aka true-dependence). | Data, ///< Regular data dependence (aka true-dependence). | |||
Anti, ///< A register anti-dependedence (aka WAR). | Anti, ///< A register anti-dependedence (aka WAR). | |||
Output, ///< A register output-dependence (aka WAW). | Output, ///< A register output-dependence (aka WAW). | |||
Order ///< Any other ordering dependency. | Order ///< Any other ordering dependency. | |||
}; | }; | |||
// Strong dependencies must be respected by the scheduler. Artificial | ||||
// dependencies may be removed only if they are redundant with another | ||||
// strong depedence. | ||||
// | ||||
// Weak dependencies may be violated by the scheduling strategy, but on | ||||
ly if | ||||
// the strategy can prove it is correct to do so. | ||||
// | ||||
// Strong OrderKinds must occur before "Weak". | ||||
// Weak OrderKinds must occur after "Weak". | ||||
enum OrderKind { | enum OrderKind { | |||
Barrier, ///< An unknown scheduling barrier. | Barrier, ///< An unknown scheduling barrier. | |||
MayAliasMem, ///< Nonvolatile load/Store instructions that may alias . | MayAliasMem, ///< Nonvolatile load/Store instructions that may alias . | |||
MustAliasMem, ///< Nonvolatile load/Store instructions that must alia s. | MustAliasMem, ///< Nonvolatile load/Store instructions that must alia s. | |||
Artificial ///< Arbitrary weak DAG edge (no actual dependence). | Artificial, ///< Arbitrary strong DAG edge (no real dependence). | |||
Weak, ///< Arbitrary weak DAG edge. | ||||
Cluster ///< Weak DAG edge linking a chain of clustered instrs. | ||||
}; | }; | |||
private: | private: | |||
/// Dep - A pointer to the depending/depended-on SUnit, and an enum | /// Dep - A pointer to the depending/depended-on SUnit, and an enum | |||
/// indicating the kind of the dependency. | /// indicating the kind of the dependency. | |||
PointerIntPair<SUnit *, 2, Kind> Dep; | PointerIntPair<SUnit *, 2, Kind> Dep; | |||
/// Contents - A union discriminated by the dependence kind. | /// Contents - A union discriminated by the dependence kind. | |||
union { | union { | |||
/// Reg - For Data, Anti, and Output dependencies, the associated | /// Reg - For Data, Anti, and Output dependencies, the associated | |||
skipping to change at line 203 | skipping to change at line 213 | |||
|| Contents.OrdKind == MustAliasMem); | || Contents.OrdKind == MustAliasMem); | |||
} | } | |||
/// isMustAlias - Test if this is an Order dependence that is marked | /// isMustAlias - Test if this is an Order dependence that is marked | |||
/// as "must alias", meaning that the SUnits at either end of the edge | /// as "must alias", meaning that the SUnits at either end of the edge | |||
/// have a memory dependence on a known memory location. | /// have a memory dependence on a known memory location. | |||
bool isMustAlias() const { | bool isMustAlias() const { | |||
return getKind() == Order && Contents.OrdKind == MustAliasMem; | return getKind() == Order && Contents.OrdKind == MustAliasMem; | |||
} | } | |||
/// isWeak - Test if this a weak dependence. Weak dependencies are | ||||
/// considered DAG edges for height computation and other heuristics, b | ||||
ut do | ||||
/// not force ordering. Breaking a weak edge may require the scheduler | ||||
to | ||||
/// compensate, for example by inserting a copy. | ||||
bool isWeak() const { | ||||
return getKind() == Order && Contents.OrdKind >= Weak; | ||||
} | ||||
/// isArtificial - Test if this is an Order dependence that is marked | /// isArtificial - Test if this is an Order dependence that is marked | |||
/// as "artificial", meaning it isn't necessary for correctness. | /// as "artificial", meaning it isn't necessary for correctness. | |||
bool isArtificial() const { | bool isArtificial() const { | |||
return getKind() == Order && Contents.OrdKind == Artificial; | return getKind() == Order && Contents.OrdKind == Artificial; | |||
} | } | |||
/// isCluster - Test if this is an Order dependence that is marked | ||||
/// as "cluster", meaning it is artificial and wants to be adjacent. | ||||
bool isCluster() const { | ||||
return getKind() == Order && Contents.OrdKind == Cluster; | ||||
} | ||||
/// isAssignedRegDep - Test if this is a Data dependence that is | /// isAssignedRegDep - Test if this is a Data dependence that is | |||
/// associated with a register. | /// associated with a register. | |||
bool isAssignedRegDep() const { | bool isAssignedRegDep() const { | |||
return getKind() == Data && Contents.Reg != 0; | return getKind() == Data && Contents.Reg != 0; | |||
} | } | |||
/// getReg - Return the register associated with this edge. This is | /// getReg - Return the register associated with this edge. This is | |||
/// only valid on Data, Anti, and Output edges. On Data edges, this | /// only valid on Data, Anti, and Output edges. On Data edges, this | |||
/// value may be zero, meaning there is no associated register. | /// value may be zero, meaning there is no associated register. | |||
unsigned getReg() const { | unsigned getReg() const { | |||
skipping to change at line 246 | skipping to change at line 270 | |||
Contents.Reg = Reg; | Contents.Reg = Reg; | |||
} | } | |||
}; | }; | |||
template <> | template <> | |||
struct isPodLike<SDep> { static const bool value = true; }; | struct isPodLike<SDep> { static const bool value = true; }; | |||
/// SUnit - Scheduling unit. This is a node in the scheduling DAG. | /// SUnit - Scheduling unit. This is a node in the scheduling DAG. | |||
class SUnit { | class SUnit { | |||
private: | private: | |||
enum { BoundaryID = ~0u }; | ||||
SDNode *Node; // Representative node. | SDNode *Node; // Representative node. | |||
MachineInstr *Instr; // Alternatively, a MachineInstr. | MachineInstr *Instr; // Alternatively, a MachineInstr. | |||
public: | public: | |||
SUnit *OrigNode; // If not this, the node from which | SUnit *OrigNode; // If not this, the node from which | |||
// this node was cloned. | // this node was cloned. | |||
// (SD scheduling only) | // (SD scheduling only) | |||
const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass. | const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass. | |||
// Preds/Succs - The SUnits before/after us in the graph. | // Preds/Succs - The SUnits before/after us in the graph. | |||
skipping to change at line 270 | skipping to change at line 296 | |||
typedef SmallVector<SDep, 4>::iterator succ_iterator; | typedef SmallVector<SDep, 4>::iterator succ_iterator; | |||
typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator; | typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator; | |||
typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator; | typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator; | |||
unsigned NodeNum; // Entry # of node in the node vect or. | unsigned NodeNum; // Entry # of node in the node vect or. | |||
unsigned NodeQueueId; // Queue id of node. | unsigned NodeQueueId; // Queue id of node. | |||
unsigned NumPreds; // # of SDep::Data preds. | unsigned NumPreds; // # of SDep::Data preds. | |||
unsigned NumSuccs; // # of SDep::Data sucss. | unsigned NumSuccs; // # of SDep::Data sucss. | |||
unsigned NumPredsLeft; // # of preds not scheduled. | unsigned NumPredsLeft; // # of preds not scheduled. | |||
unsigned NumSuccsLeft; // # of succs not scheduled. | unsigned NumSuccsLeft; // # of succs not scheduled. | |||
unsigned WeakPredsLeft; // # of weak preds not scheduled. | ||||
unsigned WeakSuccsLeft; // # of weak succs not scheduled. | ||||
unsigned short NumRegDefsLeft; // # of reg defs with no scheduled use. | unsigned short NumRegDefsLeft; // # of reg defs with no scheduled use. | |||
unsigned short Latency; // Node latency. | unsigned short Latency; // Node latency. | |||
bool isVRegCycle : 1; // May use and def the same vreg. | bool isVRegCycle : 1; // May use and def the same vreg. | |||
bool isCall : 1; // Is a function call. | bool isCall : 1; // Is a function call. | |||
bool isCallOp : 1; // Is a function call operand. | bool isCallOp : 1; // Is a function call operand. | |||
bool isTwoAddress : 1; // Is a two-address instruction. | bool isTwoAddress : 1; // Is a two-address instruction. | |||
bool isCommutable : 1; // Is a commutable instruction. | bool isCommutable : 1; // Is a commutable instruction. | |||
bool hasPhysRegUses : 1; // Has physreg uses. | ||||
bool hasPhysRegDefs : 1; // Has physreg defs that are being used. | bool hasPhysRegDefs : 1; // Has physreg defs that are being used. | |||
bool hasPhysRegClobbers : 1; // Has any physreg defs, used or no t. | bool hasPhysRegClobbers : 1; // Has any physreg defs, used or no t. | |||
bool isPending : 1; // True once pending. | bool isPending : 1; // True once pending. | |||
bool isAvailable : 1; // True once available. | bool isAvailable : 1; // True once available. | |||
bool isScheduled : 1; // True once scheduled. | bool isScheduled : 1; // True once scheduled. | |||
bool isScheduleHigh : 1; // True if preferable to schedule h igh. | bool isScheduleHigh : 1; // True if preferable to schedule h igh. | |||
bool isScheduleLow : 1; // True if preferable to schedule l ow. | bool isScheduleLow : 1; // True if preferable to schedule l ow. | |||
bool isCloned : 1; // True if this node has been clone d. | bool isCloned : 1; // True if this node has been clone d. | |||
Sched::Preference SchedulingPref; // Scheduling preference. | Sched::Preference SchedulingPref; // Scheduling preference. | |||
skipping to change at line 304 | skipping to change at line 333 | |||
unsigned BotReadyCycle; // Cycle relative to end when node is ready. | unsigned BotReadyCycle; // Cycle relative to end when node is ready. | |||
const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null. | const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null. | |||
const TargetRegisterClass *CopySrcRC; | const TargetRegisterClass *CopySrcRC; | |||
/// SUnit - Construct an SUnit for pre-regalloc scheduling to represent | /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent | |||
/// an SDNode and any nodes flagged to it. | /// an SDNode and any nodes flagged to it. | |||
SUnit(SDNode *node, unsigned nodenum) | SUnit(SDNode *node, unsigned nodenum) | |||
: Node(node), Instr(0), OrigNode(0), SchedClass(0), NodeNum(nodenum), | : Node(node), Instr(0), OrigNode(0), SchedClass(0), NodeNum(nodenum), | |||
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), | NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), | |||
NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), | NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft | |||
isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(fa | (0), | |||
lse), | Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), | |||
isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(fals | isTwoAddress(false), isCommutable(false), hasPhysRegUses(false), | |||
e), | hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), | |||
isPending(false), isAvailable(false), isScheduled(false), | isAvailable(false), isScheduled(false), isScheduleHigh(false), | |||
isScheduleHigh(false), isScheduleLow(false), isCloned(false), | isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), | |||
SchedulingPref(Sched::None), | ||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), | isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), | |||
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL ) {} | TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL ) {} | |||
/// SUnit - Construct an SUnit for post-regalloc scheduling to represen t | /// SUnit - Construct an SUnit for post-regalloc scheduling to represen t | |||
/// a MachineInstr. | /// a MachineInstr. | |||
SUnit(MachineInstr *instr, unsigned nodenum) | SUnit(MachineInstr *instr, unsigned nodenum) | |||
: Node(0), Instr(instr), OrigNode(0), SchedClass(0), NodeNum(nodenum) , | : Node(0), Instr(instr), OrigNode(0), SchedClass(0), NodeNum(nodenum) , | |||
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), | NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), | |||
NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), | NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft | |||
isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(fa | (0), | |||
lse), | Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), | |||
isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(fals | isTwoAddress(false), isCommutable(false), hasPhysRegUses(false), | |||
e), | hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), | |||
isPending(false), isAvailable(false), isScheduled(false), | isAvailable(false), isScheduled(false), isScheduleHigh(false), | |||
isScheduleHigh(false), isScheduleLow(false), isCloned(false), | isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), | |||
SchedulingPref(Sched::None), | ||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), | isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), | |||
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL ) {} | TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL ) {} | |||
/// SUnit - Construct a placeholder SUnit. | /// SUnit - Construct a placeholder SUnit. | |||
SUnit() | SUnit() | |||
: Node(0), Instr(0), OrigNode(0), SchedClass(0), NodeNum(~0u), | : Node(0), Instr(0), OrigNode(0), SchedClass(0), NodeNum(BoundaryID), | |||
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), | NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), | |||
NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), | NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft | |||
isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(fa | (0), | |||
lse), | Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), | |||
isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(fals | isTwoAddress(false), isCommutable(false), hasPhysRegUses(false), | |||
e), | hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), | |||
isPending(false), isAvailable(false), isScheduled(false), | isAvailable(false), isScheduled(false), isScheduleHigh(false), | |||
isScheduleHigh(false), isScheduleLow(false), isCloned(false), | isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), | |||
SchedulingPref(Sched::None), | ||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), | isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), | |||
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL ) {} | TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL ) {} | |||
/// \brief Boundary nodes are placeholders for the boundary of the | ||||
/// scheduling region. | ||||
/// | ||||
/// BoundaryNodes can have DAG edges, including Data edges, but they do | ||||
not | ||||
/// correspond to schedulable entities (e.g. instructions) and do not h | ||||
ave a | ||||
/// valid ID. Consequently, always check for boundary nodes before acce | ||||
ssing | ||||
/// an assoicative data structure keyed on node ID. | ||||
bool isBoundaryNode() const { return NodeNum == BoundaryID; }; | ||||
/// setNode - Assign the representative SDNode for this SUnit. | /// setNode - Assign the representative SDNode for this SUnit. | |||
/// This may be used during pre-regalloc scheduling. | /// This may be used during pre-regalloc scheduling. | |||
void setNode(SDNode *N) { | void setNode(SDNode *N) { | |||
assert(!Instr && "Setting SDNode of SUnit with MachineInstr!"); | assert(!Instr && "Setting SDNode of SUnit with MachineInstr!"); | |||
Node = N; | Node = N; | |||
} | } | |||
/// getNode - Return the representative SDNode for this SUnit. | /// getNode - Return the representative SDNode for this SUnit. | |||
/// This may be used during pre-regalloc scheduling. | /// This may be used during pre-regalloc scheduling. | |||
SDNode *getNode() const { | SDNode *getNode() const { | |||
skipping to change at line 375 | skipping to change at line 413 | |||
/// getInstr - Return the representative MachineInstr for this SUnit. | /// getInstr - Return the representative MachineInstr for this SUnit. | |||
/// This may be used during post-regalloc scheduling. | /// This may be used during post-regalloc scheduling. | |||
MachineInstr *getInstr() const { | MachineInstr *getInstr() const { | |||
assert(!Node && "Reading MachineInstr of SUnit with SDNode!"); | assert(!Node && "Reading MachineInstr of SUnit with SDNode!"); | |||
return Instr; | return Instr; | |||
} | } | |||
/// addPred - This adds the specified edge as a pred of the current nod e if | /// addPred - This adds the specified edge as a pred of the current nod e if | |||
/// not already. It also adds the current node as a successor of the | /// not already. It also adds the current node as a successor of the | |||
/// specified node. | /// specified node. | |||
bool addPred(const SDep &D); | bool addPred(const SDep &D, bool Required = true); | |||
/// removePred - This removes the specified edge as a pred of the curre nt | /// removePred - This removes the specified edge as a pred of the curre nt | |||
/// node if it exists. It also removes the current node as a successor of | /// node if it exists. It also removes the current node as a successor of | |||
/// the specified node. | /// the specified node. | |||
void removePred(const SDep &D); | void removePred(const SDep &D); | |||
/// getDepth - Return the depth of this node, which is the length of th e | /// getDepth - Return the depth of this node, which is the length of th e | |||
/// maximum path up to any node which has no predecessors. | /// maximum path up to any node which has no predecessors. | |||
unsigned getDepth() const { | unsigned getDepth() const { | |||
if (!isDepthCurrent) | if (!isDepthCurrent) | |||
skipping to change at line 441 | skipping to change at line 479 | |||
return false; | return false; | |||
} | } | |||
bool isTopReady() const { | bool isTopReady() const { | |||
return NumPredsLeft == 0; | return NumPredsLeft == 0; | |||
} | } | |||
bool isBottomReady() const { | bool isBottomReady() const { | |||
return NumSuccsLeft == 0; | return NumSuccsLeft == 0; | |||
} | } | |||
/// \brief Order this node's predecessor edges such that the critical p | ||||
ath | ||||
/// edge occurs first. | ||||
void biasCriticalPath(); | ||||
void dump(const ScheduleDAG *G) const; | void dump(const ScheduleDAG *G) const; | |||
void dumpAll(const ScheduleDAG *G) const; | void dumpAll(const ScheduleDAG *G) const; | |||
void print(raw_ostream &O, const ScheduleDAG *G) const; | void print(raw_ostream &O, const ScheduleDAG *G) const; | |||
private: | private: | |||
void ComputeDepth(); | void ComputeDepth(); | |||
void ComputeHeight(); | void ComputeHeight(); | |||
}; | }; | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
skipping to change at line 549 | skipping to change at line 591 | |||
/// getInstrDesc - Return the MCInstrDesc of this SUnit. | /// getInstrDesc - Return the MCInstrDesc of this SUnit. | |||
/// Return NULL for SDNodes without a machine opcode. | /// Return NULL for SDNodes without a machine opcode. | |||
const MCInstrDesc *getInstrDesc(const SUnit *SU) const { | const MCInstrDesc *getInstrDesc(const SUnit *SU) const { | |||
if (SU->isInstr()) return &SU->getInstr()->getDesc(); | if (SU->isInstr()) return &SU->getInstr()->getDesc(); | |||
return getNodeDesc(SU->getNode()); | return getNodeDesc(SU->getNode()); | |||
} | } | |||
/// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG render ed | /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG render ed | |||
/// using 'dot'. | /// using 'dot'. | |||
/// | /// | |||
void viewGraph(const Twine &Name, const Twine &Title); | virtual void viewGraph(const Twine &Name, const Twine &Title); | |||
void viewGraph(); | virtual void viewGraph(); | |||
virtual void dumpNode(const SUnit *SU) const = 0; | virtual void dumpNode(const SUnit *SU) const = 0; | |||
/// getGraphNodeLabel - Return a label for an SUnit node in a visualiza tion | /// getGraphNodeLabel - Return a label for an SUnit node in a visualiza tion | |||
/// of the ScheduleDAG. | /// of the ScheduleDAG. | |||
virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0; | virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0; | |||
/// getDAGLabel - Return a label for the region of code covered by the DAG. | /// getDAGLabel - Return a label for the region of code covered by the DAG. | |||
virtual std::string getDAGName() const = 0; | virtual std::string getDAGName() const = 0; | |||
skipping to change at line 657 | skipping to change at line 699 | |||
/// ScheduleDAGTopologicalSort is a class that computes a topological | /// ScheduleDAGTopologicalSort is a class that computes a topological | |||
/// ordering for SUnits and provides methods for dynamically updating | /// ordering for SUnits and provides methods for dynamically updating | |||
/// the ordering as new edges are added. | /// the ordering as new edges are added. | |||
/// | /// | |||
/// This allows a very fast implementation of IsReachable, for example. | /// This allows a very fast implementation of IsReachable, for example. | |||
/// | /// | |||
class ScheduleDAGTopologicalSort { | class ScheduleDAGTopologicalSort { | |||
/// SUnits - A reference to the ScheduleDAG's SUnits. | /// SUnits - A reference to the ScheduleDAG's SUnits. | |||
std::vector<SUnit> &SUnits; | std::vector<SUnit> &SUnits; | |||
SUnit *ExitSU; | ||||
/// Index2Node - Maps topological index to the node number. | /// Index2Node - Maps topological index to the node number. | |||
std::vector<int> Index2Node; | std::vector<int> Index2Node; | |||
/// Node2Index - Maps the node number to its topological index. | /// Node2Index - Maps the node number to its topological index. | |||
std::vector<int> Node2Index; | std::vector<int> Node2Index; | |||
/// Visited - a set of nodes visited during a DFS traversal. | /// Visited - a set of nodes visited during a DFS traversal. | |||
BitVector Visited; | BitVector Visited; | |||
/// DFS - make a DFS traversal and mark all nodes affected by the | /// DFS - make a DFS traversal and mark all nodes affected by the | |||
/// edge insertion. These nodes will later get new topological indexes | /// edge insertion. These nodes will later get new topological indexes | |||
skipping to change at line 678 | skipping to change at line 721 | |||
void DFS(const SUnit *SU, int UpperBound, bool& HasLoop); | void DFS(const SUnit *SU, int UpperBound, bool& HasLoop); | |||
/// Shift - reassign topological indexes for the nodes in the DAG | /// Shift - reassign topological indexes for the nodes in the DAG | |||
/// to preserve the topological ordering. | /// to preserve the topological ordering. | |||
void Shift(BitVector& Visited, int LowerBound, int UpperBound); | void Shift(BitVector& Visited, int LowerBound, int UpperBound); | |||
/// Allocate - assign the topological index to the node n. | /// Allocate - assign the topological index to the node n. | |||
void Allocate(int n, int index); | void Allocate(int n, int index); | |||
public: | public: | |||
explicit ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits); | ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU); | |||
/// InitDAGTopologicalSorting - create the initial topological | /// InitDAGTopologicalSorting - create the initial topological | |||
/// ordering from the DAG to be scheduled. | /// ordering from the DAG to be scheduled. | |||
void InitDAGTopologicalSorting(); | void InitDAGTopologicalSorting(); | |||
/// IsReachable - Checks if SU is reachable from TargetSU. | /// IsReachable - Checks if SU is reachable from TargetSU. | |||
bool IsReachable(const SUnit *SU, const SUnit *TargetSU); | bool IsReachable(const SUnit *SU, const SUnit *TargetSU); | |||
/// WillCreateCycle - Returns true if adding an edge from SU to TargetS | /// WillCreateCycle - Return true if addPred(TargetSU, SU) creates a cy | |||
U | cle. | |||
/// will create a cycle. | bool WillCreateCycle(SUnit *TargetSU, SUnit *SU); | |||
bool WillCreateCycle(SUnit *SU, SUnit *TargetSU); | ||||
/// AddPred - Updates the topological ordering to accommodate an edge | /// AddPred - Updates the topological ordering to accommodate an edge | |||
/// to be added from SUnit X to SUnit Y. | /// to be added from SUnit X to SUnit Y. | |||
void AddPred(SUnit *Y, SUnit *X); | void AddPred(SUnit *Y, SUnit *X); | |||
/// RemovePred - Updates the topological ordering to accommodate an | /// RemovePred - Updates the topological ordering to accommodate an | |||
/// an edge to be removed from the specified node N from the predecesso rs | /// an edge to be removed from the specified node N from the predecesso rs | |||
/// of the current node M. | /// of the current node M. | |||
void RemovePred(SUnit *M, SUnit *N); | void RemovePred(SUnit *M, SUnit *N); | |||
End of changes. 21 change blocks. | ||||
38 lines changed or deleted | 84 lines changed or added | |||
ScheduleDAGInstrs.h | ScheduleDAGInstrs.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements the ScheduleDAGInstrs class, which implements | // This file implements the ScheduleDAGInstrs class, which implements | |||
// scheduling for a MachineInstr-based dependency graph. | // scheduling for a MachineInstr-based dependency graph. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef SCHEDULEDAGINSTRS_H | #ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H | |||
#define SCHEDULEDAGINSTRS_H | #define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H | |||
#include "llvm/CodeGen/MachineDominators.h" | #include "llvm/ADT/SparseSet.h" | |||
#include "llvm/CodeGen/MachineLoopInfo.h" | #include "llvm/ADT/SparseMultiSet.h" | |||
#include "llvm/CodeGen/ScheduleDAG.h" | #include "llvm/CodeGen/ScheduleDAG.h" | |||
#include "llvm/CodeGen/TargetSchedule.h" | #include "llvm/CodeGen/TargetSchedule.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Target/TargetRegisterInfo.h" | #include "llvm/Target/TargetRegisterInfo.h" | |||
#include "llvm/ADT/SmallSet.h" | ||||
#include "llvm/ADT/SparseSet.h" | ||||
#include <map> | ||||
namespace llvm { | namespace llvm { | |||
class MachineFrameInfo; | ||||
class MachineLoopInfo; | class MachineLoopInfo; | |||
class MachineDominatorTree; | class MachineDominatorTree; | |||
class LiveIntervals; | class LiveIntervals; | |||
class RegPressureTracker; | class RegPressureTracker; | |||
/// An individual mapping from virtual register number to SUnit. | /// An individual mapping from virtual register number to SUnit. | |||
struct VReg2SUnit { | struct VReg2SUnit { | |||
unsigned VirtReg; | unsigned VirtReg; | |||
SUnit *SU; | SUnit *SU; | |||
skipping to change at line 51 | skipping to change at line 49 | |||
unsigned getSparseSetIndex() const { | unsigned getSparseSetIndex() const { | |||
return TargetRegisterInfo::virtReg2Index(VirtReg); | return TargetRegisterInfo::virtReg2Index(VirtReg); | |||
} | } | |||
}; | }; | |||
/// Record a physical register access. | /// Record a physical register access. | |||
/// For non data-dependent uses, OpIdx == -1. | /// For non data-dependent uses, OpIdx == -1. | |||
struct PhysRegSUOper { | struct PhysRegSUOper { | |||
SUnit *SU; | SUnit *SU; | |||
int OpIdx; | int OpIdx; | |||
unsigned Reg; | ||||
PhysRegSUOper(SUnit *su, int op): SU(su), OpIdx(op) {} | PhysRegSUOper(SUnit *su, int op, unsigned R): SU(su), OpIdx(op), Reg(R) | |||
}; | {} | |||
/// Combine a SparseSet with a 1x1 vector to track physical registers. | ||||
/// The SparseSet allows iterating over the (few) live registers for quic | ||||
kly | ||||
/// comparing against a regmask or clearing the set. | ||||
/// | ||||
/// Storage for the map is allocated once for the pass. The map can be | ||||
/// cleared between scheduling regions without freeing unused entries. | ||||
class Reg2SUnitsMap { | ||||
SparseSet<unsigned> PhysRegSet; | ||||
std::vector<std::vector<PhysRegSUOper> > SUnits; | ||||
public: | ||||
typedef SparseSet<unsigned>::const_iterator const_iterator; | ||||
// Allow iteration over register numbers (keys) in the map. If needed, | ||||
we | ||||
// can provide an iterator over SUnits (values) as well. | ||||
const_iterator reg_begin() const { return PhysRegSet.begin(); } | ||||
const_iterator reg_end() const { return PhysRegSet.end(); } | ||||
/// Initialize the map with the number of registers. | ||||
/// If the map is already large enough, no allocation occurs. | ||||
/// For simplicity we expect the map to be empty(). | ||||
void setRegLimit(unsigned Limit); | ||||
/// Returns true if the map is empty. | ||||
bool empty() const { return PhysRegSet.empty(); } | ||||
/// Clear the map without deallocating storage. | ||||
void clear(); | ||||
bool contains(unsigned Reg) const { return PhysRegSet.count(Reg); } | ||||
/// If this register is mapped, return its existing SUnits vector. | ||||
/// Otherwise map the register and return an empty SUnits vector. | ||||
std::vector<PhysRegSUOper> &operator[](unsigned Reg) { | ||||
bool New = PhysRegSet.insert(Reg).second; | ||||
assert((!New || SUnits[Reg].empty()) && "stale SUnits vector"); | ||||
(void)New; | ||||
return SUnits[Reg]; | ||||
} | ||||
/// Erase an existing element without freeing memory. | unsigned getSparseSetIndex() const { return Reg; } | |||
void erase(unsigned Reg) { | ||||
PhysRegSet.erase(Reg); | ||||
SUnits[Reg].clear(); | ||||
} | ||||
}; | }; | |||
/// Use a SparseMultiSet to track physical registers. Storage is only | ||||
/// allocated once for the pass. It can be cleared in constant time and r | ||||
eused | ||||
/// without any frees. | ||||
typedef SparseMultiSet<PhysRegSUOper, llvm::identity<unsigned>, uint16_t> | ||||
Reg2SUnitsMap; | ||||
/// Use SparseSet as a SparseMap by relying on the fact that it never | /// Use SparseSet as a SparseMap by relying on the fact that it never | |||
/// compares ValueT's, only unsigned keys. This allows the set to be clea red | /// compares ValueT's, only unsigned keys. This allows the set to be clea red | |||
/// between scheduling regions in constant time as long as ValueT does no t | /// between scheduling regions in constant time as long as ValueT does no t | |||
/// require a destructor. | /// require a destructor. | |||
typedef SparseSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMap; | typedef SparseSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMap; | |||
/// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of | /// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of | |||
/// MachineInstrs. | /// MachineInstrs. | |||
class ScheduleDAGInstrs : public ScheduleDAG { | class ScheduleDAGInstrs : public ScheduleDAG { | |||
protected: | protected: | |||
skipping to change at line 148 | skipping to change at line 108 | |||
/// The block in which to insert instructions | /// The block in which to insert instructions | |||
MachineBasicBlock *BB; | MachineBasicBlock *BB; | |||
/// The beginning of the range to be scheduled. | /// The beginning of the range to be scheduled. | |||
MachineBasicBlock::iterator RegionBegin; | MachineBasicBlock::iterator RegionBegin; | |||
/// The end of the range to be scheduled. | /// The end of the range to be scheduled. | |||
MachineBasicBlock::iterator RegionEnd; | MachineBasicBlock::iterator RegionEnd; | |||
/// The index in BB of RegionEnd. | /// The index in BB of RegionEnd. | |||
/// | ||||
/// This is the instruction number from the top of the current block, n | ||||
ot | ||||
/// the SlotIndex. It is only used by the AntiDepBreaker and should be | ||||
/// removed once that client is obsolete. | ||||
unsigned EndIndex; | unsigned EndIndex; | |||
/// After calling BuildSchedGraph, each machine instruction in the curr ent | /// After calling BuildSchedGraph, each machine instruction in the curr ent | |||
/// scheduling region is mapped to an SUnit. | /// scheduling region is mapped to an SUnit. | |||
DenseMap<MachineInstr*, SUnit*> MISUnitMap; | DenseMap<MachineInstr*, SUnit*> MISUnitMap; | |||
/// State internal to DAG building. | /// State internal to DAG building. | |||
/// ------------------------------- | /// ------------------------------- | |||
/// Defs, Uses - Remember where defs and uses of each register are as w e | /// Defs, Uses - Remember where defs and uses of each register are as w e | |||
skipping to change at line 189 | skipping to change at line 153 | |||
public: | public: | |||
explicit ScheduleDAGInstrs(MachineFunction &mf, | explicit ScheduleDAGInstrs(MachineFunction &mf, | |||
const MachineLoopInfo &mli, | const MachineLoopInfo &mli, | |||
const MachineDominatorTree &mdt, | const MachineDominatorTree &mdt, | |||
bool IsPostRAFlag, | bool IsPostRAFlag, | |||
LiveIntervals *LIS = 0); | LiveIntervals *LIS = 0); | |||
virtual ~ScheduleDAGInstrs() {} | virtual ~ScheduleDAGInstrs() {} | |||
/// \brief Expose LiveIntervals for use in DAG mutators and such. | ||||
LiveIntervals *getLIS() const { return LIS; } | ||||
/// \brief Get the machine model for instruction scheduling. | /// \brief Get the machine model for instruction scheduling. | |||
const TargetSchedModel *getSchedModel() const { return &SchedModel; } | const TargetSchedModel *getSchedModel() const { return &SchedModel; } | |||
/// \brief Resolve and cache a resolved scheduling class for an SUnit. | /// \brief Resolve and cache a resolved scheduling class for an SUnit. | |||
const MCSchedClassDesc *getSchedClass(SUnit *SU) const { | const MCSchedClassDesc *getSchedClass(SUnit *SU) const { | |||
if (!SU->SchedClass) | if (!SU->SchedClass) | |||
SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr()); | SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr()); | |||
return SU->SchedClass; | return SU->SchedClass; | |||
} | } | |||
End of changes. 10 change blocks. | ||||
55 lines changed or deleted | 24 lines changed or added | |||
SchedulerRegistry.h | SchedulerRegistry.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the implementation for instruction scheduler function | // This file contains the implementation for instruction scheduler function | |||
// pass registry (RegisterScheduler). | // pass registry (RegisterScheduler). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGENSCHEDULERREGISTRY_H | #ifndef LLVM_CODEGEN_SCHEDULERREGISTRY_H | |||
#define LLVM_CODEGENSCHEDULERREGISTRY_H | #define LLVM_CODEGEN_SCHEDULERREGISTRY_H | |||
#include "llvm/CodeGen/MachinePassRegistry.h" | #include "llvm/CodeGen/MachinePassRegistry.h" | |||
#include "llvm/Target/TargetMachine.h" | #include "llvm/Target/TargetMachine.h" | |||
namespace llvm { | namespace llvm { | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// | /// | |||
/// RegisterScheduler class - Track the registration of instruction schedul ers. | /// RegisterScheduler class - Track the registration of instruction schedul ers. | |||
/// | /// | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
ScoreboardHazardRecognizer.h | ScoreboardHazardRecognizer.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// encapsulates hazard-avoidance heuristics for scheduling, based on the | // encapsulates hazard-avoidance heuristics for scheduling, based on the | |||
// scheduling itineraries specified for the target. | // scheduling itineraries specified for the target. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H | #ifndef LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H | |||
#define LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H | #define LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H | |||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h" | #include "llvm/CodeGen/ScheduleHazardRecognizer.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <cassert> | #include <cassert> | |||
#include <cstring> | #include <cstring> | |||
namespace llvm { | namespace llvm { | |||
class InstrItineraryData; | class InstrItineraryData; | |||
class ScheduleDAG; | class ScheduleDAG; | |||
class SUnit; | class SUnit; | |||
class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer { | class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer { | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 0 lines changed or added | |||
SelectionDAG.h | SelectionDAG.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the SelectionDAG class, and transitively defines the | // This file declares the SelectionDAG class, and transitively defines the | |||
// SDNode class and subclasses. | // SDNode class and subclasses. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_SELECTIONDAG_H | #ifndef LLVM_CODEGEN_SELECTIONDAG_H | |||
#define LLVM_CODEGEN_SELECTIONDAG_H | #define LLVM_CODEGEN_SELECTIONDAG_H | |||
#include "llvm/ADT/ilist.h" | ||||
#include "llvm/ADT/DenseSet.h" | #include "llvm/ADT/DenseSet.h" | |||
#include "llvm/ADT/StringMap.h" | #include "llvm/ADT/StringMap.h" | |||
#include "llvm/ADT/ilist.h" | ||||
#include "llvm/CodeGen/DAGCombine.h" | ||||
#include "llvm/CodeGen/SelectionDAGNodes.h" | #include "llvm/CodeGen/SelectionDAGNodes.h" | |||
#include "llvm/Support/RecyclingAllocator.h" | #include "llvm/Support/RecyclingAllocator.h" | |||
#include "llvm/Target/TargetMachine.h" | #include "llvm/Target/TargetMachine.h" | |||
#include <cassert> | #include <cassert> | |||
#include <vector> | ||||
#include <map> | #include <map> | |||
#include <string> | #include <string> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
class AliasAnalysis; | class AliasAnalysis; | |||
class MachineConstantPoolValue; | class MachineConstantPoolValue; | |||
class MachineFunction; | class MachineFunction; | |||
class MDNode; | class MDNode; | |||
class SDNodeOrdering; | class SDNodeOrdering; | |||
class SDDbgValue; | class SDDbgValue; | |||
class TargetLowering; | class TargetLowering; | |||
class TargetSelectionDAGInfo; | class TargetSelectionDAGInfo; | |||
class TargetTransformInfo; | ||||
template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode > { | template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode > { | |||
private: | private: | |||
mutable ilist_half_node<SDNode> Sentinel; | mutable ilist_half_node<SDNode> Sentinel; | |||
public: | public: | |||
SDNode *createSentinel() const { | SDNode *createSentinel() const { | |||
return static_cast<SDNode*>(&Sentinel); | return static_cast<SDNode*>(&Sentinel); | |||
} | } | |||
static void destroySentinel(SDNode *) {} | static void destroySentinel(SDNode *) {} | |||
skipping to change at line 114 | skipping to change at line 116 | |||
return ArrayRef<SDDbgValue*>(); | return ArrayRef<SDDbgValue*>(); | |||
} | } | |||
typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator; | typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator; | |||
DbgIterator DbgBegin() { return DbgValues.begin(); } | DbgIterator DbgBegin() { return DbgValues.begin(); } | |||
DbgIterator DbgEnd() { return DbgValues.end(); } | DbgIterator DbgEnd() { return DbgValues.end(); } | |||
DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); } | DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); } | |||
DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); } | DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); } | |||
}; | }; | |||
enum CombineLevel { | ||||
BeforeLegalizeTypes, | ||||
AfterLegalizeTypes, | ||||
AfterLegalizeVectorOps, | ||||
AfterLegalizeDAG | ||||
}; | ||||
class SelectionDAG; | class SelectionDAG; | |||
void checkForCycles(const SDNode *N); | void checkForCycles(const SDNode *N); | |||
void checkForCycles(const SelectionDAG *DAG); | void checkForCycles(const SelectionDAG *DAG); | |||
/// SelectionDAG class - This is used to represent a portion of an LLVM fun ction | /// SelectionDAG class - This is used to represent a portion of an LLVM fun ction | |||
/// in a low-level Data Dependence DAG representation suitable for instruct ion | /// in a low-level Data Dependence DAG representation suitable for instruct ion | |||
/// selection. This DAG is constructed as the first step of instruction | /// selection. This DAG is constructed as the first step of instruction | |||
/// selection in order to allow implementation of machine specific optimiza tions | /// selection in order to allow implementation of machine specific optimiza tions | |||
/// and code simplifications. | /// and code simplifications. | |||
/// | /// | |||
/// The representation used by the SelectionDAG is a target-independent | /// The representation used by the SelectionDAG is a target-independent | |||
/// representation, which has some similarities to the GCC RTL representati on, | /// representation, which has some similarities to the GCC RTL representati on, | |||
/// but is significantly more simple, powerful, and is a graph form instead of a | /// but is significantly more simple, powerful, and is a graph form instead of a | |||
/// linear form. | /// linear form. | |||
/// | /// | |||
class SelectionDAG { | class SelectionDAG { | |||
const TargetMachine &TM; | const TargetMachine &TM; | |||
const TargetLowering &TLI; | const TargetLowering &TLI; | |||
const TargetSelectionDAGInfo &TSI; | const TargetSelectionDAGInfo &TSI; | |||
const TargetTransformInfo *TTI; | ||||
MachineFunction *MF; | MachineFunction *MF; | |||
LLVMContext *Context; | LLVMContext *Context; | |||
CodeGenOpt::Level OptLevel; | CodeGenOpt::Level OptLevel; | |||
/// EntryNode - The starting token. | /// EntryNode - The starting token. | |||
SDNode EntryNode; | SDNode EntryNode; | |||
/// Root - The root of the entire DAG. | /// Root - The root of the entire DAG. | |||
SDValue Root; | SDValue Root; | |||
skipping to change at line 235 | skipping to change at line 231 | |||
void operator=(const SelectionDAG&) LLVM_DELETED_FUNCTION; | void operator=(const SelectionDAG&) LLVM_DELETED_FUNCTION; | |||
SelectionDAG(const SelectionDAG&) LLVM_DELETED_FUNCTION; | SelectionDAG(const SelectionDAG&) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
explicit SelectionDAG(const TargetMachine &TM, llvm::CodeGenOpt::Level); | explicit SelectionDAG(const TargetMachine &TM, llvm::CodeGenOpt::Level); | |||
~SelectionDAG(); | ~SelectionDAG(); | |||
/// init - Prepare this SelectionDAG to process code in the given | /// init - Prepare this SelectionDAG to process code in the given | |||
/// MachineFunction. | /// MachineFunction. | |||
/// | /// | |||
void init(MachineFunction &mf); | void init(MachineFunction &mf, const TargetTransformInfo *TTI); | |||
/// clear - Clear state and free memory necessary to make this | /// clear - Clear state and free memory necessary to make this | |||
/// SelectionDAG ready to process a new block. | /// SelectionDAG ready to process a new block. | |||
/// | /// | |||
void clear(); | void clear(); | |||
MachineFunction &getMachineFunction() const { return *MF; } | MachineFunction &getMachineFunction() const { return *MF; } | |||
const TargetMachine &getTarget() const { return TM; } | const TargetMachine &getTarget() const { return TM; } | |||
const TargetLowering &getTargetLoweringInfo() const { return TLI; } | const TargetLowering &getTargetLoweringInfo() const { return TLI; } | |||
const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; } | const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; } | |||
const TargetTransformInfo *getTargetTransformInfo() const { return TTI; } | ||||
LLVMContext *getContext() const {return Context; } | LLVMContext *getContext() const {return Context; } | |||
/// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using ' dot'. | /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using ' dot'. | |||
/// | /// | |||
void viewGraph(const std::string &Title); | void viewGraph(const std::string &Title); | |||
void viewGraph(); | void viewGraph(); | |||
#ifndef NDEBUG | #ifndef NDEBUG | |||
std::map<const SDNode *, std::string> NodeGraphAttrs; | std::map<const SDNode *, std::string> NodeGraphAttrs; | |||
#endif | #endif | |||
skipping to change at line 573 | skipping to change at line 570 | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, | SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, | |||
SDValue N1, SDValue N2, SDValue N3, SDValue N4); | SDValue N1, SDValue N2, SDValue N3, SDValue N4); | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, | SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, | |||
SDValue N1, SDValue N2, SDValue N3, SDValue N4, | SDValue N1, SDValue N2, SDValue N3, SDValue N4, | |||
SDValue N5); | SDValue N5); | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, | SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, | |||
const SDUse *Ops, unsigned NumOps); | const SDUse *Ops, unsigned NumOps); | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, | SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, | |||
const SDValue *Ops, unsigned NumOps); | const SDValue *Ops, unsigned NumOps); | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, | SDValue getNode(unsigned Opcode, DebugLoc DL, | |||
const std::vector<EVT> &ResultTys, | ArrayRef<EVT> ResultTys, | |||
const SDValue *Ops, unsigned NumOps); | const SDValue *Ops, unsigned NumOps); | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, const EVT *VTs, unsigned Nu mVTs, | SDValue getNode(unsigned Opcode, DebugLoc DL, const EVT *VTs, unsigned Nu mVTs, | |||
const SDValue *Ops, unsigned NumOps); | const SDValue *Ops, unsigned NumOps); | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, | SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, | |||
const SDValue *Ops, unsigned NumOps); | const SDValue *Ops, unsigned NumOps); | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs); | SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs); | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, SDValue N); | SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, SDValue N); | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, | SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, | |||
SDValue N1, SDValue N2); | SDValue N1, SDValue N2); | |||
SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, | SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, | |||
skipping to change at line 816 | skipping to change at line 813 | |||
/// | /// | |||
/// Note that getMachineNode returns the resultant node. If there is alr eady | /// Note that getMachineNode returns the resultant node. If there is alr eady | |||
/// a node of the specified opcode and operands, it returns that node ins tead | /// a node of the specified opcode and operands, it returns that node ins tead | |||
/// of the current one. | /// of the current one. | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT); | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, | |||
SDValue Op1); | SDValue Op1); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, | |||
SDValue Op1, SDValue Op2); | SDValue Op1, SDValue Op2); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, | |||
SDValue Op1, SDValue Op2, SDValue Op3); | SDValue Op1, SDValue Op2, SDValue Op3); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, | |||
const SDValue *Ops, unsigned NumOps); | ArrayRef<SDValue> Ops); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2); | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | |||
SDValue Op1); | SDValue Op1); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, | ||||
EVT VT2, SDValue Op1, SDValue Op2); | ||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, | ||||
EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3); | ||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | |||
const SDValue *Ops, unsigned NumOps); | SDValue Op1, SDValue Op2); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT | ||||
VT2, | ||||
SDValue Op1, SDValue Op2, SDValue Op3); | ||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT | ||||
VT2, | ||||
ArrayRef<SDValue> Ops); | ||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | |||
EVT VT3, SDValue Op1, SDValue Op2); | EVT VT3, SDValue Op1, SDValue Op2); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | |||
EVT VT3, SDValue Op1, SDValue Op2, SDValue Op3); | EVT VT3, SDValue Op1, SDValue Op2, | |||
SDValue Op3); | ||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | |||
EVT VT3, const SDValue *Ops, unsigned NumOps); | EVT VT3, ArrayRef<SDValue> Ops); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, | |||
EVT VT3, EVT VT4, const SDValue *Ops, unsigned Num Ops); | EVT VT3, EVT VT4, ArrayRef<SDValue> Ops); | |||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, | |||
const std::vector<EVT> &ResultTys, const SDValue * | ArrayRef<EVT> ResultTys, | |||
Ops, | ArrayRef<SDValue> Ops); | |||
unsigned NumOps); | ||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, SDVTList VTs, | MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, SDVTList VTs, | |||
const SDValue *Ops, unsigned NumOps); | ArrayRef<SDValue> Ops); | |||
/// getTargetExtractSubreg - A convenience function for creating | /// getTargetExtractSubreg - A convenience function for creating | |||
/// TargetInstrInfo::EXTRACT_SUBREG nodes. | /// TargetInstrInfo::EXTRACT_SUBREG nodes. | |||
SDValue getTargetExtractSubreg(int SRIdx, DebugLoc DL, EVT VT, | SDValue getTargetExtractSubreg(int SRIdx, DebugLoc DL, EVT VT, | |||
SDValue Operand); | SDValue Operand); | |||
/// getTargetInsertSubreg - A convenience function for creating | /// getTargetInsertSubreg - A convenience function for creating | |||
/// TargetInstrInfo::INSERT_SUBREG nodes. | /// TargetInstrInfo::INSERT_SUBREG nodes. | |||
SDValue getTargetInsertSubreg(int SRIdx, DebugLoc DL, EVT VT, | SDValue getTargetInsertSubreg(int SRIdx, DebugLoc DL, EVT VT, | |||
SDValue Operand, SDValue Subreg); | SDValue Operand, SDValue Subreg); | |||
skipping to change at line 941 | skipping to change at line 939 | |||
case ISD::OR: | case ISD::OR: | |||
case ISD::XOR: | case ISD::XOR: | |||
case ISD::SADDO: | case ISD::SADDO: | |||
case ISD::UADDO: | case ISD::UADDO: | |||
case ISD::ADDC: | case ISD::ADDC: | |||
case ISD::ADDE: return true; | case ISD::ADDE: return true; | |||
default: return false; | default: return false; | |||
} | } | |||
} | } | |||
/// Returns an APFloat semantics tag appropriate for the given type. If V | ||||
T is | ||||
/// a vector type, the element semantics are returned. | ||||
static const fltSemantics &EVTToAPFloatSemantics(EVT VT) { | ||||
switch (VT.getScalarType().getSimpleVT().SimpleTy) { | ||||
default: llvm_unreachable("Unknown FP format"); | ||||
case MVT::f16: return APFloat::IEEEhalf; | ||||
case MVT::f32: return APFloat::IEEEsingle; | ||||
case MVT::f64: return APFloat::IEEEdouble; | ||||
case MVT::f80: return APFloat::x87DoubleExtended; | ||||
case MVT::f128: return APFloat::IEEEquad; | ||||
case MVT::ppcf128: return APFloat::PPCDoubleDouble; | ||||
} | ||||
} | ||||
/// AssignOrdering - Assign an order to the SDNode. | /// AssignOrdering - Assign an order to the SDNode. | |||
void AssignOrdering(const SDNode *SD, unsigned Order); | void AssignOrdering(const SDNode *SD, unsigned Order); | |||
/// GetOrdering - Get the order for the SDNode. | /// GetOrdering - Get the order for the SDNode. | |||
unsigned GetOrdering(const SDNode *SD) const; | unsigned GetOrdering(const SDNode *SD) const; | |||
/// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means th e | /// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means th e | |||
/// value is produced by SD. | /// value is produced by SD. | |||
void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter); | void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter); | |||
skipping to change at line 984 | skipping to change at line 996 | |||
/// CreateStackTemporary - Create a stack temporary, suitable for holding the | /// CreateStackTemporary - Create a stack temporary, suitable for holding the | |||
/// specified value type. If minAlign is specified, the slot size will h ave | /// specified value type. If minAlign is specified, the slot size will h ave | |||
/// at least that alignment. | /// at least that alignment. | |||
SDValue CreateStackTemporary(EVT VT, unsigned minAlign = 1); | SDValue CreateStackTemporary(EVT VT, unsigned minAlign = 1); | |||
/// CreateStackTemporary - Create a stack temporary suitable for holding | /// CreateStackTemporary - Create a stack temporary suitable for holding | |||
/// either of the specified value types. | /// either of the specified value types. | |||
SDValue CreateStackTemporary(EVT VT1, EVT VT2); | SDValue CreateStackTemporary(EVT VT1, EVT VT2); | |||
/// FoldConstantArithmetic - | /// FoldConstantArithmetic - | |||
SDValue FoldConstantArithmetic(unsigned Opcode, | SDValue FoldConstantArithmetic(unsigned Opcode, EVT VT, | |||
EVT VT, | SDNode *Cst1, SDNode *Cst2); | |||
ConstantSDNode *Cst1, | ||||
ConstantSDNode *Cst2); | ||||
/// FoldSetCC - Constant fold a setcc to true or false. | /// FoldSetCC - Constant fold a setcc to true or false. | |||
SDValue FoldSetCC(EVT VT, SDValue N1, | SDValue FoldSetCC(EVT VT, SDValue N1, | |||
SDValue N2, ISD::CondCode Cond, DebugLoc dl); | SDValue N2, ISD::CondCode Cond, DebugLoc dl); | |||
/// SignBitIsZero - Return true if the sign bit of Op is known to be zero . We | /// SignBitIsZero - Return true if the sign bit of Op is known to be zero . We | |||
/// use this predicate to simplify operations downstream. | /// use this predicate to simplify operations downstream. | |||
bool SignBitIsZero(SDValue Op, unsigned Depth = 0) const; | bool SignBitIsZero(SDValue Op, unsigned Depth = 0) const; | |||
/// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We | /// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We | |||
End of changes. 22 change blocks. | ||||
31 lines changed or deleted | 43 lines changed or added | |||
SelectionDAGISel.h | SelectionDAGISel.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements the SelectionDAGISel class, which is used as the co mmon | // This file implements the SelectionDAGISel class, which is used as the co mmon | |||
// base class for SelectionDAG-based instruction selectors. | // base class for SelectionDAG-based instruction selectors. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_SELECTIONDAG_ISEL_H | #ifndef LLVM_CODEGEN_SELECTIONDAGISEL_H | |||
#define LLVM_CODEGEN_SELECTIONDAG_ISEL_H | #define LLVM_CODEGEN_SELECTIONDAGISEL_H | |||
#include "llvm/BasicBlock.h" | ||||
#include "llvm/Pass.h" | ||||
#include "llvm/CodeGen/SelectionDAG.h" | ||||
#include "llvm/CodeGen/MachineFunctionPass.h" | #include "llvm/CodeGen/MachineFunctionPass.h" | |||
#include "llvm/CodeGen/SelectionDAG.h" | ||||
#include "llvm/IR/BasicBlock.h" | ||||
#include "llvm/Pass.h" | ||||
namespace llvm { | namespace llvm { | |||
class FastISel; | class FastISel; | |||
class SelectionDAGBuilder; | class SelectionDAGBuilder; | |||
class SDValue; | class SDValue; | |||
class MachineRegisterInfo; | class MachineRegisterInfo; | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
class MachineFunction; | class MachineFunction; | |||
class MachineInstr; | class MachineInstr; | |||
class TargetLowering; | class TargetLowering; | |||
class TargetLibraryInfo; | class TargetLibraryInfo; | |||
class TargetInstrInfo; | class TargetInstrInfo; | |||
class TargetTransformInfo; | ||||
class FunctionLoweringInfo; | class FunctionLoweringInfo; | |||
class ScheduleHazardRecognizer; | class ScheduleHazardRecognizer; | |||
class GCFunctionInfo; | class GCFunctionInfo; | |||
class ScheduleDAGSDNodes; | class ScheduleDAGSDNodes; | |||
class LoadInst; | class LoadInst; | |||
/// SelectionDAGISel - This is the common base class used for SelectionDAG- based | /// SelectionDAGISel - This is the common base class used for SelectionDAG- based | |||
/// pattern-matching instruction selectors. | /// pattern-matching instruction selectors. | |||
class SelectionDAGISel : public MachineFunctionPass { | class SelectionDAGISel : public MachineFunctionPass { | |||
public: | public: | |||
const TargetMachine &TM; | const TargetMachine &TM; | |||
const TargetLowering &TLI; | const TargetLowering &TLI; | |||
const TargetLibraryInfo *LibInfo; | const TargetLibraryInfo *LibInfo; | |||
const TargetTransformInfo *TTI; | ||||
FunctionLoweringInfo *FuncInfo; | FunctionLoweringInfo *FuncInfo; | |||
MachineFunction *MF; | MachineFunction *MF; | |||
MachineRegisterInfo *RegInfo; | MachineRegisterInfo *RegInfo; | |||
SelectionDAG *CurDAG; | SelectionDAG *CurDAG; | |||
SelectionDAGBuilder *SDB; | SelectionDAGBuilder *SDB; | |||
AliasAnalysis *AA; | AliasAnalysis *AA; | |||
GCFunctionInfo *GFI; | GCFunctionInfo *GFI; | |||
CodeGenOpt::Level OptLevel; | CodeGenOpt::Level OptLevel; | |||
static char ID; | static char ID; | |||
skipping to change at line 246 | skipping to change at line 248 | |||
SDNode *Select_INLINEASM(SDNode *N); | SDNode *Select_INLINEASM(SDNode *N); | |||
SDNode *Select_UNDEF(SDNode *N); | SDNode *Select_UNDEF(SDNode *N); | |||
void CannotYetSelect(SDNode *N); | void CannotYetSelect(SDNode *N); | |||
private: | private: | |||
void DoInstructionSelection(); | void DoInstructionSelection(); | |||
SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs, | SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs, | |||
const SDValue *Ops, unsigned NumOps, unsigned EmitNodeI nfo); | const SDValue *Ops, unsigned NumOps, unsigned EmitNodeI nfo); | |||
void PrepareEHLandingPad(); | void PrepareEHLandingPad(); | |||
/// \brief Perform instruction selection on all basic blocks in the funct | ||||
ion. | ||||
void SelectAllBasicBlocks(const Function &Fn); | void SelectAllBasicBlocks(const Function &Fn); | |||
bool TryToFoldFastISelLoad(const LoadInst *LI, const Instruction *FoldIns | ||||
t, | ||||
FastISel *FastIS); | ||||
void FinishBasicBlock(); | ||||
/// \brief Perform instruction selection on a single basic block, for | ||||
/// instructions between \p Begin and \p End. \p HadTailCall will be set | ||||
/// to true if a call in the block was translated as a tail call. | ||||
void SelectBasicBlock(BasicBlock::const_iterator Begin, | void SelectBasicBlock(BasicBlock::const_iterator Begin, | |||
BasicBlock::const_iterator End, | BasicBlock::const_iterator End, | |||
bool &HadTailCall); | bool &HadTailCall); | |||
void FinishBasicBlock(); | ||||
void CodeGenAndEmitDAG(); | void CodeGenAndEmitDAG(); | |||
void LowerArguments(const BasicBlock *BB); | ||||
/// \brief Generate instructions for lowering the incoming arguments of t | ||||
he | ||||
/// given function. | ||||
void LowerArguments(const Function &F); | ||||
void ComputeLiveOutVRegInfo(); | void ComputeLiveOutVRegInfo(); | |||
/// Create the scheduler. If a specific scheduler was specified | /// Create the scheduler. If a specific scheduler was specified | |||
/// via the SchedulerRegistry, use it, otherwise select the | /// via the SchedulerRegistry, use it, otherwise select the | |||
/// one preferred by the target. | /// one preferred by the target. | |||
/// | /// | |||
ScheduleDAGSDNodes *CreateScheduler(); | ScheduleDAGSDNodes *CreateScheduler(); | |||
/// OpcodeOffset - This is a cache used to dispatch efficiently into isel | /// OpcodeOffset - This is a cache used to dispatch efficiently into isel | |||
skipping to change at line 278 | skipping to change at line 287 | |||
void UpdateChainsAndGlue(SDNode *NodeToMatch, SDValue InputChain, | void UpdateChainsAndGlue(SDNode *NodeToMatch, SDValue InputChain, | |||
const SmallVectorImpl<SDNode*> &ChainNodesMatche d, | const SmallVectorImpl<SDNode*> &ChainNodesMatche d, | |||
SDValue InputGlue, const SmallVectorImpl<SDNode* > &F, | SDValue InputGlue, const SmallVectorImpl<SDNode* > &F, | |||
bool isMorphNodeTo); | bool isMorphNodeTo); | |||
}; | }; | |||
} | } | |||
#endif /* LLVM_CODEGEN_SELECTIONDAG_ISEL_H */ | #endif /* LLVM_CODEGEN_SELECTIONDAGISEL_H */ | |||
End of changes. 11 change blocks. | ||||
10 lines changed or deleted | 20 lines changed or added | |||
SelectionDAGNodes.h | SelectionDAGNodes.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// and operations are machine code level operations, with some similarities to | // and operations are machine code level operations, with some similarities to | |||
// the GCC RTL representation. | // the GCC RTL representation. | |||
// | // | |||
// Clients should include the SelectionDAG.h file instead of this file dire ctly. | // Clients should include the SelectionDAG.h file instead of this file dire ctly. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H | #ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H | |||
#define LLVM_CODEGEN_SELECTIONDAGNODES_H | #define LLVM_CODEGEN_SELECTIONDAGNODES_H | |||
#include "llvm/Constants.h" | ||||
#include "llvm/Instructions.h" | ||||
#include "llvm/ADT/FoldingSet.h" | #include "llvm/ADT/FoldingSet.h" | |||
#include "llvm/ADT/GraphTraits.h" | #include "llvm/ADT/GraphTraits.h" | |||
#include "llvm/ADT/ilist_node.h" | #include "llvm/ADT/STLExtras.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/STLExtras.h" | #include "llvm/ADT/ilist_node.h" | |||
#include "llvm/CodeGen/ISDOpcodes.h" | #include "llvm/CodeGen/ISDOpcodes.h" | |||
#include "llvm/CodeGen/ValueTypes.h" | ||||
#include "llvm/CodeGen/MachineMemOperand.h" | #include "llvm/CodeGen/MachineMemOperand.h" | |||
#include "llvm/Support/MathExtras.h" | #include "llvm/CodeGen/ValueTypes.h" | |||
#include "llvm/IR/Constants.h" | ||||
#include "llvm/IR/Instructions.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/DebugLoc.h" | #include "llvm/Support/DebugLoc.h" | |||
#include "llvm/Support/MathExtras.h" | ||||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
class SelectionDAG; | class SelectionDAG; | |||
class GlobalValue; | class GlobalValue; | |||
class MachineBasicBlock; | class MachineBasicBlock; | |||
class MachineConstantPoolValue; | class MachineConstantPoolValue; | |||
class SDNode; | class SDNode; | |||
class Value; | class Value; | |||
skipping to change at line 133 | skipping to change at line 133 | |||
return SDValue(Node, R); | return SDValue(Node, R); | |||
} | } | |||
// isOperandOf - Return true if this node is an operand of N. | // isOperandOf - Return true if this node is an operand of N. | |||
bool isOperandOf(SDNode *N) const; | bool isOperandOf(SDNode *N) const; | |||
/// getValueType - Return the ValueType of the referenced return value. | /// getValueType - Return the ValueType of the referenced return value. | |||
/// | /// | |||
inline EVT getValueType() const; | inline EVT getValueType() const; | |||
/// Return the simple ValueType of the referenced return value. | ||||
MVT getSimpleValueType() const { | ||||
return getValueType().getSimpleVT(); | ||||
} | ||||
/// getValueSizeInBits - Returns the size of the value in bits. | /// getValueSizeInBits - Returns the size of the value in bits. | |||
/// | /// | |||
unsigned getValueSizeInBits() const { | unsigned getValueSizeInBits() const { | |||
return getValueType().getSizeInBits(); | return getValueType().getSizeInBits(); | |||
} | } | |||
// Forwarding methods - These forward to the corresponding methods in SDN ode. | // Forwarding methods - These forward to the corresponding methods in SDN ode. | |||
inline unsigned getOpcode() const; | inline unsigned getOpcode() const; | |||
inline unsigned getNumOperands() const; | inline unsigned getNumOperands() const; | |||
inline const SDValue &getOperand(unsigned i) const; | inline const SDValue &getOperand(unsigned i) const; | |||
skipping to change at line 192 | skipping to change at line 197 | |||
static bool isEqual(const SDValue &LHS, const SDValue &RHS) { | static bool isEqual(const SDValue &LHS, const SDValue &RHS) { | |||
return LHS == RHS; | return LHS == RHS; | |||
} | } | |||
}; | }; | |||
template <> struct isPodLike<SDValue> { static const bool value = true; }; | template <> struct isPodLike<SDValue> { static const bool value = true; }; | |||
/// simplify_type specializations - Allow casting operators to work directl y on | /// simplify_type specializations - Allow casting operators to work directl y on | |||
/// SDValues as if they were SDNode*'s. | /// SDValues as if they were SDNode*'s. | |||
template<> struct simplify_type<SDValue> { | template<> struct simplify_type<SDValue> { | |||
typedef SDNode* SimpleType; | typedef SDNode* SimpleType; | |||
static SimpleType getSimplifiedValue(const SDValue &Val) { | static SimpleType getSimplifiedValue(SDValue &Val) { | |||
return static_cast<SimpleType>(Val.getNode()); | return Val.getNode(); | |||
} | } | |||
}; | }; | |||
template<> struct simplify_type<const SDValue> { | template<> struct simplify_type<const SDValue> { | |||
typedef SDNode* SimpleType; | typedef /*const*/ SDNode* SimpleType; | |||
static SimpleType getSimplifiedValue(const SDValue &Val) { | static SimpleType getSimplifiedValue(const SDValue &Val) { | |||
return static_cast<SimpleType>(Val.getNode()); | return Val.getNode(); | |||
} | } | |||
}; | }; | |||
/// SDUse - Represents a use of a SDNode. This class holds an SDValue, | /// SDUse - Represents a use of a SDNode. This class holds an SDValue, | |||
/// which records the SDNode being used and the result number, a | /// which records the SDNode being used and the result number, a | |||
/// pointer to the SDNode using the value, and Next and Prev pointers, | /// pointer to the SDNode using the value, and Next and Prev pointers, | |||
/// which link together all the uses of an SDNode. | /// which link together all the uses of an SDNode. | |||
/// | /// | |||
class SDUse { | class SDUse { | |||
/// Val - The value being used. | /// Val - The value being used. | |||
skipping to change at line 291 | skipping to change at line 296 | |||
void removeFromList() { | void removeFromList() { | |||
*Prev = Next; | *Prev = Next; | |||
if (Next) Next->Prev = Prev; | if (Next) Next->Prev = Prev; | |||
} | } | |||
}; | }; | |||
/// simplify_type specializations - Allow casting operators to work directl y on | /// simplify_type specializations - Allow casting operators to work directl y on | |||
/// SDValues as if they were SDNode*'s. | /// SDValues as if they were SDNode*'s. | |||
template<> struct simplify_type<SDUse> { | template<> struct simplify_type<SDUse> { | |||
typedef SDNode* SimpleType; | typedef SDNode* SimpleType; | |||
static SimpleType getSimplifiedValue(const SDUse &Val) { | static SimpleType getSimplifiedValue(SDUse &Val) { | |||
return static_cast<SimpleType>(Val.getNode()); | return Val.getNode(); | |||
} | ||||
}; | ||||
template<> struct simplify_type<const SDUse> { | ||||
typedef SDNode* SimpleType; | ||||
static SimpleType getSimplifiedValue(const SDUse &Val) { | ||||
return static_cast<SimpleType>(Val.getNode()); | ||||
} | } | |||
}; | }; | |||
/// SDNode - Represents one node in the SelectionDAG. | /// SDNode - Represents one node in the SelectionDAG. | |||
/// | /// | |||
class SDNode : public FoldingSetNode, public ilist_node<SDNode> { | class SDNode : public FoldingSetNode, public ilist_node<SDNode> { | |||
private: | private: | |||
/// NodeType - The operation that this node performs. | /// NodeType - The operation that this node performs. | |||
/// | /// | |||
int16_t NodeType; | int16_t NodeType; | |||
skipping to change at line 594 | skipping to change at line 593 | |||
/// | /// | |||
unsigned getNumValues() const { return NumValues; } | unsigned getNumValues() const { return NumValues; } | |||
/// getValueType - Return the type of a specified result. | /// getValueType - Return the type of a specified result. | |||
/// | /// | |||
EVT getValueType(unsigned ResNo) const { | EVT getValueType(unsigned ResNo) const { | |||
assert(ResNo < NumValues && "Illegal result number!"); | assert(ResNo < NumValues && "Illegal result number!"); | |||
return ValueList[ResNo]; | return ValueList[ResNo]; | |||
} | } | |||
/// Return the type of a specified result as a simple type. | ||||
/// | ||||
MVT getSimpleValueType(unsigned ResNo) const { | ||||
return getValueType(ResNo).getSimpleVT(); | ||||
} | ||||
/// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType(ResNo)). | /// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType(ResNo)). | |||
/// | /// | |||
unsigned getValueSizeInBits(unsigned ResNo) const { | unsigned getValueSizeInBits(unsigned ResNo) const { | |||
return getValueType(ResNo).getSizeInBits(); | return getValueType(ResNo).getSizeInBits(); | |||
} | } | |||
typedef const EVT* value_iterator; | typedef const EVT* value_iterator; | |||
value_iterator value_begin() const { return ValueList; } | value_iterator value_begin() const { return ValueList; } | |||
value_iterator value_end() const { return ValueList+NumValues; } | value_iterator value_end() const { return ValueList+NumValues; } | |||
skipping to change at line 1283 | skipping to change at line 1288 | |||
} Val; | } Val; | |||
int Offset; // It's a MachineConstantPoolValue if top bit is set. | int Offset; // It's a MachineConstantPoolValue if top bit is set. | |||
unsigned Alignment; // Minimum alignment requirement of CP (not log2 val ue). | unsigned Alignment; // Minimum alignment requirement of CP (not log2 val ue). | |||
unsigned char TargetFlags; | unsigned char TargetFlags; | |||
friend class SelectionDAG; | friend class SelectionDAG; | |||
ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o, | ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o, | |||
unsigned Align, unsigned char TF) | unsigned Align, unsigned char TF) | |||
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, | : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, | |||
DebugLoc(), | DebugLoc(), | |||
getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { | getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { | |||
assert((int)Offset >= 0 && "Offset is too large"); | assert(Offset >= 0 && "Offset is too large"); | |||
Val.ConstVal = c; | Val.ConstVal = c; | |||
} | } | |||
ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, | ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, | |||
EVT VT, int o, unsigned Align, unsigned char TF) | EVT VT, int o, unsigned Align, unsigned char TF) | |||
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, | : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, | |||
DebugLoc(), | DebugLoc(), | |||
getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { | getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { | |||
assert((int)Offset >= 0 && "Offset is too large"); | assert(Offset >= 0 && "Offset is too large"); | |||
Val.MachineCPVal = v; | Val.MachineCPVal = v; | |||
Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1); | Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1); | |||
} | } | |||
public: | public: | |||
bool isMachineConstantPoolEntry() const { | bool isMachineConstantPoolEntry() const { | |||
return (int)Offset < 0; | return Offset < 0; | |||
} | } | |||
const Constant *getConstVal() const { | const Constant *getConstVal() const { | |||
assert(!isMachineConstantPoolEntry() && "Wrong constantpool type"); | assert(!isMachineConstantPoolEntry() && "Wrong constantpool type"); | |||
return Val.ConstVal; | return Val.ConstVal; | |||
} | } | |||
MachineConstantPoolValue *getMachineCPVal() const { | MachineConstantPoolValue *getMachineCPVal() const { | |||
assert(isMachineConstantPoolEntry() && "Wrong constantpool type"); | assert(isMachineConstantPoolEntry() && "Wrong constantpool type"); | |||
return Val.MachineCPVal; | return Val.MachineCPVal; | |||
End of changes. 15 change blocks. | ||||
21 lines changed or deleted | 26 lines changed or added | |||
Signals.h | Signals.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines some helpful functions for dealing with the possibilit y of | // This file defines some helpful functions for dealing with the possibilit y of | |||
// unix signals occurring while your program is running. | // unix signals occurring while your program is running. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_SIGNALS_H | #ifndef LLVM_SUPPORT_SIGNALS_H | |||
#define LLVM_SYSTEM_SIGNALS_H | #define LLVM_SUPPORT_SIGNALS_H | |||
#include "llvm/Support/Path.h" | #include "llvm/Support/Path.h" | |||
#include <cstdio> | ||||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
/// This function runs all the registered interrupt handlers, including t he | /// This function runs all the registered interrupt handlers, including t he | |||
/// removal of files registered by RemoveFileOnSignal. | /// removal of files registered by RemoveFileOnSignal. | |||
void RunInterruptHandlers(); | void RunInterruptHandlers(); | |||
/// This function registers signal handlers to ensure that if a signal ge ts | /// This function registers signal handlers to ensure that if a signal ge ts | |||
/// delivered that the named file is removed. | /// delivered that the named file is removed. | |||
skipping to change at line 41 | skipping to change at line 42 | |||
/// This function removes a file from the list of files to be removed on | /// This function removes a file from the list of files to be removed on | |||
/// signal delivery. | /// signal delivery. | |||
void DontRemoveFileOnSignal(const Path &Filename); | void DontRemoveFileOnSignal(const Path &Filename); | |||
/// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the | /// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the | |||
/// process, print a stack trace and then exit. | /// process, print a stack trace and then exit. | |||
/// @brief Print a stack trace if a fatal signal occurs. | /// @brief Print a stack trace if a fatal signal occurs. | |||
void PrintStackTraceOnErrorSignal(); | void PrintStackTraceOnErrorSignal(); | |||
/// \brief Print the stack trace using the given \c FILE object. | ||||
void PrintStackTrace(FILE *); | ||||
/// AddSignalHandler - Add a function to be called when an abort/kill sig nal | /// AddSignalHandler - Add a function to be called when an abort/kill sig nal | |||
/// is delivered to the process. The handler can have a cookie passed to it | /// is delivered to the process. The handler can have a cookie passed to it | |||
/// to identify what instance of the handler it is. | /// to identify what instance of the handler it is. | |||
void AddSignalHandler(void (*FnPtr)(void *), void *Cookie); | void AddSignalHandler(void (*FnPtr)(void *), void *Cookie); | |||
/// This function registers a function to be called when the user "interr upts" | /// This function registers a function to be called when the user "interr upts" | |||
/// the program (typically by pressing ctrl-c). When the user interrupts the | /// the program (typically by pressing ctrl-c). When the user interrupts the | |||
/// program, the specified interrupt function is called instead of the pr ogram | /// program, the specified interrupt function is called instead of the pr ogram | |||
/// being killed, and the interrupt function automatically disabled. Not e | /// being killed, and the interrupt function automatically disabled. Not e | |||
/// that interrupt functions are not allowed to call any non-reentrant | /// that interrupt functions are not allowed to call any non-reentrant | |||
End of changes. 3 change blocks. | ||||
2 lines changed or deleted | 6 lines changed or added | |||
SimplifyLibCalls.h | SimplifyLibCalls.h | |||
---|---|---|---|---|
skipping to change at line 34 | skipping to change at line 34 | |||
class LibCallSimplifierImpl; | class LibCallSimplifierImpl; | |||
/// LibCallSimplifier - This class implements a collection of optimizatio ns | /// LibCallSimplifier - This class implements a collection of optimizatio ns | |||
/// that replace well formed calls to library functions with a more optim al | /// that replace well formed calls to library functions with a more optim al | |||
/// form. For example, replacing 'printf("Hello!")' with 'puts("Hello!") '. | /// form. For example, replacing 'printf("Hello!")' with 'puts("Hello!") '. | |||
class LibCallSimplifier { | class LibCallSimplifier { | |||
/// Impl - A pointer to the actual implementation of the library call | /// Impl - A pointer to the actual implementation of the library call | |||
/// simplifier. | /// simplifier. | |||
LibCallSimplifierImpl *Impl; | LibCallSimplifierImpl *Impl; | |||
public: | public: | |||
LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI); | LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI, | |||
bool UnsafeFPShrink); | ||||
virtual ~LibCallSimplifier(); | virtual ~LibCallSimplifier(); | |||
/// optimizeCall - Take the given call instruction and return a more | /// optimizeCall - Take the given call instruction and return a more | |||
/// optimal value to replace the instruction with or 0 if a more | /// optimal value to replace the instruction with or 0 if a more | |||
/// optimal form can't be found. Note that the returned value may | /// optimal form can't be found. Note that the returned value may | |||
/// be equal to the instruction being optimized. In this case all | /// be equal to the instruction being optimized. In this case all | |||
/// other instructions that use the given instruction were modified | /// other instructions that use the given instruction were modified | |||
/// and the given instruction is dead. | /// and the given instruction is dead. | |||
Value *optimizeCall(CallInst *CI); | Value *optimizeCall(CallInst *CI); | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 2 lines changed or added | |||
SlotIndexes.h | SlotIndexes.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// be live. | // be live. | |||
// | // | |||
// SlotIndex is mostly a proxy for entries of the SlotIndexList, a class wh ich | // SlotIndex is mostly a proxy for entries of the SlotIndexList, a class wh ich | |||
// is held is LiveIntervals and provides the real numbering. This allows | // is held is LiveIntervals and provides the real numbering. This allows | |||
// LiveIntervals to perform largely transparent renumbering. | // LiveIntervals to perform largely transparent renumbering. | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_SLOTINDEXES_H | #ifndef LLVM_CODEGEN_SLOTINDEXES_H | |||
#define LLVM_CODEGEN_SLOTINDEXES_H | #define LLVM_CODEGEN_SLOTINDEXES_H | |||
#include "llvm/CodeGen/MachineInstrBundle.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/CodeGen/MachineFunction.h" | #include "llvm/ADT/IntervalMap.h" | |||
#include "llvm/CodeGen/MachineFunctionPass.h" | ||||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/ADT/ilist.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/ilist.h" | |||
#include "llvm/CodeGen/MachineFunction.h" | ||||
#include "llvm/CodeGen/MachineFunctionPass.h" | ||||
#include "llvm/CodeGen/MachineInstrBundle.h" | ||||
#include "llvm/Support/Allocator.h" | #include "llvm/Support/Allocator.h" | |||
namespace llvm { | namespace llvm { | |||
/// This class represents an entry in the slot index list held in the | /// This class represents an entry in the slot index list held in the | |||
/// SlotIndexes pass. It should not be used directly. See the | /// SlotIndexes pass. It should not be used directly. See the | |||
/// SlotIndex & SlotIndexes classes for the public interface to this | /// SlotIndex & SlotIndexes classes for the public interface to this | |||
/// information. | /// information. | |||
class IndexListEntry : public ilist_node<IndexListEntry> { | class IndexListEntry : public ilist_node<IndexListEntry> { | |||
MachineInstr *mi; | MachineInstr *mi; | |||
skipping to change at line 55 | skipping to change at line 56 | |||
MachineInstr* getInstr() const { return mi; } | MachineInstr* getInstr() const { return mi; } | |||
void setInstr(MachineInstr *mi) { | void setInstr(MachineInstr *mi) { | |||
this->mi = mi; | this->mi = mi; | |||
} | } | |||
unsigned getIndex() const { return index; } | unsigned getIndex() const { return index; } | |||
void setIndex(unsigned index) { | void setIndex(unsigned index) { | |||
this->index = index; | this->index = index; | |||
} | } | |||
#ifdef EXPENSIVE_CHECKS | ||||
// When EXPENSIVE_CHECKS is defined, "erased" index list entries will | ||||
// actually be moved to a "graveyard" list, and have their pointers | ||||
// 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?"); | ||||
tmp |= 0x1; | ||||
mi = reinterpret_cast<MachineInstr*>(tmp); | ||||
} | ||||
bool isPoisoned() const { return (reinterpret_cast<intptr_t>(mi) & 0x1) | ||||
== 0x1; } | ||||
#endif // EXPENSIVE_CHECKS | ||||
}; | }; | |||
template <> | template <> | |||
struct ilist_traits<IndexListEntry> : public ilist_default_traits<IndexLi stEntry> { | struct ilist_traits<IndexListEntry> : public ilist_default_traits<IndexLi stEntry> { | |||
private: | private: | |||
mutable ilist_half_node<IndexListEntry> Sentinel; | mutable ilist_half_node<IndexListEntry> Sentinel; | |||
public: | public: | |||
IndexListEntry *createSentinel() const { | IndexListEntry *createSentinel() const { | |||
return static_cast<IndexListEntry*>(&Sentinel); | return static_cast<IndexListEntry*>(&Sentinel); | |||
} | } | |||
skipping to change at line 111 | skipping to change at line 126 | |||
Slot_Count | Slot_Count | |||
}; | }; | |||
PointerIntPair<IndexListEntry*, 2, unsigned> lie; | PointerIntPair<IndexListEntry*, 2, unsigned> lie; | |||
SlotIndex(IndexListEntry *entry, unsigned slot) | SlotIndex(IndexListEntry *entry, unsigned slot) | |||
: lie(entry, slot) {} | : lie(entry, slot) {} | |||
IndexListEntry* listEntry() const { | IndexListEntry* listEntry() const { | |||
assert(isValid() && "Attempt to compare reserved index."); | assert(isValid() && "Attempt to compare reserved index."); | |||
#ifdef EXPENSIVE_CHECKS | ||||
assert(!lie.getPointer()->isPoisoned() && | ||||
"Attempt to access deleted list-entry."); | ||||
#endif // EXPENSIVE_CHECKS | ||||
return lie.getPointer(); | return lie.getPointer(); | |||
} | } | |||
int getIndex() const { | unsigned getIndex() const { | |||
return listEntry()->getIndex() | getSlot(); | return listEntry()->getIndex() | getSlot(); | |||
} | } | |||
/// Returns the slot for this SlotIndex. | /// Returns the slot for this SlotIndex. | |||
Slot getSlot() const { | Slot getSlot() const { | |||
return static_cast<Slot>(lie.getInt()); | return static_cast<Slot>(lie.getInt()); | |||
} | } | |||
public: | public: | |||
enum { | enum { | |||
skipping to change at line 314 | skipping to change at line 333 | |||
/// SlotIndexes pass. | /// SlotIndexes pass. | |||
/// | /// | |||
/// This pass assigns indexes to each instruction. | /// This pass assigns indexes to each instruction. | |||
class SlotIndexes : public MachineFunctionPass { | class SlotIndexes : public MachineFunctionPass { | |||
private: | private: | |||
typedef ilist<IndexListEntry> IndexList; | typedef ilist<IndexListEntry> IndexList; | |||
IndexList indexList; | IndexList indexList; | |||
#ifdef EXPENSIVE_CHECKS | ||||
IndexList graveyardList; | ||||
#endif // EXPENSIVE_CHECKS | ||||
MachineFunction *mf; | MachineFunction *mf; | |||
typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap; | typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap; | |||
Mi2IndexMap mi2iMap; | Mi2IndexMap mi2iMap; | |||
/// MBBRanges - Map MBB number to (start, stop) indexes. | /// MBBRanges - Map MBB number to (start, stop) indexes. | |||
SmallVector<std::pair<SlotIndex, SlotIndex>, 8> MBBRanges; | SmallVector<std::pair<SlotIndex, SlotIndex>, 8> MBBRanges; | |||
/// Idx2MBBMap - Sorted list of pairs of index of first instruction | /// Idx2MBBMap - Sorted list of pairs of index of first instruction | |||
/// and MBB id. | /// and MBB id. | |||
skipping to change at line 361 | skipping to change at line 384 | |||
virtual void releaseMemory(); | virtual void releaseMemory(); | |||
virtual bool runOnMachineFunction(MachineFunction &fn); | virtual bool runOnMachineFunction(MachineFunction &fn); | |||
/// Dump the indexes. | /// Dump the indexes. | |||
void dump() const; | void dump() const; | |||
/// Renumber the index list, providing space for new instructions. | /// Renumber the index list, providing space for new instructions. | |||
void renumberIndexes(); | void renumberIndexes(); | |||
/// Repair indexes after adding and removing instructions. | ||||
void repairIndexesInRange(MachineBasicBlock *MBB, | ||||
MachineBasicBlock::iterator Begin, | ||||
MachineBasicBlock::iterator End); | ||||
/// Returns the zero index for this analysis. | /// Returns the zero index for this analysis. | |||
SlotIndex getZeroIndex() { | SlotIndex getZeroIndex() { | |||
assert(indexList.front().getIndex() == 0 && "First index is not 0?"); | assert(indexList.front().getIndex() == 0 && "First index is not 0?"); | |||
return SlotIndex(&indexList.front(), 0); | return SlotIndex(&indexList.front(), 0); | |||
} | } | |||
/// Returns the base index of the last slot in this analysis. | /// Returns the base index of the last slot in this analysis. | |||
SlotIndex getLastIndex() { | SlotIndex getLastIndex() { | |||
return SlotIndex(&indexList.back(), 0); | return SlotIndex(&indexList.back(), 0); | |||
} | } | |||
skipping to change at line 392 | skipping to change at line 420 | |||
assert(itr != mi2iMap.end() && "Instruction not found in maps."); | assert(itr != mi2iMap.end() && "Instruction not found in maps."); | |||
return itr->second; | return itr->second; | |||
} | } | |||
/// Returns the instruction for the given index, or null if the given | /// Returns the instruction for the given index, or null if the given | |||
/// index has no instruction associated with it. | /// index has no instruction associated with it. | |||
MachineInstr* getInstructionFromIndex(SlotIndex index) const { | MachineInstr* getInstructionFromIndex(SlotIndex index) const { | |||
return index.isValid() ? index.listEntry()->getInstr() : 0; | return index.isValid() ? index.listEntry()->getInstr() : 0; | |||
} | } | |||
/// Returns the next non-null index. | /// Returns the next non-null index, if one exists. | |||
SlotIndex getNextNonNullIndex(SlotIndex index) { | /// Otherwise returns getLastIndex(). | |||
IndexList::iterator itr(index.listEntry()); | SlotIndex getNextNonNullIndex(SlotIndex Index) { | |||
++itr; | IndexList::iterator I = Index.listEntry(); | |||
while (itr != indexList.end() && itr->getInstr() == 0) { ++itr; } | IndexList::iterator E = indexList.end(); | |||
return SlotIndex(itr, index.getSlot()); | while (++I != E) | |||
if (I->getInstr()) | ||||
return SlotIndex(I, Index.getSlot()); | ||||
// We reached the end of the function. | ||||
return getLastIndex(); | ||||
} | } | |||
/// getIndexBefore - Returns the index of the last indexed instruction | /// getIndexBefore - Returns the index of the last indexed instruction | |||
/// before MI, or the start index of its basic block. | /// before MI, or the start index of its basic block. | |||
/// MI is not required to have an index. | /// MI is not required to have an index. | |||
SlotIndex getIndexBefore(const MachineInstr *MI) const { | SlotIndex getIndexBefore(const MachineInstr *MI) const { | |||
const MachineBasicBlock *MBB = MI->getParent(); | const MachineBasicBlock *MBB = MI->getParent(); | |||
assert(MBB && "MI must be inserted inna basic block"); | assert(MBB && "MI must be inserted inna basic block"); | |||
MachineBasicBlock::const_iterator I = MI, B = MBB->begin(); | MachineBasicBlock::const_iterator I = MI, B = MBB->begin(); | |||
for (;;) { | for (;;) { | |||
skipping to change at line 603 | skipping to change at line 635 | |||
"Mismatched instruction in index tables."); | "Mismatched instruction in index tables."); | |||
miEntry->setInstr(newMI); | miEntry->setInstr(newMI); | |||
mi2iMap.erase(mi2iItr); | mi2iMap.erase(mi2iItr); | |||
mi2iMap.insert(std::make_pair(newMI, replaceBaseIndex)); | mi2iMap.insert(std::make_pair(newMI, replaceBaseIndex)); | |||
} | } | |||
/// Add the given MachineBasicBlock into the maps. | /// Add the given MachineBasicBlock into the maps. | |||
void insertMBBInMaps(MachineBasicBlock *mbb) { | void insertMBBInMaps(MachineBasicBlock *mbb) { | |||
MachineFunction::iterator nextMBB = | MachineFunction::iterator nextMBB = | |||
llvm::next(MachineFunction::iterator(mbb)); | llvm::next(MachineFunction::iterator(mbb)); | |||
IndexListEntry *startEntry = createEntry(0, 0); | ||||
IndexListEntry *stopEntry = createEntry(0, 0); | ||||
IndexListEntry *nextEntry = 0; | ||||
IndexListEntry *startEntry = 0; | ||||
IndexListEntry *endEntry = 0; | ||||
IndexList::iterator newItr; | ||||
if (nextMBB == mbb->getParent()->end()) { | if (nextMBB == mbb->getParent()->end()) { | |||
nextEntry = indexList.end(); | startEntry = &indexList.back(); | |||
endEntry = createEntry(0, 0); | ||||
newItr = indexList.insertAfter(startEntry, endEntry); | ||||
} else { | } else { | |||
nextEntry = getMBBStartIdx(nextMBB).listEntry(); | startEntry = createEntry(0, 0); | |||
endEntry = getMBBStartIdx(nextMBB).listEntry(); | ||||
newItr = indexList.insert(endEntry, startEntry); | ||||
} | } | |||
indexList.insert(nextEntry, startEntry); | ||||
indexList.insert(nextEntry, stopEntry); | ||||
SlotIndex startIdx(startEntry, SlotIndex::Slot_Block); | SlotIndex startIdx(startEntry, SlotIndex::Slot_Block); | |||
SlotIndex endIdx(nextEntry, SlotIndex::Slot_Block); | SlotIndex endIdx(endEntry, SlotIndex::Slot_Block); | |||
MachineFunction::iterator prevMBB(mbb); | ||||
assert(prevMBB != mbb->getParent()->end() && | ||||
"Can't insert a new block at the beginning of a function."); | ||||
--prevMBB; | ||||
MBBRanges[prevMBB->getNumber()].second = startIdx; | ||||
assert(unsigned(mbb->getNumber()) == MBBRanges.size() && | assert(unsigned(mbb->getNumber()) == MBBRanges.size() && | |||
"Blocks must be added in order"); | "Blocks must be added in order"); | |||
MBBRanges.push_back(std::make_pair(startIdx, endIdx)); | MBBRanges.push_back(std::make_pair(startIdx, endIdx)); | |||
idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb)); | idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb)); | |||
renumberIndexes(); | renumberIndexes(newItr); | |||
std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); | std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); | |||
} | } | |||
/// \brief Free the resources that were required to maintain a SlotInde | ||||
x. | ||||
/// | ||||
/// Once an index is no longer needed (for instance because the instruc | ||||
tion | ||||
/// at that index has been moved), the resources required to maintain t | ||||
he | ||||
/// index can be relinquished to reduce memory use and improve renumber | ||||
ing | ||||
/// 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 SlotInde | ||||
x | ||||
/// bugs, build with EXPENSIVE_CHECKS=1. This will cause "erased" index | ||||
es to | ||||
/// be retained in a graveyard instead of being freed. Operations on in | ||||
dexes | ||||
/// in the graveyard will trigger an assertion. | ||||
void eraseIndex(SlotIndex index) { | ||||
IndexListEntry *entry = index.listEntry(); | ||||
#ifdef EXPENSIVE_CHECKS | ||||
indexList.remove(entry); | ||||
graveyardList.push_back(entry); | ||||
entry->setPoison(); | ||||
#else | ||||
indexList.erase(entry); | ||||
#endif | ||||
} | ||||
}; | }; | |||
// Specialize IntervalMapInfo for half-open slot index intervals. | // Specialize IntervalMapInfo for half-open slot index intervals. | |||
template <typename> struct IntervalMapInfo; | template <> | |||
template <> struct IntervalMapInfo<SlotIndex> { | struct IntervalMapInfo<SlotIndex> : IntervalMapHalfOpenInfo<SlotIndex> { | |||
static inline bool startLess(const SlotIndex &x, const SlotIndex &a) { | ||||
return x < a; | ||||
} | ||||
static inline bool stopLess(const SlotIndex &b, const SlotIndex &x) { | ||||
return b <= x; | ||||
} | ||||
static inline bool adjacent(const SlotIndex &a, const SlotIndex &b) { | ||||
return a == b; | ||||
} | ||||
}; | }; | |||
} | } | |||
#endif // LLVM_CODEGEN_SLOTINDEXES_H | #endif // LLVM_CODEGEN_SLOTINDEXES_H | |||
End of changes. 19 change blocks. | ||||
34 lines changed or deleted | 98 lines changed or added | |||
SmallBitVector.h | SmallBitVector.h | |||
---|---|---|---|---|
skipping to change at line 156 | skipping to change at line 156 | |||
} | } | |||
/// SmallBitVector copy ctor. | /// SmallBitVector copy ctor. | |||
SmallBitVector(const SmallBitVector &RHS) { | SmallBitVector(const SmallBitVector &RHS) { | |||
if (RHS.isSmall()) | if (RHS.isSmall()) | |||
X = RHS.X; | X = RHS.X; | |||
else | else | |||
switchToLarge(new BitVector(*RHS.getPointer())); | switchToLarge(new BitVector(*RHS.getPointer())); | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) { | SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) { | |||
RHS.X = 1; | RHS.X = 1; | |||
} | } | |||
#endif | #endif | |||
~SmallBitVector() { | ~SmallBitVector() { | |||
if (!isSmall()) | if (!isSmall()) | |||
delete getPointer(); | delete getPointer(); | |||
} | } | |||
skipping to change at line 181 | skipping to change at line 181 | |||
/// size - Returns the number of bits in this bitvector. | /// size - Returns the number of bits in this bitvector. | |||
size_t size() const { | size_t size() const { | |||
return isSmall() ? getSmallSize() : getPointer()->size(); | return isSmall() ? getSmallSize() : getPointer()->size(); | |||
} | } | |||
/// count - Returns the number of bits which are set. | /// count - Returns the number of bits which are set. | |||
unsigned count() const { | unsigned count() const { | |||
if (isSmall()) { | if (isSmall()) { | |||
uintptr_t Bits = getSmallBits(); | uintptr_t Bits = getSmallBits(); | |||
if (sizeof(uintptr_t) * CHAR_BIT == 32) | if (NumBaseBits == 32) | |||
return CountPopulation_32(Bits); | return CountPopulation_32(Bits); | |||
if (sizeof(uintptr_t) * CHAR_BIT == 64) | if (NumBaseBits == 64) | |||
return CountPopulation_64(Bits); | return CountPopulation_64(Bits); | |||
llvm_unreachable("Unsupported!"); | llvm_unreachable("Unsupported!"); | |||
} | } | |||
return getPointer()->count(); | return getPointer()->count(); | |||
} | } | |||
/// any - Returns true if any bit is set. | /// any - Returns true if any bit is set. | |||
bool any() const { | bool any() const { | |||
if (isSmall()) | if (isSmall()) | |||
return getSmallBits() != 0; | return getSmallBits() != 0; | |||
skipping to change at line 218 | skipping to change at line 218 | |||
return getPointer()->none(); | return getPointer()->none(); | |||
} | } | |||
/// find_first - Returns the index of the first set bit, -1 if none | /// find_first - Returns the index of the first set bit, -1 if none | |||
/// of the bits are set. | /// of the bits are set. | |||
int find_first() const { | int find_first() const { | |||
if (isSmall()) { | if (isSmall()) { | |||
uintptr_t Bits = getSmallBits(); | uintptr_t Bits = getSmallBits(); | |||
if (Bits == 0) | if (Bits == 0) | |||
return -1; | return -1; | |||
if (sizeof(uintptr_t) * CHAR_BIT == 32) | if (NumBaseBits == 32) | |||
return CountTrailingZeros_32(Bits); | return CountTrailingZeros_32(Bits); | |||
if (sizeof(uintptr_t) * CHAR_BIT == 64) | if (NumBaseBits == 64) | |||
return CountTrailingZeros_64(Bits); | return CountTrailingZeros_64(Bits); | |||
llvm_unreachable("Unsupported!"); | llvm_unreachable("Unsupported!"); | |||
} | } | |||
return getPointer()->find_first(); | return getPointer()->find_first(); | |||
} | } | |||
/// find_next - Returns the index of the next set bit following the | /// find_next - Returns the index of the next set bit following the | |||
/// "Prev" bit. Returns -1 if the next set bit is not found. | /// "Prev" bit. Returns -1 if the next set bit is not found. | |||
int find_next(unsigned Prev) const { | int find_next(unsigned Prev) const { | |||
if (isSmall()) { | if (isSmall()) { | |||
uintptr_t Bits = getSmallBits(); | uintptr_t Bits = getSmallBits(); | |||
// Mask off previous bits. | // Mask off previous bits. | |||
Bits &= ~uintptr_t(0) << (Prev + 1); | Bits &= ~uintptr_t(0) << (Prev + 1); | |||
if (Bits == 0 || Prev + 1 >= getSmallSize()) | if (Bits == 0 || Prev + 1 >= getSmallSize()) | |||
return -1; | return -1; | |||
if (sizeof(uintptr_t) * CHAR_BIT == 32) | if (NumBaseBits == 32) | |||
return CountTrailingZeros_32(Bits); | return CountTrailingZeros_32(Bits); | |||
if (sizeof(uintptr_t) * CHAR_BIT == 64) | if (NumBaseBits == 64) | |||
return CountTrailingZeros_64(Bits); | return CountTrailingZeros_64(Bits); | |||
llvm_unreachable("Unsupported!"); | llvm_unreachable("Unsupported!"); | |||
} | } | |||
return getPointer()->find_next(Prev); | return getPointer()->find_next(Prev); | |||
} | } | |||
/// clear - Clear all bits. | /// clear - Clear all bits. | |||
void clear() { | void clear() { | |||
if (!isSmall()) | if (!isSmall()) | |||
delete getPointer(); | delete getPointer(); | |||
skipping to change at line 475 | skipping to change at line 475 | |||
if (!RHS.isSmall()) | if (!RHS.isSmall()) | |||
*getPointer() = *RHS.getPointer(); | *getPointer() = *RHS.getPointer(); | |||
else { | else { | |||
delete getPointer(); | delete getPointer(); | |||
X = RHS.X; | X = RHS.X; | |||
} | } | |||
} | } | |||
return *this; | return *this; | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
const SmallBitVector &operator=(SmallBitVector &&RHS) { | const SmallBitVector &operator=(SmallBitVector &&RHS) { | |||
if (this != &RHS) { | if (this != &RHS) { | |||
clear(); | clear(); | |||
swap(RHS); | swap(RHS); | |||
} | } | |||
return *this; | return *this; | |||
} | } | |||
#endif | #endif | |||
void swap(SmallBitVector &RHS) { | void swap(SmallBitVector &RHS) { | |||
End of changes. 8 change blocks. | ||||
8 lines changed or deleted | 8 lines changed or added | |||
SmallPtrSet.h | SmallPtrSet.h | |||
---|---|---|---|---|
skipping to change at line 57 | skipping to change at line 57 | |||
/// | /// | |||
class SmallPtrSetImpl { | class SmallPtrSetImpl { | |||
friend class SmallPtrSetIteratorImpl; | friend class SmallPtrSetIteratorImpl; | |||
protected: | protected: | |||
/// SmallArray - Points to a fixed size set of buckets, used in 'small mo de'. | /// SmallArray - Points to a fixed size set of buckets, used in 'small mo de'. | |||
const void **SmallArray; | const void **SmallArray; | |||
/// CurArray - This is the current set of buckets. If equal to SmallArra y, | /// CurArray - This is the current set of buckets. If equal to SmallArra y, | |||
/// then the set is in 'small mode'. | /// then the set is in 'small mode'. | |||
const void **CurArray; | const void **CurArray; | |||
/// CurArraySize - The allocated size of CurArray, always a power of two. | /// CurArraySize - The allocated size of CurArray, always a power of two. | |||
/// Note that CurArray points to an array that has CurArraySize+1 element | ||||
s in | ||||
/// it, so that the end iterator actually points to valid memory. | ||||
unsigned CurArraySize; | unsigned CurArraySize; | |||
// If small, this is # elts allocated consecutively | // If small, this is # elts allocated consecutively | |||
unsigned NumElements; | unsigned NumElements; | |||
unsigned NumTombstones; | unsigned NumTombstones; | |||
// Helper to copy construct a SmallPtrSet. | // Helper to copy construct a SmallPtrSet. | |||
SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl& that); | SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl& that); | |||
explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize) : | explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize) : | |||
SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSiz e) { | SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSiz e) { | |||
assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 && | assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 && | |||
"Initial size must be a power of two!"); | "Initial size must be a power of two!"); | |||
// The end pointer, always valid, is set to a valid element to help the | ||||
// iterator. | ||||
CurArray[SmallSize] = 0; | ||||
clear(); | clear(); | |||
} | } | |||
~SmallPtrSetImpl(); | ~SmallPtrSetImpl(); | |||
public: | public: | |||
bool empty() const { return size() == 0; } | bool empty() const { return size() == 0; } | |||
unsigned size() const { return NumElements; } | unsigned size() const { return NumElements; } | |||
void clear() { | void clear() { | |||
// If the capacity of the array is huge, and the # elements used is sma ll, | // If the capacity of the array is huge, and the # elements used is sma ll, | |||
skipping to change at line 150 | skipping to change at line 145 | |||
void swap(SmallPtrSetImpl &RHS); | void swap(SmallPtrSetImpl &RHS); | |||
void CopyFrom(const SmallPtrSetImpl &RHS); | void CopyFrom(const SmallPtrSetImpl &RHS); | |||
}; | }; | |||
/// SmallPtrSetIteratorImpl - This is the common base class shared between all | /// SmallPtrSetIteratorImpl - This is the common base class shared between all | |||
/// instances of SmallPtrSetIterator. | /// instances of SmallPtrSetIterator. | |||
class SmallPtrSetIteratorImpl { | class SmallPtrSetIteratorImpl { | |||
protected: | protected: | |||
const void *const *Bucket; | const void *const *Bucket; | |||
const void *const *End; | ||||
public: | public: | |||
explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) { | explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const | |||
AdvanceIfNotValid(); | *E) | |||
: Bucket(BP), End(E) { | ||||
AdvanceIfNotValid(); | ||||
} | } | |||
bool operator==(const SmallPtrSetIteratorImpl &RHS) const { | bool operator==(const SmallPtrSetIteratorImpl &RHS) const { | |||
return Bucket == RHS.Bucket; | return Bucket == RHS.Bucket; | |||
} | } | |||
bool operator!=(const SmallPtrSetIteratorImpl &RHS) const { | bool operator!=(const SmallPtrSetIteratorImpl &RHS) const { | |||
return Bucket != RHS.Bucket; | return Bucket != RHS.Bucket; | |||
} | } | |||
protected: | protected: | |||
/// AdvanceIfNotValid - If the current bucket isn't valid, advance to a b ucket | /// AdvanceIfNotValid - If the current bucket isn't valid, advance to a b ucket | |||
/// that is. This is guaranteed to stop because the end() bucket is mar ked | /// that is. This is guaranteed to stop because the end() bucket is mar ked | |||
/// valid. | /// valid. | |||
void AdvanceIfNotValid() { | void AdvanceIfNotValid() { | |||
while (*Bucket == SmallPtrSetImpl::getEmptyMarker() || | assert(Bucket <= End); | |||
*Bucket == SmallPtrSetImpl::getTombstoneMarker()) | while (Bucket != End && | |||
(*Bucket == SmallPtrSetImpl::getEmptyMarker() || | ||||
*Bucket == SmallPtrSetImpl::getTombstoneMarker())) | ||||
++Bucket; | ++Bucket; | |||
} | } | |||
}; | }; | |||
/// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet. | /// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet. | |||
template<typename PtrTy> | template<typename PtrTy> | |||
class SmallPtrSetIterator : public SmallPtrSetIteratorImpl { | class SmallPtrSetIterator : public SmallPtrSetIteratorImpl { | |||
typedef PointerLikeTypeTraits<PtrTy> PtrTraits; | typedef PointerLikeTypeTraits<PtrTy> PtrTraits; | |||
public: | public: | |||
typedef PtrTy value_type; | typedef PtrTy value_type; | |||
typedef PtrTy reference; | typedef PtrTy reference; | |||
typedef PtrTy pointer; | typedef PtrTy pointer; | |||
typedef std::ptrdiff_t difference_type; | typedef std::ptrdiff_t difference_type; | |||
typedef std::forward_iterator_tag iterator_category; | typedef std::forward_iterator_tag iterator_category; | |||
explicit SmallPtrSetIterator(const void *const *BP) | explicit SmallPtrSetIterator(const void *const *BP, const void *const *E) | |||
: SmallPtrSetIteratorImpl(BP) {} | : SmallPtrSetIteratorImpl(BP, E) {} | |||
// Most methods provided by baseclass. | // Most methods provided by baseclass. | |||
const PtrTy operator*() const { | const PtrTy operator*() const { | |||
assert(Bucket < End); | ||||
return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket)); | return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket)); | |||
} | } | |||
inline SmallPtrSetIterator& operator++() { // Preincrement | inline SmallPtrSetIterator& operator++() { // Preincrement | |||
++Bucket; | ++Bucket; | |||
AdvanceIfNotValid(); | AdvanceIfNotValid(); | |||
return *this; | return *this; | |||
} | } | |||
SmallPtrSetIterator operator++(int) { // Postincrement | SmallPtrSetIterator operator++(int) { // Postincrement | |||
skipping to change at line 238 | skipping to change at line 238 | |||
}; | }; | |||
/// SmallPtrSet - This class implements a set which is optimized for holdin g | /// SmallPtrSet - This class implements a set which is optimized for holdin g | |||
/// SmallSize or less elements. This internally rounds up SmallSize to the next | /// SmallSize or less elements. This internally rounds up SmallSize to the next | |||
/// power of two if it is not already a power of two. See the comments abo ve | /// power of two if it is not already a power of two. See the comments abo ve | |||
/// SmallPtrSetImpl for details of the algorithm. | /// SmallPtrSetImpl for details of the algorithm. | |||
template<class PtrType, unsigned SmallSize> | template<class PtrType, unsigned SmallSize> | |||
class SmallPtrSet : public SmallPtrSetImpl { | class SmallPtrSet : public SmallPtrSetImpl { | |||
// Make sure that SmallSize is a power of two, round up if not. | // Make sure that SmallSize is a power of two, round up if not. | |||
enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val }; | enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val }; | |||
/// SmallStorage - Fixed size storage used in 'small mode'. The extra el | /// SmallStorage - Fixed size storage used in 'small mode'. | |||
ement | const void *SmallStorage[SmallSizePowTwo]; | |||
/// ensures that the end iterator actually points to valid memory. | ||||
const void *SmallStorage[SmallSizePowTwo+1]; | ||||
typedef PointerLikeTypeTraits<PtrType> PtrTraits; | typedef PointerLikeTypeTraits<PtrType> PtrTraits; | |||
public: | public: | |||
SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {} | SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {} | |||
SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(SmallStorage, that ) {} | SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(SmallStorage, that ) {} | |||
template<typename It> | template<typename It> | |||
SmallPtrSet(It I, It E) : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) { | SmallPtrSet(It I, It E) : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) { | |||
insert(I, E); | insert(I, E); | |||
} | } | |||
skipping to change at line 277 | skipping to change at line 276 | |||
template <typename IterT> | template <typename IterT> | |||
void insert(IterT I, IterT E) { | void insert(IterT I, IterT E) { | |||
for (; I != E; ++I) | for (; I != E; ++I) | |||
insert(*I); | insert(*I); | |||
} | } | |||
typedef SmallPtrSetIterator<PtrType> iterator; | typedef SmallPtrSetIterator<PtrType> iterator; | |||
typedef SmallPtrSetIterator<PtrType> const_iterator; | typedef SmallPtrSetIterator<PtrType> const_iterator; | |||
inline iterator begin() const { | inline iterator begin() const { | |||
return iterator(CurArray); | return iterator(CurArray, CurArray+CurArraySize); | |||
} | } | |||
inline iterator end() const { | inline iterator end() const { | |||
return iterator(CurArray+CurArraySize); | return iterator(CurArray+CurArraySize, CurArray+CurArraySize); | |||
} | } | |||
// Allow assignment from any smallptrset with the same element type even if it | // Allow assignment from any smallptrset with the same element type even if it | |||
// doesn't have the same smallsize. | // doesn't have the same smallsize. | |||
const SmallPtrSet<PtrType, SmallSize>& | const SmallPtrSet<PtrType, SmallSize>& | |||
operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) { | operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) { | |||
CopyFrom(RHS); | CopyFrom(RHS); | |||
return *this; | return *this; | |||
} | } | |||
End of changes. 10 change blocks. | ||||
18 lines changed or deleted | 16 lines changed or added | |||
SmallSet.h | SmallSet.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the SmallSet class. | // This file defines the SmallSet class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_SMALLSET_H | #ifndef LLVM_ADT_SMALLSET_H | |||
#define LLVM_ADT_SMALLSET_H | #define LLVM_ADT_SMALLSET_H | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include <set> | #include <set> | |||
namespace llvm { | namespace llvm { | |||
/// SmallSet - This maintains a set of unique values, optimizing for the ca se | /// SmallSet - This maintains a set of unique values, optimizing for the ca se | |||
/// when the set is small (less than N). In this case, the set can be | /// when the set is small (less than N). In this case, the set can be | |||
/// maintained with no mallocs. If the set gets large, we expand to using an | /// maintained with no mallocs. If the set gets large, we expand to using an | |||
/// std::set to maintain reasonable lookup times. | /// std::set to maintain reasonable lookup times. | |||
/// | /// | |||
/// Note that this set does not provide a way to iterate over members in th e | /// Note that this set does not provide a way to iterate over members in th e | |||
skipping to change at line 58 | skipping to change at line 58 | |||
bool count(const T &V) const { | bool count(const T &V) const { | |||
if (isSmall()) { | if (isSmall()) { | |||
// Since the collection is small, just do a linear search. | // Since the collection is small, just do a linear search. | |||
return vfind(V) != Vector.end(); | return vfind(V) != Vector.end(); | |||
} else { | } else { | |||
return Set.count(V); | return Set.count(V); | |||
} | } | |||
} | } | |||
/// insert - Insert an element into the set if it isn't already there. | /// insert - Insert an element into the set if it isn't already there. | |||
/// Returns true if the element is inserted (it was not in the set before ). | ||||
bool insert(const T &V) { | bool insert(const T &V) { | |||
if (!isSmall()) | if (!isSmall()) | |||
return Set.insert(V).second; | return Set.insert(V).second; | |||
VIterator I = vfind(V); | VIterator I = vfind(V); | |||
if (I != Vector.end()) // Don't reinsert if it already exists. | if (I != Vector.end()) // Don't reinsert if it already exists. | |||
return false; | return false; | |||
if (Vector.size() < N) { | if (Vector.size() < N) { | |||
Vector.push_back(V); | Vector.push_back(V); | |||
return true; | return true; | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 2 lines changed or added | |||
SmallVector.h | SmallVector.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file defines the SmallVector class. | // This file defines the SmallVector class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_SMALLVECTOR_H | #ifndef LLVM_ADT_SMALLVECTOR_H | |||
#define LLVM_ADT_SMALLVECTOR_H | #define LLVM_ADT_SMALLVECTOR_H | |||
#include "llvm/Support/AlignOf.h" | #include "llvm/Support/AlignOf.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/MathExtras.h" | ||||
#include "llvm/Support/type_traits.h" | #include "llvm/Support/type_traits.h" | |||
#include <algorithm> | #include <algorithm> | |||
#include <cassert> | #include <cassert> | |||
#include <cstddef> | #include <cstddef> | |||
#include <cstdlib> | #include <cstdlib> | |||
#include <cstring> | #include <cstring> | |||
#include <iterator> | #include <iterator> | |||
#include <memory> | #include <memory> | |||
namespace llvm { | namespace llvm { | |||
skipping to change at line 148 | skipping to change at line 149 | |||
reference operator[](unsigned idx) { | reference operator[](unsigned idx) { | |||
assert(begin() + idx < end()); | assert(begin() + idx < end()); | |||
return begin()[idx]; | return begin()[idx]; | |||
} | } | |||
const_reference operator[](unsigned idx) const { | const_reference operator[](unsigned idx) const { | |||
assert(begin() + idx < end()); | assert(begin() + idx < end()); | |||
return begin()[idx]; | return begin()[idx]; | |||
} | } | |||
reference front() { | reference front() { | |||
assert(!empty()); | ||||
return begin()[0]; | return begin()[0]; | |||
} | } | |||
const_reference front() const { | const_reference front() const { | |||
assert(!empty()); | ||||
return begin()[0]; | return begin()[0]; | |||
} | } | |||
reference back() { | reference back() { | |||
assert(!empty()); | ||||
return end()[-1]; | return end()[-1]; | |||
} | } | |||
const_reference back() const { | const_reference back() const { | |||
assert(!empty()); | ||||
return end()[-1]; | return end()[-1]; | |||
} | } | |||
}; | }; | |||
/// SmallVectorTemplateBase<isPodLike = false> - This is where we put metho d | /// SmallVectorTemplateBase<isPodLike = false> - This is where we put metho d | |||
/// implementations that are designed to work with non-POD-like T's. | /// implementations that are designed to work with non-POD-like T's. | |||
template <typename T, bool isPodLike> | template <typename T, bool isPodLike> | |||
class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> { | class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> { | |||
protected: | protected: | |||
SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {} | SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {} | |||
skipping to change at line 181 | skipping to change at line 186 | |||
--E; | --E; | |||
E->~T(); | E->~T(); | |||
} | } | |||
} | } | |||
/// move - Use move-assignment to move the range [I, E) onto the | /// move - Use move-assignment to move the range [I, E) onto the | |||
/// objects starting with "Dest". This is just <memory>'s | /// objects starting with "Dest". This is just <memory>'s | |||
/// std::move, but not all stdlibs actually provide that. | /// std::move, but not all stdlibs actually provide that. | |||
template<typename It1, typename It2> | template<typename It1, typename It2> | |||
static It2 move(It1 I, It1 E, It2 Dest) { | static It2 move(It1 I, It1 E, It2 Dest) { | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
for (; I != E; ++I, ++Dest) | for (; I != E; ++I, ++Dest) | |||
*Dest = ::std::move(*I); | *Dest = ::std::move(*I); | |||
return Dest; | return Dest; | |||
#else | #else | |||
return ::std::copy(I, E, Dest); | return ::std::copy(I, E, Dest); | |||
#endif | #endif | |||
} | } | |||
/// move_backward - Use move-assignment to move the range | /// move_backward - Use move-assignment to move the range | |||
/// [I, E) onto the objects ending at "Dest", moving objects | /// [I, E) onto the objects ending at "Dest", moving objects | |||
/// in reverse order. This is just <algorithm>'s | /// in reverse order. This is just <algorithm>'s | |||
/// std::move_backward, but not all stdlibs actually provide that. | /// std::move_backward, but not all stdlibs actually provide that. | |||
template<typename It1, typename It2> | template<typename It1, typename It2> | |||
static It2 move_backward(It1 I, It1 E, It2 Dest) { | static It2 move_backward(It1 I, It1 E, It2 Dest) { | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
while (I != E) | while (I != E) | |||
*--Dest = ::std::move(*--E); | *--Dest = ::std::move(*--E); | |||
return Dest; | return Dest; | |||
#else | #else | |||
return ::std::copy_backward(I, E, Dest); | return ::std::copy_backward(I, E, Dest); | |||
#endif | #endif | |||
} | } | |||
/// uninitialized_move - Move the range [I, E) into the uninitialized | /// uninitialized_move - Move the range [I, E) into the uninitialized | |||
/// memory starting with "Dest", constructing elements as needed. | /// memory starting with "Dest", constructing elements as needed. | |||
template<typename It1, typename It2> | template<typename It1, typename It2> | |||
static void uninitialized_move(It1 I, It1 E, It2 Dest) { | static void uninitialized_move(It1 I, It1 E, It2 Dest) { | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
for (; I != E; ++I, ++Dest) | for (; I != E; ++I, ++Dest) | |||
::new ((void*) &*Dest) T(::std::move(*I)); | ::new ((void*) &*Dest) T(::std::move(*I)); | |||
#else | #else | |||
::std::uninitialized_copy(I, E, Dest); | ::std::uninitialized_copy(I, E, Dest); | |||
#endif | #endif | |||
} | } | |||
/// uninitialized_copy - Copy the range [I, E) onto the uninitialized | /// uninitialized_copy - Copy the range [I, E) onto the uninitialized | |||
/// memory starting with "Dest", constructing elements as needed. | /// memory starting with "Dest", constructing elements as needed. | |||
template<typename It1, typename It2> | template<typename It1, typename It2> | |||
skipping to change at line 242 | skipping to change at line 247 | |||
if (this->EndX < this->CapacityX) { | if (this->EndX < this->CapacityX) { | |||
Retry: | Retry: | |||
::new ((void*) this->end()) T(Elt); | ::new ((void*) this->end()) T(Elt); | |||
this->setEnd(this->end()+1); | this->setEnd(this->end()+1); | |||
return; | return; | |||
} | } | |||
this->grow(); | this->grow(); | |||
goto Retry; | goto Retry; | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
void push_back(T &&Elt) { | void push_back(T &&Elt) { | |||
if (this->EndX < this->CapacityX) { | if (this->EndX < this->CapacityX) { | |||
Retry: | Retry: | |||
::new ((void*) this->end()) T(::std::move(Elt)); | ::new ((void*) this->end()) T(::std::move(Elt)); | |||
this->setEnd(this->end()+1); | this->setEnd(this->end()+1); | |||
return; | return; | |||
} | } | |||
this->grow(); | this->grow(); | |||
goto Retry; | goto Retry; | |||
} | } | |||
skipping to change at line 266 | skipping to change at line 271 | |||
this->setEnd(this->end()-1); | this->setEnd(this->end()-1); | |||
this->end()->~T(); | this->end()->~T(); | |||
} | } | |||
}; | }; | |||
// Define this out-of-line to dissuade the C++ compiler from inlining it. | // Define this out-of-line to dissuade the C++ compiler from inlining it. | |||
template <typename T, bool isPodLike> | template <typename T, bool isPodLike> | |||
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) { | void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) { | |||
size_t CurCapacity = this->capacity(); | size_t CurCapacity = this->capacity(); | |||
size_t CurSize = this->size(); | size_t CurSize = this->size(); | |||
size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero. | // Always grow, even from zero. | |||
size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2)); | ||||
if (NewCapacity < MinSize) | if (NewCapacity < MinSize) | |||
NewCapacity = MinSize; | NewCapacity = MinSize; | |||
T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T))); | T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T))); | |||
// Move the elements over. | // Move the elements over. | |||
this->uninitialized_move(this->begin(), this->end(), NewElts); | this->uninitialized_move(this->begin(), this->end(), NewElts); | |||
// Destroy the original elements. | // Destroy the original elements. | |||
destroy_range(this->begin(), this->end()); | destroy_range(this->begin(), this->end()); | |||
skipping to change at line 366 | skipping to change at line 372 | |||
} | } | |||
}; | }; | |||
/// SmallVectorImpl - This class consists of common code factored out of th e | /// SmallVectorImpl - This class consists of common code factored out of th e | |||
/// SmallVector class to reduce code duplication based on the SmallVector ' N' | /// SmallVector class to reduce code duplication based on the SmallVector ' N' | |||
/// template parameter. | /// template parameter. | |||
template <typename T> | template <typename T> | |||
class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::val ue> { | class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::val ue> { | |||
typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass; | typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass; | |||
SmallVectorImpl(const SmallVectorImpl&); // DISABLED. | SmallVectorImpl(const SmallVectorImpl&) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
typedef typename SuperClass::iterator iterator; | typedef typename SuperClass::iterator iterator; | |||
typedef typename SuperClass::size_type size_type; | typedef typename SuperClass::size_type size_type; | |||
protected: | protected: | |||
// Default ctor - Initialize to empty. | // Default ctor - Initialize to empty. | |||
explicit SmallVectorImpl(unsigned N) | explicit SmallVectorImpl(unsigned N) | |||
: SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) { | : SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) { | |||
} | } | |||
skipping to change at line 422 | skipping to change at line 428 | |||
this->setEnd(this->begin()+N); | this->setEnd(this->begin()+N); | |||
} | } | |||
} | } | |||
void reserve(unsigned N) { | void reserve(unsigned N) { | |||
if (this->capacity() < N) | if (this->capacity() < N) | |||
this->grow(N); | this->grow(N); | |||
} | } | |||
T pop_back_val() { | T pop_back_val() { | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
T Result = ::std::move(this->back()); | T Result = ::std::move(this->back()); | |||
#else | #else | |||
T Result = this->back(); | T Result = this->back(); | |||
#endif | #endif | |||
this->pop_back(); | this->pop_back(); | |||
return Result; | return Result; | |||
} | } | |||
void swap(SmallVectorImpl &RHS); | void swap(SmallVectorImpl &RHS); | |||
skipping to change at line 495 | skipping to change at line 501 | |||
iterator N = S; | iterator N = S; | |||
// Shift all elts down. | // Shift all elts down. | |||
iterator I = this->move(E, this->end(), S); | iterator I = this->move(E, this->end(), S); | |||
// Drop the last elts. | // Drop the last elts. | |||
this->destroy_range(I, this->end()); | this->destroy_range(I, this->end()); | |||
this->setEnd(I); | this->setEnd(I); | |||
return(N); | return(N); | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
iterator insert(iterator I, T &&Elt) { | iterator insert(iterator I, T &&Elt) { | |||
if (I == this->end()) { // Important special case for empty vector. | if (I == this->end()) { // Important special case for empty vector. | |||
this->push_back(::std::move(Elt)); | this->push_back(::std::move(Elt)); | |||
return this->end()-1; | return this->end()-1; | |||
} | } | |||
assert(I >= this->begin() && "Insertion iterator is out of bounds."); | assert(I >= this->begin() && "Insertion iterator is out of bounds."); | |||
assert(I <= this->end() && "Inserting past the end of the vector."); | assert(I <= this->end() && "Inserting past the end of the vector."); | |||
if (this->EndX < this->CapacityX) { | if (this->EndX < this->CapacityX) { | |||
skipping to change at line 667 | skipping to change at line 673 | |||
++J; ++From; | ++J; ++From; | |||
} | } | |||
// Insert the non-overwritten middle part. | // Insert the non-overwritten middle part. | |||
this->uninitialized_copy(From, To, OldEnd); | this->uninitialized_copy(From, To, OldEnd); | |||
return I; | return I; | |||
} | } | |||
SmallVectorImpl &operator=(const SmallVectorImpl &RHS); | SmallVectorImpl &operator=(const SmallVectorImpl &RHS); | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
SmallVectorImpl &operator=(SmallVectorImpl &&RHS); | SmallVectorImpl &operator=(SmallVectorImpl &&RHS); | |||
#endif | #endif | |||
bool operator==(const SmallVectorImpl &RHS) const { | bool operator==(const SmallVectorImpl &RHS) const { | |||
if (this->size() != RHS.size()) return false; | if (this->size() != RHS.size()) return false; | |||
return std::equal(this->begin(), this->end(), RHS.begin()); | return std::equal(this->begin(), this->end(), RHS.begin()); | |||
} | } | |||
bool operator!=(const SmallVectorImpl &RHS) const { | bool operator!=(const SmallVectorImpl &RHS) const { | |||
return !(*this == RHS); | return !(*this == RHS); | |||
} | } | |||
skipping to change at line 786 | skipping to change at line 792 | |||
// Copy construct the new elements in place. | // Copy construct the new elements in place. | |||
this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(), | this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(), | |||
this->begin()+CurSize); | this->begin()+CurSize); | |||
// Set end. | // Set end. | |||
this->setEnd(this->begin()+RHSSize); | this->setEnd(this->begin()+RHSSize); | |||
return *this; | return *this; | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
template <typename T> | template <typename T> | |||
SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) { | SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) { | |||
// Avoid self-assignment. | // Avoid self-assignment. | |||
if (this == &RHS) return *this; | if (this == &RHS) return *this; | |||
// If the RHS isn't small, clear this vector and then steal its buffer. | // If the RHS isn't small, clear this vector and then steal its buffer. | |||
if (!RHS.isSmall()) { | if (!RHS.isSmall()) { | |||
this->destroy_range(this->begin(), this->end()); | this->destroy_range(this->begin(), this->end()); | |||
if (!this->isSmall()) free(this->begin()); | if (!this->isSmall()) free(this->begin()); | |||
this->BeginX = RHS.BeginX; | this->BeginX = RHS.BeginX; | |||
skipping to change at line 897 | skipping to change at line 903 | |||
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) { | SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) { | |||
if (!RHS.empty()) | if (!RHS.empty()) | |||
SmallVectorImpl<T>::operator=(RHS); | SmallVectorImpl<T>::operator=(RHS); | |||
} | } | |||
const SmallVector &operator=(const SmallVector &RHS) { | const SmallVector &operator=(const SmallVector &RHS) { | |||
SmallVectorImpl<T>::operator=(RHS); | SmallVectorImpl<T>::operator=(RHS); | |||
return *this; | return *this; | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) { | SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) { | |||
if (!RHS.empty()) | if (!RHS.empty()) | |||
SmallVectorImpl<T>::operator=(::std::move(RHS)); | SmallVectorImpl<T>::operator=(::std::move(RHS)); | |||
} | } | |||
const SmallVector &operator=(SmallVector &&RHS) { | const SmallVector &operator=(SmallVector &&RHS) { | |||
SmallVectorImpl<T>::operator=(::std::move(RHS)); | SmallVectorImpl<T>::operator=(::std::move(RHS)); | |||
return *this; | return *this; | |||
} | } | |||
#endif | #endif | |||
End of changes. 16 change blocks. | ||||
11 lines changed or deleted | 17 lines changed or added | |||
Solaris.h | Solaris.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
* | * | |||
* This file is distributed under the University of Illinois Open Source | * This file is distributed under the University of Illinois Open Source | |||
* License. See LICENSE.TXT for details. | * License. See LICENSE.TXT for details. | |||
* | * | |||
*===---------------------------------------------------------------------- ===* | *===---------------------------------------------------------------------- ===* | |||
* | * | |||
* This file contains portability fixes for Solaris hosts. | * This file contains portability fixes for Solaris hosts. | |||
* | * | |||
*===---------------------------------------------------------------------- ===*/ | *===---------------------------------------------------------------------- ===*/ | |||
#ifndef LLVM_SYSTEM_SOLARIS_H | #ifndef LLVM_SUPPORT_SOLARIS_H | |||
#define LLVM_SYSTEM_SOLARIS_H | #define LLVM_SUPPORT_SOLARIS_H | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#include <sys/regset.h> | #include <sys/regset.h> | |||
#undef CS | #undef CS | |||
#undef DS | #undef DS | |||
#undef ES | #undef ES | |||
#undef FS | #undef FS | |||
#undef GS | #undef GS | |||
#undef SS | #undef SS | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Solution.h | Solution.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// PBQP Solution class. | // PBQP Solution class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_PBQP_SOLUTION_H | #ifndef LLVM_CODEGEN_PBQP_SOLUTION_H | |||
#define LLVM_CODEGEN_PBQP_SOLUTION_H | #define LLVM_CODEGEN_PBQP_SOLUTION_H | |||
#include "Math.h" | ||||
#include "Graph.h" | #include "Graph.h" | |||
#include "Math.h" | ||||
#include <map> | #include <map> | |||
namespace PBQP { | namespace PBQP { | |||
/// \brief Represents a solution to a PBQP problem. | /// \brief Represents a solution to a PBQP problem. | |||
/// | /// | |||
/// To get the selection for each node in the problem use the getSelectio n method. | /// To get the selection for each node in the problem use the getSelectio n method. | |||
class Solution { | class Solution { | |||
private: | private: | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 1 lines changed or added | |||
SourceMgr.h | SourceMgr.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the SMDiagnostic and SourceMgr classes. This | // This file declares the SMDiagnostic and SourceMgr classes. This | |||
// provides a simple substrate for diagnostics, #include handling, and othe r low | // provides a simple substrate for diagnostics, #include handling, and othe r low | |||
// level things for simple parsers. | // level things for simple parsers. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef SUPPORT_SOURCEMGR_H | #ifndef LLVM_SUPPORT_SOURCEMGR_H | |||
#define SUPPORT_SOURCEMGR_H | #define LLVM_SUPPORT_SOURCEMGR_H | |||
#include "llvm/Support/SMLoc.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/ADT/StringRef.h" | ||||
#include "llvm/ADT/Twine.h" | ||||
#include "llvm/Support/SMLoc.h" | ||||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class MemoryBuffer; | class MemoryBuffer; | |||
class SourceMgr; | class SourceMgr; | |||
class SMDiagnostic; | class SMDiagnostic; | |||
class SMFixIt; | ||||
class Twine; | class Twine; | |||
class raw_ostream; | class raw_ostream; | |||
/// SourceMgr - This owns the files read by a parser, handles include stack s, | /// SourceMgr - This owns the files read by a parser, handles include stack s, | |||
/// and handles diagnostic wrangling. | /// and handles diagnostic wrangling. | |||
class SourceMgr { | class SourceMgr { | |||
public: | public: | |||
enum DiagKind { | enum DiagKind { | |||
DK_Error, | DK_Error, | |||
DK_Warning, | DK_Warning, | |||
skipping to change at line 98 | skipping to change at line 101 | |||
const SrcBuffer &getBufferInfo(unsigned i) const { | const SrcBuffer &getBufferInfo(unsigned i) const { | |||
assert(i < Buffers.size() && "Invalid Buffer ID!"); | assert(i < Buffers.size() && "Invalid Buffer ID!"); | |||
return Buffers[i]; | return Buffers[i]; | |||
} | } | |||
const MemoryBuffer *getMemoryBuffer(unsigned i) const { | const MemoryBuffer *getMemoryBuffer(unsigned i) const { | |||
assert(i < Buffers.size() && "Invalid Buffer ID!"); | assert(i < Buffers.size() && "Invalid Buffer ID!"); | |||
return Buffers[i].Buffer; | return Buffers[i].Buffer; | |||
} | } | |||
unsigned getNumBuffers() const { | ||||
return Buffers.size(); | ||||
} | ||||
SMLoc getParentIncludeLoc(unsigned i) const { | SMLoc getParentIncludeLoc(unsigned i) const { | |||
assert(i < Buffers.size() && "Invalid Buffer ID!"); | assert(i < Buffers.size() && "Invalid Buffer ID!"); | |||
return Buffers[i].IncludeLoc; | return Buffers[i].IncludeLoc; | |||
} | } | |||
/// AddNewSourceBuffer - Add a new source buffer to this source manager. This | /// AddNewSourceBuffer - Add a new source buffer to this source manager. This | |||
/// takes ownership of the memory buffer. | /// takes ownership of the memory buffer. | |||
unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) { | unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) { | |||
SrcBuffer NB; | SrcBuffer NB; | |||
NB.Buffer = F; | NB.Buffer = F; | |||
skipping to change at line 141 | skipping to change at line 148 | |||
/// location in the specified file. This is not a fast method. | /// location in the specified file. This is not a fast method. | |||
std::pair<unsigned, unsigned> | std::pair<unsigned, unsigned> | |||
getLineAndColumn(SMLoc Loc, int BufferID = -1) const; | getLineAndColumn(SMLoc Loc, int BufferID = -1) const; | |||
/// PrintMessage - Emit a message about the specified location with the | /// PrintMessage - Emit a message about the specified location with the | |||
/// specified string. | /// specified string. | |||
/// | /// | |||
/// @param ShowColors - Display colored messages if output is a terminal and | /// @param ShowColors - Display colored messages if output is a terminal and | |||
/// the default error handler is used. | /// the default error handler is used. | |||
void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, | void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, | |||
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(), | ArrayRef<SMRange> Ranges = None, | |||
ArrayRef<SMFixIt> FixIts = None, | ||||
bool ShowColors = true) const; | bool ShowColors = true) const; | |||
/// GetMessage - Return an SMDiagnostic at the specified location with th e | /// GetMessage - Return an SMDiagnostic at the specified location with th e | |||
/// specified string. | /// specified string. | |||
/// | /// | |||
/// @param Msg If non-null, the kind of message (e.g., "error") which is | /// @param Msg If non-null, the kind of message (e.g., "error") which is | |||
/// prefixed to the message. | /// prefixed to the message. | |||
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, | SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, | |||
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) c | ArrayRef<SMRange> Ranges = None, | |||
onst; | ArrayRef<SMFixIt> FixIts = None) const; | |||
/// PrintIncludeStack - Prints the names of included files and the line o f the | /// PrintIncludeStack - Prints the names of included files and the line o f the | |||
/// file they were included from. A diagnostic handler can use this befo re | /// file they were included from. A diagnostic handler can use this befo re | |||
/// printing its custom formatted message. | /// printing its custom formatted message. | |||
/// | /// | |||
/// @param IncludeLoc - The line of the include. | /// @param IncludeLoc - The line of the include. | |||
/// @param OS the raw_ostream to print on. | /// @param OS the raw_ostream to print on. | |||
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const; | void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const; | |||
}; | }; | |||
/// Represents a single fixit, a replacement of one range of text with anot | ||||
her. | ||||
class SMFixIt { | ||||
SMRange Range; | ||||
std::string Text; | ||||
public: | ||||
// FIXME: Twine.str() is not very efficient. | ||||
SMFixIt(SMLoc Loc, const Twine &Insertion) | ||||
: Range(Loc, Loc), Text(Insertion.str()) { | ||||
assert(Loc.isValid()); | ||||
} | ||||
// FIXME: Twine.str() is not very efficient. | ||||
SMFixIt(SMRange R, const Twine &Replacement) | ||||
: Range(R), Text(Replacement.str()) { | ||||
assert(R.isValid()); | ||||
} | ||||
StringRef getText() const { return Text; } | ||||
SMRange getRange() const { return Range; } | ||||
bool operator<(const SMFixIt &Other) const { | ||||
if (Range.Start.getPointer() != Other.Range.Start.getPointer()) | ||||
return Range.Start.getPointer() < Other.Range.Start.getPointer(); | ||||
if (Range.End.getPointer() != Other.Range.End.getPointer()) | ||||
return Range.End.getPointer() < Other.Range.End.getPointer(); | ||||
return Text < Other.Text; | ||||
} | ||||
}; | ||||
/// SMDiagnostic - Instances of this class encapsulate one diagnostic repor t, | /// SMDiagnostic - Instances of this class encapsulate one diagnostic repor t, | |||
/// allowing printing to a raw_ostream as a caret diagnostic. | /// allowing printing to a raw_ostream as a caret diagnostic. | |||
class SMDiagnostic { | class SMDiagnostic { | |||
const SourceMgr *SM; | const SourceMgr *SM; | |||
SMLoc Loc; | SMLoc Loc; | |||
std::string Filename; | std::string Filename; | |||
int LineNo, ColumnNo; | int LineNo, ColumnNo; | |||
SourceMgr::DiagKind Kind; | SourceMgr::DiagKind Kind; | |||
std::string Message, LineContents; | std::string Message, LineContents; | |||
std::vector<std::pair<unsigned, unsigned> > Ranges; | std::vector<std::pair<unsigned, unsigned> > Ranges; | |||
SmallVector<SMFixIt, 4> FixIts; | ||||
public: | public: | |||
// Null diagnostic. | // Null diagnostic. | |||
SMDiagnostic() | SMDiagnostic() | |||
: SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {} | : SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {} | |||
// Diagnostic with no location (e.g. file not found, command line arg err or). | // Diagnostic with no location (e.g. file not found, command line arg err or). | |||
SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Knd, | SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg) | |||
const std::string &Msg) | ||||
: SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd), | : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd), | |||
Message(Msg) {} | Message(Msg) {} | |||
// Diagnostic with a location. | // Diagnostic with a location. | |||
SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN, | SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, | |||
int Line, int Col, SourceMgr::DiagKind Kind, | int Line, int Col, SourceMgr::DiagKind Kind, | |||
const std::string &Msg, const std::string &LineStr, | StringRef Msg, StringRef LineStr, | |||
ArrayRef<std::pair<unsigned,unsigned> > Ranges); | ArrayRef<std::pair<unsigned,unsigned> > Ranges, | |||
ArrayRef<SMFixIt> FixIts = None); | ||||
const SourceMgr *getSourceMgr() const { return SM; } | const SourceMgr *getSourceMgr() const { return SM; } | |||
SMLoc getLoc() const { return Loc; } | SMLoc getLoc() const { return Loc; } | |||
const std::string &getFilename() const { return Filename; } | StringRef getFilename() const { return Filename; } | |||
int getLineNo() const { return LineNo; } | int getLineNo() const { return LineNo; } | |||
int getColumnNo() const { return ColumnNo; } | int getColumnNo() const { return ColumnNo; } | |||
SourceMgr::DiagKind getKind() const { return Kind; } | SourceMgr::DiagKind getKind() const { return Kind; } | |||
const std::string &getMessage() const { return Message; } | StringRef getMessage() const { return Message; } | |||
const std::string &getLineContents() const { return LineContents; } | StringRef getLineContents() const { return LineContents; } | |||
const std::vector<std::pair<unsigned, unsigned> > &getRanges() const { | ArrayRef<std::pair<unsigned, unsigned> > getRanges() const { | |||
return Ranges; | return Ranges; | |||
} | } | |||
void print(const char *ProgName, raw_ostream &S, bool ShowColors = true) | ||||
const; | void addFixIt(const SMFixIt &Hint) { | |||
FixIts.push_back(Hint); | ||||
} | ||||
ArrayRef<SMFixIt> getFixIts() const { | ||||
return FixIts; | ||||
} | ||||
void print(const char *ProgName, raw_ostream &S, | ||||
bool ShowColors = true) const; | ||||
}; | }; | |||
} // end llvm namespace | } // end llvm namespace | |||
#endif | #endif | |||
End of changes. 15 change blocks. | ||||
17 lines changed or deleted | 67 lines changed or added | |||
SparsePropagation.h | SparsePropagation.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements an abstract sparse conditional propagation algorith m, | // This file implements an abstract sparse conditional propagation algorith m, | |||
// modeled after SCCP, but with a customizable lattice function. | // modeled after SCCP, but with a customizable lattice function. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_SPARSE_PROPAGATION_H | #ifndef LLVM_ANALYSIS_SPARSEPROPAGATION_H | |||
#define LLVM_ANALYSIS_SPARSE_PROPAGATION_H | #define LLVM_ANALYSIS_SPARSEPROPAGATION_H | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | |||
#include <vector> | ||||
#include <set> | #include <set> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
class Value; | class Value; | |||
class Constant; | class Constant; | |||
class Argument; | class Argument; | |||
class Instruction; | class Instruction; | |||
class PHINode; | class PHINode; | |||
class TerminatorInst; | class TerminatorInst; | |||
class BasicBlock; | class BasicBlock; | |||
class Function; | class Function; | |||
skipping to change at line 205 | skipping to change at line 205 | |||
bool AggressiveUndef); | bool AggressiveUndef); | |||
void visitInst(Instruction &I); | void visitInst(Instruction &I); | |||
void visitPHINode(PHINode &I); | void visitPHINode(PHINode &I); | |||
void visitTerminatorInst(TerminatorInst &TI); | void visitTerminatorInst(TerminatorInst &TI); | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif // LLVM_ANALYSIS_SPARSE_PROPAGATION_H | #endif // LLVM_ANALYSIS_SPARSEPROPAGATION_H | |||
End of changes. 4 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
SparseSet.h | SparseSet.h | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// | // | |||
// A sparse set holds a small number of objects identified by integer keys from | // A sparse set holds a small number of objects identified by integer keys from | |||
// a moderately sized universe. The sparse set uses more memory than other | // a moderately sized universe. The sparse set uses more memory than other | |||
// containers in order to provide faster operations. | // containers in order to provide faster operations. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_SPARSESET_H | #ifndef LLVM_ADT_SPARSESET_H | |||
#define LLVM_ADT_SPARSESET_H | #define LLVM_ADT_SPARSESET_H | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/STLExtras.h" | #include "llvm/ADT/STLExtras.h" | |||
#include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <limits> | #include <limits> | |||
namespace llvm { | namespace llvm { | |||
/// SparseSetValTraits - Objects in a SparseSet are identified by keys that can | /// SparseSetValTraits - Objects in a SparseSet are identified by keys that can | |||
/// be uniquely converted to a small integer less than the set's universe. This | /// be uniquely converted to a small integer less than the set's universe. This | |||
/// class allows the set to hold values that differ from the set's key type as | /// class allows the set to hold values that differ from the set's key type as | |||
/// long as an index can still be derived from the value. SparseSet never | /// long as an index can still be derived from the value. SparseSet never | |||
/// directly compares ValueT, only their indices, so it can map keys to | /// directly compares ValueT, only their indices, so it can map keys to | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Statistic.h | Statistic.h | |||
---|---|---|---|---|
skipping to change at line 54 | skipping to change at line 54 | |||
const char *getDesc() const { return Desc; } | const char *getDesc() const { return Desc; } | |||
/// construct - This should only be called for non-global statistics. | /// construct - This should only be called for non-global statistics. | |||
void construct(const char *name, const char *desc) { | void construct(const char *name, const char *desc) { | |||
Name = name; Desc = desc; | Name = name; Desc = desc; | |||
Value = 0; Initialized = 0; | Value = 0; Initialized = 0; | |||
} | } | |||
// Allow use of this class as the value itself. | // Allow use of this class as the value itself. | |||
operator unsigned() const { return Value; } | operator unsigned() const { return Value; } | |||
const Statistic &operator=(unsigned Val) { | ||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) | ||||
const Statistic &operator=(unsigned Val) { | ||||
Value = Val; | Value = Val; | |||
return init(); | return init(); | |||
} | } | |||
const Statistic &operator++() { | const Statistic &operator++() { | |||
// FIXME: This function and all those that follow carefully use an | // FIXME: This function and all those that follow carefully use an | |||
// atomic operation to update the value safely in the presence of | // atomic operation to update the value safely in the presence of | |||
// concurrent accesses, but not to read the return value, so the | // concurrent accesses, but not to read the return value, so the | |||
// return value is not thread safe. | // return value is not thread safe. | |||
sys::AtomicIncrement(&Value); | sys::AtomicIncrement(&Value); | |||
skipping to change at line 109 | skipping to change at line 111 | |||
const Statistic &operator*=(const unsigned &V) { | const Statistic &operator*=(const unsigned &V) { | |||
sys::AtomicMul(&Value, V); | sys::AtomicMul(&Value, V); | |||
return init(); | return init(); | |||
} | } | |||
const Statistic &operator/=(const unsigned &V) { | const Statistic &operator/=(const unsigned &V) { | |||
sys::AtomicDiv(&Value, V); | sys::AtomicDiv(&Value, V); | |||
return init(); | return init(); | |||
} | } | |||
#else // Statistics are disabled in release builds. | ||||
const Statistic &operator=(unsigned Val) { | ||||
return *this; | ||||
} | ||||
const Statistic &operator++() { | ||||
return *this; | ||||
} | ||||
unsigned operator++(int) { | ||||
return 0; | ||||
} | ||||
const Statistic &operator--() { | ||||
return *this; | ||||
} | ||||
unsigned operator--(int) { | ||||
return 0; | ||||
} | ||||
const Statistic &operator+=(const unsigned &V) { | ||||
return *this; | ||||
} | ||||
const Statistic &operator-=(const unsigned &V) { | ||||
return *this; | ||||
} | ||||
const Statistic &operator*=(const unsigned &V) { | ||||
return *this; | ||||
} | ||||
const Statistic &operator/=(const unsigned &V) { | ||||
return *this; | ||||
} | ||||
#endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) | ||||
protected: | protected: | |||
Statistic &init() { | Statistic &init() { | |||
bool tmp = Initialized; | bool tmp = Initialized; | |||
sys::MemoryFence(); | sys::MemoryFence(); | |||
if (!tmp) RegisterStatistic(); | if (!tmp) RegisterStatistic(); | |||
TsanHappensAfter(this); | TsanHappensAfter(this); | |||
return *this; | return *this; | |||
} | } | |||
void RegisterStatistic(); | void RegisterStatistic(); | |||
}; | }; | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 43 lines changed or added | |||
StreamableMemoryObject.h | StreamableMemoryObject.h | |||
---|---|---|---|---|
//===- StreamableMemoryObject.h - Streamable data interface -----*- C++ -*- ===// | //===- StreamableMemoryObject.h - Streamable data interface -----*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef STREAMABLEMEMORYOBJECT_H_ | #ifndef LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H | |||
#define STREAMABLEMEMORYOBJECT_H_ | #define LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H | |||
#include "llvm/ADT/OwningPtr.h" | #include "llvm/ADT/OwningPtr.h" | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/MemoryObject.h" | ||||
#include "llvm/Support/DataStream.h" | #include "llvm/Support/DataStream.h" | |||
#include "llvm/Support/MemoryObject.h" | ||||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
/// StreamableMemoryObject - Interface to data which might be streamed. | /// StreamableMemoryObject - Interface to data which might be streamed. | |||
/// Streamability has 2 important implications/restrictions. First, the dat a | /// Streamability has 2 important implications/restrictions. First, the dat a | |||
/// might not yet exist in memory when the request is made. This just means | /// might not yet exist in memory when the request is made. This just means | |||
/// that readByte/readBytes might have to block or do some work to get it. | /// that readByte/readBytes might have to block or do some work to get it. | |||
/// More significantly, the exact size of the object might not be known unt il | /// More significantly, the exact size of the object might not be known unt il | |||
/// it has all been fetched. This means that to return the right result, | /// it has all been fetched. This means that to return the right result, | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
StringExtras.h | StringExtras.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains some functions that are useful when dealing with stri ngs. | // This file contains some functions that are useful when dealing with stri ngs. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_STRINGEXTRAS_H | #ifndef LLVM_ADT_STRINGEXTRAS_H | |||
#define LLVM_ADT_STRINGEXTRAS_H | #define LLVM_ADT_STRINGEXTRAS_H | |||
#include "llvm/Support/DataTypes.h" | ||||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/DataTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
template<typename T> class SmallVectorImpl; | template<typename T> class SmallVectorImpl; | |||
/// hexdigit - Return the hexadecimal character for the | /// hexdigit - Return the hexadecimal character for the | |||
/// given number \p X (which should be less than 16). | /// given number \p X (which should be less than 16). | |||
static inline char hexdigit(unsigned X, bool LowerCase = false) { | static inline char hexdigit(unsigned X, bool LowerCase = false) { | |||
const char HexChar = LowerCase ? 'a' : 'A'; | const char HexChar = LowerCase ? 'a' : 'A'; | |||
return X < 10 ? '0' + X : HexChar + X - 10; | return X < 10 ? '0' + X : HexChar + X - 10; | |||
} | } | |||
/// Interpret the given character \p C as a hexadecimal digit and return it | ||||
s | ||||
/// value. | ||||
/// | ||||
/// If \p C is not a valid hex digit, -1U is returned. | ||||
static inline unsigned hexDigitValue(char C) { | ||||
if (C >= '0' && C <= '9') return C-'0'; | ||||
if (C >= 'a' && C <= 'f') return C-'a'+10U; | ||||
if (C >= 'A' && C <= 'F') return C-'A'+10U; | ||||
return -1U; | ||||
} | ||||
/// utohex_buffer - Emit the specified number into the buffer specified by | /// utohex_buffer - Emit the specified number into the buffer specified by | |||
/// BufferEnd, returning a pointer to the start of the string. This can be used | /// BufferEnd, returning a pointer to the start of the string. This can be used | |||
/// like this: (note that the buffer must be large enough to handle any num ber): | /// like this: (note that the buffer must be large enough to handle any num ber): | |||
/// char Buffer[40]; | /// char Buffer[40]; | |||
/// printf("0x%s", utohex_buffer(X, Buffer+40)); | /// printf("0x%s", utohex_buffer(X, Buffer+40)); | |||
/// | /// | |||
/// This should only be used with unsigned types. | /// This should only be used with unsigned types. | |||
/// | /// | |||
template<typename IntTy> | template<typename IntTy> | |||
static inline char *utohex_buffer(IntTy X, char *BufferEnd) { | static inline char *utohex_buffer(IntTy X, char *BufferEnd) { | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 13 lines changed or added | |||
StringMap.h | StringMap.h | |||
---|---|---|---|---|
skipping to change at line 55 | skipping to change at line 55 | |||
explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {} | explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {} | |||
unsigned getKeyLength() const { return StrLen; } | unsigned getKeyLength() const { return StrLen; } | |||
}; | }; | |||
/// StringMapImpl - This is the base class of StringMap that is shared amon g | /// StringMapImpl - This is the base class of StringMap that is shared amon g | |||
/// all of its instantiations. | /// all of its instantiations. | |||
class StringMapImpl { | class StringMapImpl { | |||
protected: | protected: | |||
// Array of NumBuckets pointers to entries, null pointers are holes. | // Array of NumBuckets pointers to entries, null pointers are holes. | |||
// TheTable[NumBuckets] contains a sentinel value for easy iteration. Fol lwed | // TheTable[NumBuckets] contains a sentinel value for easy iteration. Fol lowed | |||
// by an array of the actual hash values as unsigned integers. | // by an array of the actual hash values as unsigned integers. | |||
StringMapEntryBase **TheTable; | StringMapEntryBase **TheTable; | |||
unsigned NumBuckets; | unsigned NumBuckets; | |||
unsigned NumItems; | unsigned NumItems; | |||
unsigned NumTombstones; | unsigned NumTombstones; | |||
unsigned ItemSize; | unsigned ItemSize; | |||
protected: | protected: | |||
explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) { | explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) { | |||
// Initialize the map with zero buckets to allocation. | // Initialize the map with zero buckets to allocation. | |||
TheTable = 0; | TheTable = 0; | |||
skipping to change at line 238 | skipping to change at line 238 | |||
public: | public: | |||
typedef StringMapEntry<ValueTy> MapEntryTy; | typedef StringMapEntry<ValueTy> MapEntryTy; | |||
StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {} | StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {} | |||
explicit StringMap(unsigned InitialSize) | explicit StringMap(unsigned InitialSize) | |||
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {} | : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {} | |||
explicit StringMap(AllocatorTy A) | explicit StringMap(AllocatorTy A) | |||
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A ) {} | : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A ) {} | |||
StringMap(unsigned InitialSize, AllocatorTy A) | ||||
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) | ||||
, | ||||
Allocator(A) {} | ||||
StringMap(const StringMap &RHS) | StringMap(const StringMap &RHS) | |||
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) { | : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) { | |||
assert(RHS.empty() && | assert(RHS.empty() && | |||
"Copy ctor from non-empty stringmap not implemented yet!"); | "Copy ctor from non-empty stringmap not implemented yet!"); | |||
(void)RHS; | (void)RHS; | |||
} | } | |||
void operator=(const StringMap &RHS) { | void operator=(const StringMap &RHS) { | |||
assert(RHS.empty() && | assert(RHS.empty() && | |||
"assignment from non-empty stringmap not implemented yet!"); | "assignment from non-empty stringmap not implemented yet!"); | |||
(void)RHS; | (void)RHS; | |||
skipping to change at line 289 | skipping to change at line 293 | |||
if (Bucket == -1) return end(); | if (Bucket == -1) return end(); | |||
return iterator(TheTable+Bucket, true); | return iterator(TheTable+Bucket, true); | |||
} | } | |||
const_iterator find(StringRef Key) const { | const_iterator find(StringRef Key) const { | |||
int Bucket = FindKey(Key); | int Bucket = FindKey(Key); | |||
if (Bucket == -1) return end(); | if (Bucket == -1) return end(); | |||
return const_iterator(TheTable+Bucket, true); | return const_iterator(TheTable+Bucket, true); | |||
} | } | |||
/// lookup - Return the entry for the specified key, or a default | /// lookup - Return the entry for the specified key, or a default | |||
/// constructed value if no such entry exists. | /// constructed value if no such entry exists. | |||
ValueTy lookup(StringRef Key) const { | ValueTy lookup(StringRef Key) const { | |||
const_iterator it = find(Key); | const_iterator it = find(Key); | |||
if (it != end()) | if (it != end()) | |||
return it->second; | return it->second; | |||
return ValueTy(); | return ValueTy(); | |||
} | } | |||
ValueTy &operator[](StringRef Key) { | ValueTy &operator[](StringRef Key) { | |||
return GetOrCreateValue(Key).getValue(); | return GetOrCreateValue(Key).getValue(); | |||
skipping to change at line 335 | skipping to change at line 339 | |||
// clear - Empties out the StringMap | // clear - Empties out the StringMap | |||
void clear() { | void clear() { | |||
if (empty()) return; | if (empty()) return; | |||
// Zap all values, resetting the keys back to non-present (not tombston e), | // Zap all values, resetting the keys back to non-present (not tombston e), | |||
// which is safe because we're removing all elements. | // which is safe because we're removing all elements. | |||
for (unsigned I = 0, E = NumBuckets; I != E; ++I) { | for (unsigned I = 0, E = NumBuckets; I != E; ++I) { | |||
StringMapEntryBase *&Bucket = TheTable[I]; | StringMapEntryBase *&Bucket = TheTable[I]; | |||
if (Bucket && Bucket != getTombstoneVal()) { | if (Bucket && Bucket != getTombstoneVal()) { | |||
static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator); | static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator); | |||
Bucket = 0; | ||||
} | } | |||
Bucket = 0; | ||||
} | } | |||
NumItems = 0; | NumItems = 0; | |||
NumTombstones = 0; | NumTombstones = 0; | |||
} | } | |||
/// GetOrCreateValue - Look up the specified key in the table. If a valu e | /// GetOrCreateValue - Look up the specified key in the table. If a valu e | |||
/// exists, return it. Otherwise, default construct a value, insert it, and | /// exists, return it. Otherwise, default construct a value, insert it, and | |||
/// return. | /// return. | |||
template <typename InitTy> | template <typename InitTy> | |||
skipping to change at line 425 | skipping to change at line 429 | |||
return static_cast<StringMapEntry<ValueTy>*>(*Ptr); | return static_cast<StringMapEntry<ValueTy>*>(*Ptr); | |||
} | } | |||
bool operator==(const StringMapConstIterator &RHS) const { | bool operator==(const StringMapConstIterator &RHS) const { | |||
return Ptr == RHS.Ptr; | return Ptr == RHS.Ptr; | |||
} | } | |||
bool operator!=(const StringMapConstIterator &RHS) const { | bool operator!=(const StringMapConstIterator &RHS) const { | |||
return Ptr != RHS.Ptr; | return Ptr != RHS.Ptr; | |||
} | } | |||
inline StringMapConstIterator& operator++() { // Preincrement | inline StringMapConstIterator& operator++() { // Preincrement | |||
++Ptr; | ++Ptr; | |||
AdvancePastEmptyBuckets(); | AdvancePastEmptyBuckets(); | |||
return *this; | return *this; | |||
} | } | |||
StringMapConstIterator operator++(int) { // Postincrement | StringMapConstIterator operator++(int) { // Postincrement | |||
StringMapConstIterator tmp = *this; ++*this; return tmp; | StringMapConstIterator tmp = *this; ++*this; return tmp; | |||
} | } | |||
private: | private: | |||
void AdvancePastEmptyBuckets() { | void AdvancePastEmptyBuckets() { | |||
End of changes. 6 change blocks. | ||||
4 lines changed or deleted | 9 lines changed or added | |||
StringMatcher.h | StringMatcher.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements the StringMatcher class. | // This file implements the StringMatcher class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef STRINGMATCHER_H | #ifndef LLVM_TABLEGEN_STRINGMATCHER_H | |||
#define STRINGMATCHER_H | #define LLVM_TABLEGEN_STRINGMATCHER_H | |||
#include <vector> | #include "llvm/ADT/StringRef.h" | |||
#include <string> | #include <string> | |||
#include <utility> | #include <utility> | |||
#include "llvm/ADT/StringRef.h" | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class raw_ostream; | class raw_ostream; | |||
/// StringMatcher - Given a list of strings and code to execute when they m atch, | /// StringMatcher - Given a list of strings and code to execute when they m atch, | |||
/// output a simple switch tree to classify the input string. | /// output a simple switch tree to classify the input string. | |||
/// | /// | |||
/// If a match is found, the code in Vals[i].second is executed; control mu st | /// If a match is found, the code in Vals[i].second is executed; control mu st | |||
/// not exit this code fragment. If nothing matches, execution falls throu gh. | /// not exit this code fragment. If nothing matches, execution falls throu gh. | |||
/// | /// | |||
End of changes. 3 change blocks. | ||||
4 lines changed or deleted | 4 lines changed or added | |||
StringPool.h | StringPool.h | |||
---|---|---|---|---|
skipping to change at line 33 | skipping to change at line 33 | |||
// Pooled strings are immutable, but you can change a PooledStringPtr to po int | // Pooled strings are immutable, but you can change a PooledStringPtr to po int | |||
// to another instance. So that interned strings can eventually be freed, | // to another instance. So that interned strings can eventually be freed, | |||
// strings in the string pool are reference-counted (automatically). | // strings in the string pool are reference-counted (automatically). | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_STRINGPOOL_H | #ifndef LLVM_SUPPORT_STRINGPOOL_H | |||
#define LLVM_SUPPORT_STRINGPOOL_H | #define LLVM_SUPPORT_STRINGPOOL_H | |||
#include "llvm/ADT/StringMap.h" | #include "llvm/ADT/StringMap.h" | |||
#include <new> | ||||
#include <cassert> | #include <cassert> | |||
#include <new> | ||||
namespace llvm { | namespace llvm { | |||
class PooledStringPtr; | class PooledStringPtr; | |||
/// StringPool - An interned string pool. Use the intern method to add a | /// StringPool - An interned string pool. Use the intern method to add a | |||
/// string. Strings are removed automatically as PooledStringPtrs are | /// string. Strings are removed automatically as PooledStringPtrs are | |||
/// destroyed. | /// destroyed. | |||
class StringPool { | class StringPool { | |||
/// PooledString - This is the value of an entry in the pool's internin g | /// PooledString - This is the value of an entry in the pool's internin g | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
StringRef.h | StringRef.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_STRINGREF_H | #ifndef LLVM_ADT_STRINGREF_H | |||
#define LLVM_ADT_STRINGREF_H | #define LLVM_ADT_STRINGREF_H | |||
#include "llvm/Support/type_traits.h" | #include "llvm/Support/type_traits.h" | |||
#include <algorithm> | #include <algorithm> | |||
#include <cassert> | #include <cassert> | |||
#include <cstring> | #include <cstring> | |||
#include <limits> | #include <limits> | |||
#include <string> | #include <string> | |||
#include <utility> | #include <utility> | |||
namespace llvm { | namespace llvm { | |||
template<typename T> | template<typename T> | |||
class SmallVectorImpl; | class SmallVectorImpl; | |||
skipping to change at line 264 | skipping to change at line 263 | |||
} | } | |||
/// Search for the last string \p Str in the string. | /// Search for the last string \p Str in the string. | |||
/// | /// | |||
/// \returns The index of the last occurrence of \p Str, or npos if not | /// \returns The index of the last occurrence of \p Str, or npos if not | |||
/// found. | /// found. | |||
size_t rfind(StringRef Str) const; | size_t rfind(StringRef Str) const; | |||
/// Find the first character in the string that is \p C, or npos if not | /// Find the first character in the string that is \p C, or npos if not | |||
/// found. Same as find. | /// found. Same as find. | |||
size_type find_first_of(char C, size_t From = 0) const { | size_t find_first_of(char C, size_t From = 0) const { | |||
return find(C, From); | return find(C, From); | |||
} | } | |||
/// Find the first character in the string that is in \p Chars, or npos if | /// Find the first character in the string that is in \p Chars, or npos if | |||
/// not found. | /// not found. | |||
/// | /// | |||
/// Complexity: O(size() + Chars.size()) | /// Complexity: O(size() + Chars.size()) | |||
size_type find_first_of(StringRef Chars, size_t From = 0) const; | size_t find_first_of(StringRef Chars, size_t From = 0) const; | |||
/// Find the first character in the string that is not \p C or npos if not | /// Find the first character in the string that is not \p C or npos if not | |||
/// found. | /// found. | |||
size_type find_first_not_of(char C, size_t From = 0) const; | size_t find_first_not_of(char C, size_t From = 0) const; | |||
/// Find the first character in the string that is not in the string | /// Find the first character in the string that is not in the string | |||
/// \p Chars, or npos if not found. | /// \p Chars, or npos if not found. | |||
/// | /// | |||
/// Complexity: O(size() + Chars.size()) | /// Complexity: O(size() + Chars.size()) | |||
size_type find_first_not_of(StringRef Chars, size_t From = 0) const; | size_t find_first_not_of(StringRef Chars, size_t From = 0) const; | |||
/// Find the last character in the string that is \p C, or npos if not | /// Find the last character in the string that is \p C, or npos if not | |||
/// found. | /// found. | |||
size_type find_last_of(char C, size_t From = npos) const { | size_t find_last_of(char C, size_t From = npos) const { | |||
return rfind(C, From); | return rfind(C, From); | |||
} | } | |||
/// Find the last character in the string that is in \p C, or npos if n ot | /// Find the last character in the string that is in \p C, or npos if n ot | |||
/// found. | /// found. | |||
/// | /// | |||
/// Complexity: O(size() + Chars.size()) | /// Complexity: O(size() + Chars.size()) | |||
size_type find_last_of(StringRef Chars, size_t From = npos) const; | size_t find_last_of(StringRef Chars, size_t From = npos) const; | |||
/// Find the last character in the string that is not \p C, or npos if not | /// Find the last character in the string that is not \p C, or npos if not | |||
/// found. | /// found. | |||
size_type find_last_not_of(char C, size_t From = npos) const; | size_t find_last_not_of(char C, size_t From = npos) const; | |||
/// Find the last character in the string that is not in \p Chars, or | /// Find the last character in the string that is not in \p Chars, or | |||
/// npos if not found. | /// npos if not found. | |||
/// | /// | |||
/// Complexity: O(size() + Chars.size()) | /// Complexity: O(size() + Chars.size()) | |||
size_type find_last_not_of(StringRef Chars, size_t From = npos) const; | size_t find_last_not_of(StringRef Chars, size_t From = npos) const; | |||
/// @} | /// @} | |||
/// @name Helpful Algorithms | /// @name Helpful Algorithms | |||
/// @{ | /// @{ | |||
/// Return the number of occurrences of \p C in the string. | /// Return the number of occurrences of \p C in the string. | |||
size_t count(char C) const { | size_t count(char C) const { | |||
size_t Count = 0; | size_t Count = 0; | |||
for (size_t i = 0, e = Length; i != e; ++i) | for (size_t i = 0, e = Length; i != e; ++i) | |||
if (Data[i] == C) | if (Data[i] == C) | |||
skipping to change at line 394 | skipping to change at line 393 | |||
/// \param N The number of characters to included in the substring. If N | /// \param N The number of characters to included in the substring. If N | |||
/// exceeds the number of characters remaining in the string, the strin g | /// exceeds the number of characters remaining in the string, the strin g | |||
/// suffix (starting with \p Start) will be returned. | /// suffix (starting with \p Start) will be returned. | |||
StringRef substr(size_t Start, size_t N = npos) const { | StringRef substr(size_t Start, size_t N = npos) const { | |||
Start = min(Start, Length); | Start = min(Start, Length); | |||
return StringRef(Data + Start, min(N, Length - Start)); | return StringRef(Data + Start, min(N, Length - Start)); | |||
} | } | |||
/// Return a StringRef equal to 'this' but with the first \p N elements | /// Return a StringRef equal to 'this' but with the first \p N elements | |||
/// dropped. | /// dropped. | |||
StringRef drop_front(unsigned N = 1) const { | StringRef drop_front(size_t N = 1) const { | |||
assert(size() >= N && "Dropping more elements than exist"); | assert(size() >= N && "Dropping more elements than exist"); | |||
return substr(N); | return substr(N); | |||
} | } | |||
/// Return a StringRef equal to 'this' but with the last \p N elements | /// Return a StringRef equal to 'this' but with the last \p N elements | |||
/// dropped. | /// dropped. | |||
StringRef drop_back(unsigned N = 1) const { | StringRef drop_back(size_t N = 1) const { | |||
assert(size() >= N && "Dropping more elements than exist"); | assert(size() >= N && "Dropping more elements than exist"); | |||
return substr(0, size()-N); | return substr(0, size()-N); | |||
} | } | |||
/// Return a reference to the substring from [Start, End). | /// Return a reference to the substring from [Start, End). | |||
/// | /// | |||
/// \param Start The index of the starting character in the substring; if | /// \param Start The index of the starting character in the substring; if | |||
/// the index is npos or greater than the length of the string then the | /// the index is npos or greater than the length of the string then the | |||
/// empty substring will be returned. | /// empty substring will be returned. | |||
/// | /// | |||
skipping to change at line 539 | skipping to change at line 538 | |||
} | } | |||
inline bool operator>(StringRef LHS, StringRef RHS) { | inline bool operator>(StringRef LHS, StringRef RHS) { | |||
return LHS.compare(RHS) == 1; | return LHS.compare(RHS) == 1; | |||
} | } | |||
inline bool operator>=(StringRef LHS, StringRef RHS) { | inline bool operator>=(StringRef LHS, StringRef RHS) { | |||
return LHS.compare(RHS) != -1; | return LHS.compare(RHS) != -1; | |||
} | } | |||
inline std::string &operator+=(std::string &buffer, llvm::StringRef strin g) { | inline std::string &operator+=(std::string &buffer, StringRef string) { | |||
return buffer.append(string.data(), string.size()); | return buffer.append(string.data(), string.size()); | |||
} | } | |||
/// @} | /// @} | |||
/// \brief Compute a hash_code for a StringRef. | /// \brief Compute a hash_code for a StringRef. | |||
hash_code hash_value(StringRef S); | hash_code hash_value(StringRef S); | |||
// StringRefs can be treated like a POD type. | // StringRefs can be treated like a POD type. | |||
template <typename T> struct isPodLike; | template <typename T> struct isPodLike; | |||
End of changes. 12 change blocks. | ||||
12 lines changed or deleted | 11 lines changed or added | |||
StringSet.h | StringSet.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_STRINGSET_H | #ifndef LLVM_ADT_STRINGSET_H | |||
#define LLVM_ADT_STRINGSET_H | #define LLVM_ADT_STRINGSET_H | |||
#include "llvm/ADT/StringMap.h" | #include "llvm/ADT/StringMap.h" | |||
namespace llvm { | namespace llvm { | |||
/// StringSet - A wrapper for StringMap that provides set-like | /// StringSet - A wrapper for StringMap that provides set-like functional | |||
/// functionality. Only insert() and count() methods are used by my | ity. | |||
/// code. | ||||
template <class AllocatorTy = llvm::MallocAllocator> | template <class AllocatorTy = llvm::MallocAllocator> | |||
class StringSet : public llvm::StringMap<char, AllocatorTy> { | class StringSet : public llvm::StringMap<char, AllocatorTy> { | |||
typedef llvm::StringMap<char, AllocatorTy> base; | typedef llvm::StringMap<char, AllocatorTy> base; | |||
public: | public: | |||
bool insert(StringRef InLang) { | ||||
assert(!InLang.empty()); | /// insert - Insert the specified key into the set. If the key already | |||
const char *KeyStart = InLang.data(); | /// exists in the set, return false and ignore the request, otherwise i | |||
const char *KeyEnd = KeyStart + InLang.size(); | nsert | |||
llvm::StringMapEntry<char> *Entry = llvm::StringMapEntry<char>:: | /// it and return true. | |||
Create(KeyStart, KeyEnd, base::getAllocator(), | bool insert(StringRef Key) { | |||
'+'); | // Get or create the map entry for the key; if it doesn't exist the v | |||
if (!base::insert(Entry)) { | alue | |||
Entry->Destroy(base::getAllocator()); | // type will be default constructed which we use to detect insert. | |||
// | ||||
// We use '+' as the sentinel value in the map. | ||||
assert(!Key.empty()); | ||||
StringMapEntry<char> &Entry = this->GetOrCreateValue(Key); | ||||
if (Entry.getValue() == '+') | ||||
return false; | return false; | |||
} | Entry.setValue('+'); | |||
return true; | return true; | |||
} | } | |||
}; | }; | |||
} | } | |||
#endif // LLVM_ADT_STRINGSET_H | #endif // LLVM_ADT_STRINGSET_H | |||
End of changes. 3 change blocks. | ||||
13 lines changed or deleted | 17 lines changed or added | |||
SubtargetFeature.h | SubtargetFeature.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// The intent is to be able to package specific features that should or sho uld | // The intent is to be able to package specific features that should or sho uld | |||
// not be used on a specific target processor. A tool, such as llc, could, as | // not be used on a specific target processor. A tool, such as llc, could, as | |||
// as example, gather chip info from the command line, a long with features | // as example, gather chip info from the command line, a long with features | |||
// that should be used on that chip. | // that should be used on that chip. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_MC_SUBTARGETFEATURE_H | #ifndef LLVM_MC_SUBTARGETFEATURE_H | |||
#define LLVM_MC_SUBTARGETFEATURE_H | #define LLVM_MC_SUBTARGETFEATURE_H | |||
#include <vector> | ||||
#include "llvm/ADT/Triple.h" | #include "llvm/ADT/Triple.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
class raw_ostream; | class raw_ostream; | |||
class StringRef; | class StringRef; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// | /// | |||
/// SubtargetFeatureKV - Used to provide key value pairs for feature and | /// SubtargetFeatureKV - Used to provide key value pairs for feature and | |||
/// CPU bit flags. | /// CPU bit flags. | |||
// | // | |||
skipping to change at line 65 | skipping to change at line 65 | |||
// Compare routine for std binary search | // Compare routine for std binary search | |||
bool operator<(const SubtargetInfoKV &S) const { | bool operator<(const SubtargetInfoKV &S) const { | |||
return strcmp(Key, S.Key) < 0; | return strcmp(Key, S.Key) < 0; | |||
} | } | |||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// | /// | |||
/// SubtargetFeatures - Manages the enabling and disabling of subtarget | /// SubtargetFeatures - Manages the enabling and disabling of subtarget | |||
/// specific features. Features are encoded as a string of the form | /// specific features. Features are encoded as a string of the form | |||
/// "cpu,+attr1,+attr2,-attr3,...,+attrN" | /// "+attr1,+attr2,-attr3,...,+attrN" | |||
/// A comma separates each feature from the next (all lowercase.) | /// A comma separates each feature from the next (all lowercase.) | |||
/// The first feature is always the CPU subtype (eg. pentiumm). If the CPU | ||||
/// value is "generic" then the CPU subtype should be generic for the targe | ||||
t. | ||||
/// Each of the remaining features is prefixed with + or - indicating wheth er | /// Each of the remaining features is prefixed with + or - indicating wheth er | |||
/// that feature should be enabled or disabled contrary to the cpu | /// that feature should be enabled or disabled contrary to the cpu | |||
/// specification. | /// specification. | |||
/// | /// | |||
class SubtargetFeatures { | class SubtargetFeatures { | |||
std::vector<std::string> Features; // Subtarget features as a vector | std::vector<std::string> Features; // Subtarget features as a vector | |||
public: | public: | |||
explicit SubtargetFeatures(const StringRef Initial = ""); | explicit SubtargetFeatures(const StringRef Initial = ""); | |||
End of changes. 4 change blocks. | ||||
5 lines changed or deleted | 2 lines changed or added | |||
SwapByteOrder.h | SwapByteOrder.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares generic and optimized functions to swap the byte orde r of | // This file declares generic and optimized functions to swap the byte orde r of | |||
// an integral type. | // an integral type. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_SWAP_BYTE_ORDER_H | #ifndef LLVM_SUPPORT_SWAPBYTEORDER_H | |||
#define LLVM_SYSTEM_SWAP_BYTE_ORDER_H | #define LLVM_SUPPORT_SWAPBYTEORDER_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <cstddef> | #include <cstddef> | |||
#include <limits> | #include <limits> | |||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
/// SwapByteOrder_16 - This function returns a byte-swapped representation of | /// SwapByteOrder_16 - This function returns a byte-swapped representation of | |||
/// the 16-bit argument. | /// the 16-bit argument. | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
SymbolTableListTraits.h | SymbolTableListTraits.h | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
// intrusive list that makes up the list of instructions in a basic block. When | // intrusive list that makes up the list of instructions in a basic block. When | |||
// a new element is added to the list of instructions, the traits class is | // a new element is added to the list of instructions, the traits class is | |||
// notified, allowing the symbol table to be updated. | // notified, allowing the symbol table to be updated. | |||
// | // | |||
// This generic class implements the traits class. It must be generic so t hat | // This generic class implements the traits class. It must be generic so t hat | |||
// it can work for all uses it, which include lists of instructions, basic | // it can work for all uses it, which include lists of instructions, basic | |||
// blocks, arguments, functions, global variables, etc... | // blocks, arguments, functions, global variables, etc... | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYMBOLTABLELISTTRAITS_H | #ifndef LLVM_IR_SYMBOLTABLELISTTRAITS_H | |||
#define LLVM_SYMBOLTABLELISTTRAITS_H | #define LLVM_IR_SYMBOLTABLELISTTRAITS_H | |||
#include "llvm/ADT/ilist.h" | #include "llvm/ADT/ilist.h" | |||
namespace llvm { | namespace llvm { | |||
class ValueSymbolTable; | class ValueSymbolTable; | |||
template<typename NodeTy> class ilist_iterator; | template<typename NodeTy> class ilist_iterator; | |||
template<typename NodeTy, typename Traits> class iplist; | template<typename NodeTy, typename Traits> class iplist; | |||
template<typename Ty> struct ilist_traits; | template<typename Ty> struct ilist_traits; | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Target.h | Target.h | |||
---|---|---|---|---|
skipping to change at line 238 | skipping to change at line 238 | |||
/** Deallocates a TargetData. | /** Deallocates a TargetData. | |||
See the destructor llvm::DataLayout::~DataLayout. */ | See the destructor llvm::DataLayout::~DataLayout. */ | |||
void LLVMDisposeTargetData(LLVMTargetDataRef); | void LLVMDisposeTargetData(LLVMTargetDataRef); | |||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} | } | |||
namespace llvm { | ||||
class DataLayout; | ||||
class TargetLibraryInfo; | ||||
inline DataLayout *unwrap(LLVMTargetDataRef P) { | ||||
return reinterpret_cast<DataLayout*>(P); | ||||
} | ||||
inline LLVMTargetDataRef wrap(const DataLayout *P) { | ||||
return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P)); | ||||
} | ||||
inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) { | ||||
return reinterpret_cast<TargetLibraryInfo*>(P); | ||||
} | ||||
inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) { | ||||
TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P); | ||||
return reinterpret_cast<LLVMTargetLibraryInfoRef>(X); | ||||
} | ||||
} | ||||
#endif /* defined(__cplusplus) */ | #endif /* defined(__cplusplus) */ | |||
#endif | #endif | |||
End of changes. 1 change blocks. | ||||
23 lines changed or deleted | 0 lines changed or added | |||
Target.td | Target.td | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the target-independent interfaces which should be | // This file defines the target-independent interfaces which should be | |||
// implemented by each target which is using a TableGen based code generato r. | // implemented by each target which is using a TableGen based code generato r. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Include all information about LLVM intrinsics. | // Include all information about LLVM intrinsics. | |||
include "llvm/Intrinsics.td" | include "llvm/IR/Intrinsics.td" | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// Register file description - These classes are used to fill in the target | // Register file description - These classes are used to fill in the target | |||
// description classes. | // description classes. | |||
class RegisterClass; // Forward def | class RegisterClass; // Forward def | |||
// SubRegIndex - Use instances of SubRegIndex to identify subregisters. | // SubRegIndex - Use instances of SubRegIndex to identify subregisters. | |||
class SubRegIndex<list<SubRegIndex> comps = []> { | class SubRegIndex<list<SubRegIndex> comps = []> { | |||
string Namespace = ""; | string Namespace = ""; | |||
skipping to change at line 369 | skipping to change at line 369 | |||
bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement ? | bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement ? | |||
bit isPseudo = 0; // Is this instruction a pseudo-instruction? | bit isPseudo = 0; // Is this instruction a pseudo-instruction? | |||
// If so, won't have encoding information for | // If so, won't have encoding information for | |||
// the [MC]CodeEmitter stuff. | // the [MC]CodeEmitter stuff. | |||
// Side effect flags - When set, the flags have these meanings: | // Side effect flags - When set, the flags have these meanings: | |||
// | // | |||
// hasSideEffects - The instruction has side effects that are not | // hasSideEffects - The instruction has side effects that are not | |||
// captured by any operands of the instruction or other flags. | // captured by any operands of the instruction or other flags. | |||
// | // | |||
// neverHasSideEffects - Set on an instruction with no pattern if it has | // neverHasSideEffects (deprecated) - Set on an instruction with no patt | |||
no | ern | |||
// side effects. | // if it has no side effects. This is now equivalent to setting | |||
// "hasSideEffects = 0". | ||||
bit hasSideEffects = ?; | bit hasSideEffects = ?; | |||
bit neverHasSideEffects = 0; | bit neverHasSideEffects = 0; | |||
// Is this instruction a "real" instruction (with a distinct machine | // Is this instruction a "real" instruction (with a distinct machine | |||
// encoding), or is it a pseudo instruction used for codegen modeling | // encoding), or is it a pseudo instruction used for codegen modeling | |||
// purposes. | // purposes. | |||
// FIXME: For now this is distinct from isPseudo, above, as code-gen-only | // FIXME: For now this is distinct from isPseudo, above, as code-gen-only | |||
// instructions can (and often do) still have encoding information | // instructions can (and often do) still have encoding information | |||
// associated with them. Once we've migrated all of them over to true | // associated with them. Once we've migrated all of them over to true | |||
// pseudo-instructions that are lowered to real instructions prior to | // pseudo-instructions that are lowered to real instructions prior to | |||
skipping to change at line 398 | skipping to change at line 399 | |||
// CodeEmitter unchanged, but duplicates a canonical instruction | // CodeEmitter unchanged, but duplicates a canonical instruction | |||
// definition's encoding and should be ignored when constructing the | // definition's encoding and should be ignored when constructing the | |||
// assembler match tables. | // assembler match tables. | |||
bit isCodeGenOnly = 0; | bit isCodeGenOnly = 0; | |||
// Is this instruction a pseudo instruction for use by the assembler pars er. | // Is this instruction a pseudo instruction for use by the assembler pars er. | |||
bit isAsmParserOnly = 0; | bit isAsmParserOnly = 0; | |||
InstrItinClass Itinerary = NoItinerary;// Execution steps used for schedu ling. | InstrItinClass Itinerary = NoItinerary;// Execution steps used for schedu ling. | |||
// Scheduling information from TargetSchedule.td. | ||||
list<SchedReadWrite> SchedRW; | ||||
string Constraints = ""; // OperandConstraint, e.g. $src = $dst. | string Constraints = ""; // OperandConstraint, e.g. $src = $dst. | |||
/// DisableEncoding - List of operand names (e.g. "$op1,$op2") that shoul d not | /// DisableEncoding - List of operand names (e.g. "$op1,$op2") that shoul d not | |||
/// be encoded into the output machineinstr. | /// be encoded into the output machineinstr. | |||
string DisableEncoding = ""; | string DisableEncoding = ""; | |||
string PostEncoderMethod = ""; | string PostEncoderMethod = ""; | |||
string DecoderMethod = ""; | string DecoderMethod = ""; | |||
/// Target-specific flags. This becomes the TSFlags field in TargetInstrD esc. | /// Target-specific flags. This becomes the TSFlags field in TargetInstrD esc. | |||
skipping to change at line 785 | skipping to change at line 789 | |||
// AsmParserClassName - This specifies the suffix to use for the asmparse r | // AsmParserClassName - This specifies the suffix to use for the asmparse r | |||
// class. Generated AsmParser classes are always prefixed with the targe t | // class. Generated AsmParser classes are always prefixed with the targe t | |||
// name. | // name. | |||
string AsmParserClassName = "AsmParser"; | string AsmParserClassName = "AsmParser"; | |||
// AsmParserInstCleanup - If non-empty, this is the name of a custom memb er | // AsmParserInstCleanup - If non-empty, this is the name of a custom memb er | |||
// function of the AsmParser class to call on every matched instruction. | // function of the AsmParser class to call on every matched instruction. | |||
// This can be used to perform target specific instruction post-processin g. | // This can be used to perform target specific instruction post-processin g. | |||
string AsmParserInstCleanup = ""; | string AsmParserInstCleanup = ""; | |||
//ShouldEmitMatchRegisterName - Set to false if the target needs a hand | // ShouldEmitMatchRegisterName - Set to false if the target needs a hand | |||
//written register name matcher | // written register name matcher | |||
bit ShouldEmitMatchRegisterName = 1; | bit ShouldEmitMatchRegisterName = 1; | |||
} | } | |||
def DefaultAsmParser : AsmParser; | def DefaultAsmParser : AsmParser; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// AsmParserVariant - Subtargets can have multiple different assembly parse rs | // AsmParserVariant - Subtargets can have multiple different assembly parse rs | |||
// (e.g. AT&T vs Intel syntax on X86 for example). This class can be | // (e.g. AT&T vs Intel syntax on X86 for example). This class can be | |||
// implemented by targets to describe such variants. | // implemented by targets to describe such variants. | |||
// | // | |||
class AsmParserVariant { | class AsmParserVariant { | |||
// Variant - AsmParsers can be of multiple different variants. Variants are | // Variant - AsmParsers can be of multiple different variants. Variants are | |||
// used to support targets that need to parser multiple formats for the | // used to support targets that need to parser multiple formats for the | |||
// assembly language. | // assembly language. | |||
int Variant = 0; | int Variant = 0; | |||
// Name - The AsmParser variant name (e.g., AT&T vs Intel). | ||||
string Name = ""; | ||||
// CommentDelimiter - If given, the delimiter string used to recognize | // CommentDelimiter - If given, the delimiter string used to recognize | |||
// comments which are hard coded in the .td assembler strings for individ ual | // comments which are hard coded in the .td assembler strings for individ ual | |||
// instructions. | // instructions. | |||
string CommentDelimiter = ""; | string CommentDelimiter = ""; | |||
// RegisterPrefix - If given, the token prefix which indicates a register | // RegisterPrefix - If given, the token prefix which indicates a register | |||
// token. This is used by the matcher to automatically recognize hard cod ed | // token. This is used by the matcher to automatically recognize hard cod ed | |||
// register tokens as constrained registers, instead of tokens, for the | // register tokens as constrained registers, instead of tokens, for the | |||
// purposes of matching. | // purposes of matching. | |||
string RegisterPrefix = ""; | string RegisterPrefix = ""; | |||
skipping to change at line 855 | skipping to change at line 862 | |||
/// translated to a shl, so it can be handled with (in the case of X86, it | /// translated to a shl, so it can be handled with (in the case of X86, it | |||
/// actually has one for each suffix as well): | /// actually has one for each suffix as well): | |||
/// def : MnemonicAlias<"sal", "shl">; | /// def : MnemonicAlias<"sal", "shl">; | |||
/// | /// | |||
/// Mnemonic aliases are mapped before any other translation in the match p hase, | /// Mnemonic aliases are mapped before any other translation in the match p hase, | |||
/// and do allow Requires predicates, e.g.: | /// and do allow Requires predicates, e.g.: | |||
/// | /// | |||
/// def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>; | /// def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>; | |||
/// def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>; | /// def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>; | |||
/// | /// | |||
class MnemonicAlias<string From, string To> { | /// Mnemonic aliases can also be constrained to specific variants, e.g.: | |||
/// | ||||
/// def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]> | ||||
; | ||||
/// | ||||
/// If no variant (e.g., "att" or "intel") is specified then the alias is | ||||
/// applied unconditionally. | ||||
class MnemonicAlias<string From, string To, string VariantName = ""> { | ||||
string FromMnemonic = From; | string FromMnemonic = From; | |||
string ToMnemonic = To; | string ToMnemonic = To; | |||
string AsmVariantName = VariantName; | ||||
// Predicates - Predicates that must be true for this remapping to happen . | // Predicates - Predicates that must be true for this remapping to happen . | |||
list<Predicate> Predicates = []; | list<Predicate> Predicates = []; | |||
} | } | |||
/// InstAlias - This defines an alternate assembly syntax that is allowed t o | /// InstAlias - This defines an alternate assembly syntax that is allowed t o | |||
/// match an instruction that has a different (more canonical) assembly | /// match an instruction that has a different (more canonical) assembly | |||
/// representation. | /// representation. | |||
class InstAlias<string Asm, dag Result, bit Emit = 0b1> { | class InstAlias<string Asm, dag Result, bit Emit = 0b1> { | |||
string AsmString = Asm; // The .s format to match the instruction wi th. | string AsmString = Asm; // The .s format to match the instruction wi th. | |||
End of changes. 7 change blocks. | ||||
7 lines changed or deleted | 22 lines changed or added | |||
TargetCallingConv.h | TargetCallingConv.h | |||
---|---|---|---|---|
skipping to change at line 39 | skipping to change at line 39 | |||
static const uint64_t SExt = 1ULL<<1; ///< Sign extended | static const uint64_t SExt = 1ULL<<1; ///< Sign extended | |||
static const uint64_t SExtOffs = 1; | static const uint64_t SExtOffs = 1; | |||
static const uint64_t InReg = 1ULL<<2; ///< Passed in registe r | static const uint64_t InReg = 1ULL<<2; ///< Passed in registe r | |||
static const uint64_t InRegOffs = 2; | static const uint64_t InRegOffs = 2; | |||
static const uint64_t SRet = 1ULL<<3; ///< Hidden struct-ret ptr | static const uint64_t SRet = 1ULL<<3; ///< Hidden struct-ret ptr | |||
static const uint64_t SRetOffs = 3; | static const uint64_t SRetOffs = 3; | |||
static const uint64_t ByVal = 1ULL<<4; ///< Struct passed by value | static const uint64_t ByVal = 1ULL<<4; ///< Struct passed by value | |||
static const uint64_t ByValOffs = 4; | static const uint64_t ByValOffs = 4; | |||
static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain | static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain | |||
static const uint64_t NestOffs = 5; | static const uint64_t NestOffs = 5; | |||
static const uint64_t ByValAlign = 0xFULL << 6; ///< Struct alignme | static const uint64_t Returned = 1ULL<<6; ///< Always returned | |||
nt | static const uint64_t ReturnedOffs = 6; | |||
static const uint64_t ByValAlignOffs = 6; | static const uint64_t ByValAlign = 0xFULL<<7; ///< Struct alignment | |||
static const uint64_t Split = 1ULL << 10; | static const uint64_t ByValAlignOffs = 7; | |||
static const uint64_t SplitOffs = 10; | static const uint64_t Split = 1ULL<<11; | |||
static const uint64_t SplitOffs = 11; | ||||
static const uint64_t OrigAlign = 0x1FULL<<27; | static const uint64_t OrigAlign = 0x1FULL<<27; | |||
static const uint64_t OrigAlignOffs = 27; | static const uint64_t OrigAlignOffs = 27; | |||
static const uint64_t ByValSize = 0xffffffffULL << 32; ///< Struct size | static const uint64_t ByValSize = 0xffffffffULL<<32; ///< Struct s ize | |||
static const uint64_t ByValSizeOffs = 32; | static const uint64_t ByValSizeOffs = 32; | |||
static const uint64_t One = 1ULL; ///< 1 of this type, for s hifts | static const uint64_t One = 1ULL; ///< 1 of this type, for s hifts | |||
uint64_t Flags; | uint64_t Flags; | |||
public: | public: | |||
ArgFlagsTy() : Flags(0) { } | ArgFlagsTy() : Flags(0) { } | |||
bool isZExt() const { return Flags & ZExt; } | bool isZExt() const { return Flags & ZExt; } | |||
void setZExt() { Flags |= One << ZExtOffs; } | void setZExt() { Flags |= One << ZExtOffs; } | |||
bool isSExt() const { return Flags & SExt; } | bool isSExt() const { return Flags & SExt; } | |||
void setSExt() { Flags |= One << SExtOffs; } | void setSExt() { Flags |= One << SExtOffs; } | |||
bool isInReg() const { return Flags & InReg; } | bool isInReg() const { return Flags & InReg; } | |||
void setInReg() { Flags |= One << InRegOffs; } | void setInReg() { Flags |= One << InRegOffs; } | |||
bool isSRet() const { return Flags & SRet; } | bool isSRet() const { return Flags & SRet; } | |||
void setSRet() { Flags |= One << SRetOffs; } | void setSRet() { Flags |= One << SRetOffs; } | |||
bool isByVal() const { return Flags & ByVal; } | bool isByVal() const { return Flags & ByVal; } | |||
void setByVal() { Flags |= One << ByValOffs; } | void setByVal() { Flags |= One << ByValOffs; } | |||
bool isNest() const { return Flags & Nest; } | bool isNest() const { return Flags & Nest; } | |||
void setNest() { Flags |= One << NestOffs; } | void setNest() { Flags |= One << NestOffs; } | |||
bool isReturned() const { return Flags & Returned; } | ||||
void setReturned() { Flags |= One << ReturnedOffs; } | ||||
unsigned getByValAlign() const { | unsigned getByValAlign() const { | |||
return (unsigned) | return (unsigned) | |||
((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2); | ((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2); | |||
} | } | |||
void setByValAlign(unsigned A) { | void setByValAlign(unsigned A) { | |||
Flags = (Flags & ~ByValAlign) | | Flags = (Flags & ~ByValAlign) | | |||
(uint64_t(Log2_32(A) + 1) << ByValAlignOffs); | (uint64_t(Log2_32(A) + 1) << ByValAlignOffs); | |||
} | } | |||
skipping to change at line 100 | skipping to change at line 105 | |||
(uint64_t(Log2_32(A) + 1) << OrigAlignOffs); | (uint64_t(Log2_32(A) + 1) << OrigAlignOffs); | |||
} | } | |||
unsigned getByValSize() const { | unsigned getByValSize() const { | |||
return (unsigned)((Flags & ByValSize) >> ByValSizeOffs); | return (unsigned)((Flags & ByValSize) >> ByValSizeOffs); | |||
} | } | |||
void setByValSize(unsigned S) { | void setByValSize(unsigned S) { | |||
Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs); | Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs); | |||
} | } | |||
/// getArgFlagsString - Returns the flags as a string, eg: "zext align: | ||||
4". | ||||
std::string getArgFlagsString(); | ||||
/// getRawBits - Represent the flags as a bunch of bits. | /// getRawBits - Represent the flags as a bunch of bits. | |||
uint64_t getRawBits() const { return Flags; } | uint64_t getRawBits() const { return Flags; } | |||
}; | }; | |||
/// InputArg - This struct carries flags and type information about a | /// InputArg - This struct carries flags and type information about a | |||
/// single incoming (formal) argument or incoming (from the perspective | /// single incoming (formal) argument or incoming (from the perspective | |||
/// of the caller) return value virtual register. | /// of the caller) return value virtual register. | |||
/// | /// | |||
struct InputArg { | struct InputArg { | |||
ArgFlagsTy Flags; | ArgFlagsTy Flags; | |||
End of changes. 9 change blocks. | ||||
22 lines changed or deleted | 22 lines changed or added | |||
TargetFolder.h | TargetFolder.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// target dependent folding, in addition to the same target-independent | // target dependent folding, in addition to the same target-independent | |||
// folding that the ConstantFolder class provides. For general constant | // folding that the ConstantFolder class provides. For general constant | |||
// creation and folding, use ConstantExpr and the routines in | // creation and folding, use ConstantExpr and the routines in | |||
// llvm/Analysis/ConstantFolding.h. | // llvm/Analysis/ConstantFolding.h. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_TARGETFOLDER_H | #ifndef LLVM_SUPPORT_TARGETFOLDER_H | |||
#define LLVM_SUPPORT_TARGETFOLDER_H | #define LLVM_SUPPORT_TARGETFOLDER_H | |||
#include "llvm/Constants.h" | ||||
#include "llvm/InstrTypes.h" | ||||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/Analysis/ConstantFolding.h" | #include "llvm/Analysis/ConstantFolding.h" | |||
#include "llvm/IR/Constants.h" | ||||
#include "llvm/IR/InstrTypes.h" | ||||
namespace llvm { | namespace llvm { | |||
class DataLayout; | class DataLayout; | |||
/// TargetFolder - Create constants with target dependent folding. | /// TargetFolder - Create constants with target dependent folding. | |||
class TargetFolder { | class TargetFolder { | |||
const DataLayout *TD; | const DataLayout *TD; | |||
/// Fold - Fold the constant using target specific information. | /// Fold - Fold the constant using target specific information. | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
TargetFrameLowering.h | TargetFrameLowering.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// Interface to describe the layout of a stack frame on the target machine. | // Interface to describe the layout of a stack frame on the target machine. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TARGET_TARGETFRAMELOWERING_H | #ifndef LLVM_TARGET_TARGETFRAMELOWERING_H | |||
#define LLVM_TARGET_TARGETFRAMELOWERING_H | #define LLVM_TARGET_TARGETFRAMELOWERING_H | |||
#include "llvm/CodeGen/MachineBasicBlock.h" | #include "llvm/CodeGen/MachineBasicBlock.h" | |||
#include <utility> | #include <utility> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class CalleeSavedInfo; | class CalleeSavedInfo; | |||
class MachineFunction; | class MachineFunction; | |||
class RegScavenger; | class RegScavenger; | |||
/// Information about stack frame layout on the target. It holds the direc tion | /// Information about stack frame layout on the target. It holds the direc tion | |||
/// of stack growth, the known stack alignment on entry to each function, a nd | /// of stack growth, the known stack alignment on entry to each function, a nd | |||
skipping to change at line 51 | skipping to change at line 50 | |||
// Maps a callee saved register to a stack slot with a fixed offset. | // Maps a callee saved register to a stack slot with a fixed offset. | |||
struct SpillSlot { | struct SpillSlot { | |||
unsigned Reg; | unsigned Reg; | |||
int Offset; // Offset relative to stack pointer on function entry. | int Offset; // Offset relative to stack pointer on function entry. | |||
}; | }; | |||
private: | private: | |||
StackDirection StackDir; | StackDirection StackDir; | |||
unsigned StackAlignment; | unsigned StackAlignment; | |||
unsigned TransientStackAlignment; | unsigned TransientStackAlignment; | |||
int LocalAreaOffset; | int LocalAreaOffset; | |||
bool StackRealignable; | ||||
public: | public: | |||
TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO, | TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO, | |||
unsigned TransAl = 1) | unsigned TransAl = 1, bool StackReal = true) | |||
: StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl ), | : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl ), | |||
LocalAreaOffset(LAO) {} | LocalAreaOffset(LAO), StackRealignable(StackReal) {} | |||
virtual ~TargetFrameLowering(); | virtual ~TargetFrameLowering(); | |||
// These methods return information that describes the abstract stack lay out | // These methods return information that describes the abstract stack lay out | |||
// of the target machine. | // of the target machine. | |||
/// getStackGrowthDirection - Return the direction the stack grows | /// getStackGrowthDirection - Return the direction the stack grows | |||
/// | /// | |||
StackDirection getStackGrowthDirection() const { return StackDir; } | StackDirection getStackGrowthDirection() const { return StackDir; } | |||
skipping to change at line 80 | skipping to change at line 80 | |||
unsigned getStackAlignment() const { return StackAlignment; } | unsigned getStackAlignment() const { return StackAlignment; } | |||
/// getTransientStackAlignment - This method returns the number of bytes to | /// getTransientStackAlignment - This method returns the number of bytes to | |||
/// which the stack pointer must be aligned at all times, even between | /// which the stack pointer must be aligned at all times, even between | |||
/// calls. | /// calls. | |||
/// | /// | |||
unsigned getTransientStackAlignment() const { | unsigned getTransientStackAlignment() const { | |||
return TransientStackAlignment; | return TransientStackAlignment; | |||
} | } | |||
/// isStackRealignable - This method returns whether the stack can be | ||||
/// realigned. | ||||
bool isStackRealignable() const { | ||||
return StackRealignable; | ||||
} | ||||
/// getOffsetOfLocalArea - This method returns the offset of the local ar ea | /// getOffsetOfLocalArea - This method returns the offset of the local ar ea | |||
/// from the stack pointer on entrance to a function. | /// from the stack pointer on entrance to a function. | |||
/// | /// | |||
int getOffsetOfLocalArea() const { return LocalAreaOffset; } | int getOffsetOfLocalArea() const { return LocalAreaOffset; } | |||
/// getCalleeSavedSpillSlots - This method returns a pointer to an array of | /// getCalleeSavedSpillSlots - This method returns a pointer to an array of | |||
/// pairs, that contains an entry for each callee saved register that mus t be | /// pairs, that contains an entry for each callee saved register that mus t be | |||
/// spilled to a particular stack location if it is spilled. | /// spilled to a particular stack location if it is spilled. | |||
/// | /// | |||
/// Each entry in this array contains a <register,offset> pair, indicatin g the | /// Each entry in this array contains a <register,offset> pair, indicatin g the | |||
skipping to change at line 117 | skipping to change at line 123 | |||
/// emitProlog/emitEpilog - These methods insert prolog and epilog code i nto | /// emitProlog/emitEpilog - These methods insert prolog and epilog code i nto | |||
/// the function. | /// the function. | |||
virtual void emitPrologue(MachineFunction &MF) const = 0; | virtual void emitPrologue(MachineFunction &MF) const = 0; | |||
virtual void emitEpilogue(MachineFunction &MF, | virtual void emitEpilogue(MachineFunction &MF, | |||
MachineBasicBlock &MBB) const = 0; | MachineBasicBlock &MBB) const = 0; | |||
/// Adjust the prologue to have the function use segmented stacks. This w orks | /// Adjust the prologue to have the function use segmented stacks. This w orks | |||
/// by adding a check even before the "normal" function prologue. | /// by adding a check even before the "normal" function prologue. | |||
virtual void adjustForSegmentedStacks(MachineFunction &MF) const { } | virtual void adjustForSegmentedStacks(MachineFunction &MF) const { } | |||
/// Adjust the prologue to add Erlang Run-Time System (ERTS) specific cod | ||||
e in | ||||
/// the assembly prologue to explicitly handle the stack. | ||||
virtual void adjustForHiPEPrologue(MachineFunction &MF) const { } | ||||
/// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee | /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee | |||
/// saved registers and returns true if it isn't possible / profitable to do | /// saved registers and returns true if it isn't possible / profitable to do | |||
/// so by issuing a series of store instructions via | /// so by issuing a series of store instructions via | |||
/// storeRegToStackSlot(). Returns false otherwise. | /// storeRegToStackSlot(). Returns false otherwise. | |||
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, | virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, | |||
MachineBasicBlock::iterator MI, | MachineBasicBlock::iterator MI, | |||
const std::vector<CalleeSavedInfo> &CSI, | const std::vector<CalleeSavedInfo> &CSI, | |||
const TargetRegisterInfo *TRI) con st { | const TargetRegisterInfo *TRI) con st { | |||
return false; | return false; | |||
} | } | |||
skipping to change at line 187 | skipping to change at line 197 | |||
virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, | virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, | |||
RegScavenger *RS = NULL) co nst { | RegScavenger *RS = NULL) co nst { | |||
} | } | |||
/// processFunctionBeforeFrameFinalized - This method is called immediate ly | /// processFunctionBeforeFrameFinalized - This method is called immediate ly | |||
/// before the specified function's frame layout (MF.getFrameInfo()) is | /// before the specified function's frame layout (MF.getFrameInfo()) is | |||
/// finalized. Once the frame is finalized, MO_FrameIndex operands are | /// finalized. Once the frame is finalized, MO_FrameIndex operands are | |||
/// replaced with direct constants. This method is optional. | /// replaced with direct constants. This method is optional. | |||
/// | /// | |||
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) con | virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF, | |||
st { | RegScavenger *RS = NULL) con | |||
st { | ||||
} | ||||
/// eliminateCallFramePseudoInstr - This method is called during prolog/e | ||||
pilog | ||||
/// code insertion to eliminate call frame setup and destroy pseudo | ||||
/// instructions (but only if the Target is using them). It is responsib | ||||
le | ||||
/// for eliminating these instructions, replacing them with concrete | ||||
/// instructions. This method need only be implemented if using call fra | ||||
me | ||||
/// setup/destroy pseudo instructions. | ||||
/// | ||||
virtual void | ||||
eliminateCallFramePseudoInstr(MachineFunction &MF, | ||||
MachineBasicBlock &MBB, | ||||
MachineBasicBlock::iterator MI) const { | ||||
llvm_unreachable("Call Frame Pseudo Instructions do not exist on this " | ||||
"target!"); | ||||
} | } | |||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 7 change blocks. | ||||
5 lines changed or deleted | 35 lines changed or added | |||
TargetInstrInfo.h | TargetInstrInfo.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file describes the target machine instruction set to the code gener ator. | // This file describes the target machine instruction set to the code gener ator. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TARGET_TARGETINSTRINFO_H | #ifndef LLVM_TARGET_TARGETINSTRINFO_H | |||
#define LLVM_TARGET_TARGETINSTRINFO_H | #define LLVM_TARGET_TARGETINSTRINFO_H | |||
#include "llvm/ADT/SmallSet.h" | #include "llvm/ADT/SmallSet.h" | |||
#include "llvm/MC/MCInstrInfo.h" | ||||
#include "llvm/CodeGen/DFAPacketizer.h" | #include "llvm/CodeGen/DFAPacketizer.h" | |||
#include "llvm/CodeGen/MachineFunction.h" | #include "llvm/CodeGen/MachineFunction.h" | |||
#include "llvm/MC/MCInstrInfo.h" | ||||
namespace llvm { | namespace llvm { | |||
class InstrItineraryData; | class InstrItineraryData; | |||
class LiveVariables; | class LiveVariables; | |||
class MCAsmInfo; | class MCAsmInfo; | |||
class MachineMemOperand; | class MachineMemOperand; | |||
class MachineRegisterInfo; | class MachineRegisterInfo; | |||
class MDNode; | class MDNode; | |||
class MCInst; | class MCInst; | |||
skipping to change at line 145 | skipping to change at line 145 | |||
/// hasLoadFromStackSlot - If the specified machine instruction has | /// hasLoadFromStackSlot - If the specified machine instruction has | |||
/// a load from a stack slot, return true along with the FrameIndex | /// a load from a stack slot, return true along with the FrameIndex | |||
/// of the loaded stack slot and the machine mem operand containing | /// of the loaded stack slot and the machine mem operand containing | |||
/// the reference. If not, return false. Unlike | /// the reference. If not, return false. Unlike | |||
/// isLoadFromStackSlot, this returns true for any instructions that | /// isLoadFromStackSlot, this returns true for any instructions that | |||
/// loads from the stack. This is just a hint, as some cases may be | /// loads from the stack. This is just a hint, as some cases may be | |||
/// missed. | /// missed. | |||
virtual bool hasLoadFromStackSlot(const MachineInstr *MI, | virtual bool hasLoadFromStackSlot(const MachineInstr *MI, | |||
const MachineMemOperand *&MMO, | const MachineMemOperand *&MMO, | |||
int &FrameIndex) const { | int &FrameIndex) const; | |||
return 0; | ||||
} | ||||
/// isStoreToStackSlot - If the specified machine instruction is a direct | /// isStoreToStackSlot - If the specified machine instruction is a direct | |||
/// store to a stack slot, return the virtual or physical register number of | /// store to a stack slot, return the virtual or physical register number of | |||
/// the source reg along with the FrameIndex of the loaded stack slot. I f | /// the source reg along with the FrameIndex of the loaded stack slot. I f | |||
/// not, return 0. This predicate must return 0 if the instruction has | /// not, return 0. This predicate must return 0 if the instruction has | |||
/// any side effects other than storing to the stack slot. | /// any side effects other than storing to the stack slot. | |||
virtual unsigned isStoreToStackSlot(const MachineInstr *MI, | virtual unsigned isStoreToStackSlot(const MachineInstr *MI, | |||
int &FrameIndex) const { | int &FrameIndex) const { | |||
return 0; | return 0; | |||
} | } | |||
skipping to change at line 175 | skipping to change at line 173 | |||
} | } | |||
/// hasStoreToStackSlot - If the specified machine instruction has a | /// hasStoreToStackSlot - If the specified machine instruction has a | |||
/// store to a stack slot, return true along with the FrameIndex of | /// store to a stack slot, return true along with the FrameIndex of | |||
/// the loaded stack slot and the machine mem operand containing the | /// the loaded stack slot and the machine mem operand containing the | |||
/// reference. If not, return false. Unlike isStoreToStackSlot, | /// reference. If not, return false. Unlike isStoreToStackSlot, | |||
/// this returns true for any instructions that stores to the | /// this returns true for any instructions that stores to the | |||
/// stack. This is just a hint, as some cases may be missed. | /// stack. This is just a hint, as some cases may be missed. | |||
virtual bool hasStoreToStackSlot(const MachineInstr *MI, | virtual bool hasStoreToStackSlot(const MachineInstr *MI, | |||
const MachineMemOperand *&MMO, | const MachineMemOperand *&MMO, | |||
int &FrameIndex) const { | int &FrameIndex) const; | |||
return 0; | ||||
} | ||||
/// reMaterialize - Re-issue the specified 'original' instruction at the | /// reMaterialize - Re-issue the specified 'original' instruction at the | |||
/// specific location targeting a new destination register. | /// specific location targeting a new destination register. | |||
/// The register in Orig->getOperand(0).getReg() will be substituted by | /// The register in Orig->getOperand(0).getReg() will be substituted by | |||
/// DestReg:SubIdx. Any existing subreg index is preserved or composed wi th | /// DestReg:SubIdx. Any existing subreg index is preserved or composed wi th | |||
/// SubIdx. | /// SubIdx. | |||
virtual void reMaterialize(MachineBasicBlock &MBB, | virtual void reMaterialize(MachineBasicBlock &MBB, | |||
MachineBasicBlock::iterator MI, | MachineBasicBlock::iterator MI, | |||
unsigned DestReg, unsigned SubIdx, | unsigned DestReg, unsigned SubIdx, | |||
const MachineInstr *Orig, | const MachineInstr *Orig, | |||
const TargetRegisterInfo &TRI) const = 0; | const TargetRegisterInfo &TRI) const; | |||
/// duplicate - Create a duplicate of the Orig instruction in MF. This is like | /// duplicate - Create a duplicate of the Orig instruction in MF. This is like | |||
/// MachineFunction::CloneMachineInstr(), but the target may update opera nds | /// MachineFunction::CloneMachineInstr(), but the target may update opera nds | |||
/// that are required to be unique. | /// that are required to be unique. | |||
/// | /// | |||
/// The instruction must be duplicable as indicated by isNotDuplicable(). | /// The instruction must be duplicable as indicated by isNotDuplicable(). | |||
virtual MachineInstr *duplicate(MachineInstr *Orig, | virtual MachineInstr *duplicate(MachineInstr *Orig, | |||
MachineFunction &MF) const = 0; | MachineFunction &MF) const; | |||
/// convertToThreeAddress - This method must be implemented by targets th at | /// convertToThreeAddress - This method must be implemented by targets th at | |||
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the tar get | /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the tar get | |||
/// may be able to convert a two-address instruction into one or more tru e | /// may be able to convert a two-address instruction into one or more tru e | |||
/// three-address instructions on demand. This allows the X86 target (fo r | /// three-address instructions on demand. This allows the X86 target (fo r | |||
/// example) to convert ADD and SHL instructions into LEA instructions if they | /// example) to convert ADD and SHL instructions into LEA instructions if they | |||
/// would require register copies due to two-addressness. | /// would require register copies due to two-addressness. | |||
/// | /// | |||
/// This method returns a null pointer if the transformation cannot be | /// This method returns a null pointer if the transformation cannot be | |||
/// performed, otherwise it returns the last new instruction. | /// performed, otherwise it returns the last new instruction. | |||
skipping to change at line 223 | skipping to change at line 219 | |||
/// commuteInstruction - If a target has any instructions that are | /// commuteInstruction - If a target has any instructions that are | |||
/// commutable but require converting to different instructions or making | /// commutable but require converting to different instructions or making | |||
/// non-trivial changes to commute them, this method can overloaded to do | /// non-trivial changes to commute them, this method can overloaded to do | |||
/// that. The default implementation simply swaps the commutable operand s. | /// that. The default implementation simply swaps the commutable operand s. | |||
/// If NewMI is false, MI is modified in place and returned; otherwise, a | /// If NewMI is false, MI is modified in place and returned; otherwise, a | |||
/// new machine instruction is created and returned. Do not call this | /// new machine instruction is created and returned. Do not call this | |||
/// method for a non-commutable instruction, but there may be some cases | /// method for a non-commutable instruction, but there may be some cases | |||
/// where this method fails and returns null. | /// where this method fails and returns null. | |||
virtual MachineInstr *commuteInstruction(MachineInstr *MI, | virtual MachineInstr *commuteInstruction(MachineInstr *MI, | |||
bool NewMI = false) const = 0; | bool NewMI = false) const; | |||
/// findCommutedOpIndices - If specified MI is commutable, return the two | /// findCommutedOpIndices - If specified MI is commutable, return the two | |||
/// operand indices that would swap value. Return false if the instructio n | /// operand indices that would swap value. Return false if the instructio n | |||
/// is not in a form which this routine understands. | /// is not in a form which this routine understands. | |||
virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, | virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, | |||
unsigned &SrcOpIdx2) const = 0; | unsigned &SrcOpIdx2) const; | |||
/// produceSameValue - Return true if two machine instructions would prod uce | /// produceSameValue - Return true if two machine instructions would prod uce | |||
/// identical values. By default, this is only true when the two instruct ions | /// identical values. By default, this is only true when the two instruct ions | |||
/// are deemed identical except for defs. If this function is called when the | /// are deemed identical except for defs. If this function is called when the | |||
/// IR is still in SSA form, the caller can pass the MachineRegisterInfo for | /// IR is still in SSA form, the caller can pass the MachineRegisterInfo for | |||
/// aggressive checks. | /// aggressive checks. | |||
virtual bool produceSameValue(const MachineInstr *MI0, | virtual bool produceSameValue(const MachineInstr *MI0, | |||
const MachineInstr *MI1, | const MachineInstr *MI1, | |||
const MachineRegisterInfo *MRI = 0) const = 0; | const MachineRegisterInfo *MRI = 0) const; | |||
/// AnalyzeBranch - Analyze the branching code at the end of MBB, returni ng | /// AnalyzeBranch - Analyze the branching code at the end of MBB, returni ng | |||
/// true if it cannot be understood (e.g. it's a switch dispatch or isn't | /// true if it cannot be understood (e.g. it's a switch dispatch or isn't | |||
/// implemented for a target). Upon success, this returns false and retu rns | /// implemented for a target). Upon success, this returns false and retu rns | |||
/// with the following information in various cases: | /// with the following information in various cases: | |||
/// | /// | |||
/// 1. If this block ends with no branches (it just falls through to its succ) | /// 1. If this block ends with no branches (it just falls through to its succ) | |||
/// just return false, leaving TBB/FBB null. | /// just return false, leaving TBB/FBB null. | |||
/// 2. If this block ends with only an unconditional branch, it sets TBB to be | /// 2. If this block ends with only an unconditional branch, it sets TBB to be | |||
/// the destination block. | /// the destination block. | |||
skipping to change at line 300 | skipping to change at line 296 | |||
MachineBasicBlock *FBB, | MachineBasicBlock *FBB, | |||
const SmallVectorImpl<MachineOperand> &Cond , | const SmallVectorImpl<MachineOperand> &Cond , | |||
DebugLoc DL) const { | DebugLoc DL) const { | |||
llvm_unreachable("Target didn't implement TargetInstrInfo::InsertBranch !"); | llvm_unreachable("Target didn't implement TargetInstrInfo::InsertBranch !"); | |||
} | } | |||
/// ReplaceTailWithBranchTo - Delete the instruction OldInst and everythi ng | /// ReplaceTailWithBranchTo - Delete the instruction OldInst and everythi ng | |||
/// after it, replacing it with an unconditional branch to NewDest. This is | /// after it, replacing it with an unconditional branch to NewDest. This is | |||
/// used by the tail merging pass. | /// used by the tail merging pass. | |||
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, | virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, | |||
MachineBasicBlock *NewDest) const = 0; | MachineBasicBlock *NewDest) const; | |||
/// isLegalToSplitMBBAt - Return true if it's legal to split the given ba sic | /// isLegalToSplitMBBAt - Return true if it's legal to split the given ba sic | |||
/// block at the specified instruction (i.e. instruction would be the sta rt | /// block at the specified instruction (i.e. instruction would be the sta rt | |||
/// of a new basic block). | /// of a new basic block). | |||
virtual bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, | virtual bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, | |||
MachineBasicBlock::iterator MBBI) const { | MachineBasicBlock::iterator MBBI) const { | |||
return true; | return true; | |||
} | } | |||
/// isProfitableToIfCvt - Return true if it's profitable to predicate | /// isProfitableToIfCvt - Return true if it's profitable to predicate | |||
skipping to change at line 370 | skipping to change at line 366 | |||
virtual bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, | virtual bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, | |||
MachineBasicBlock &FMBB) const { | MachineBasicBlock &FMBB) const { | |||
return false; | return false; | |||
} | } | |||
/// canInsertSelect - Return true if it is possible to insert a select | /// canInsertSelect - Return true if it is possible to insert a select | |||
/// instruction that chooses between TrueReg and FalseReg based on the | /// instruction that chooses between TrueReg and FalseReg based on the | |||
/// condition code in Cond. | /// condition code in Cond. | |||
/// | /// | |||
/// When successful, also return the latency in cycles from TrueReg, | /// When successful, also return the latency in cycles from TrueReg, | |||
/// FalseReg, and Cond to the destination register. The Cond latency shou | /// FalseReg, and Cond to the destination register. In most cases, a sele | |||
ld | ct | |||
/// compensate for a conditional branch being removed. For example, if a | /// instruction will be 1 cycle, so CondCycles = TrueCycles = FalseCycles | |||
/// conditional branch has a 3 cycle latency from the condition code read | = 1 | |||
, | /// | |||
/// and a cmov instruction has a 2 cycle latency from the condition code | /// Some x86 implementations have 2-cycle cmov instructions. | |||
/// read, CondCycles should be returned as -1. | ||||
/// | /// | |||
/// @param MBB Block where select instruction would be inserted. | /// @param MBB Block where select instruction would be inserted. | |||
/// @param Cond Condition returned by AnalyzeBranch. | /// @param Cond Condition returned by AnalyzeBranch. | |||
/// @param TrueReg Virtual register to select when Cond is true. | /// @param TrueReg Virtual register to select when Cond is true. | |||
/// @param FalseReg Virtual register to select when Cond is false. | /// @param FalseReg Virtual register to select when Cond is false. | |||
/// @param CondCycles Latency from Cond+Branch to select output. | /// @param CondCycles Latency from Cond+Branch to select output. | |||
/// @param TrueCycles Latency from TrueReg to select output. | /// @param TrueCycles Latency from TrueReg to select output. | |||
/// @param FalseCycles Latency from FalseReg to select output. | /// @param FalseCycles Latency from FalseReg to select output. | |||
virtual bool canInsertSelect(const MachineBasicBlock &MBB, | virtual bool canInsertSelect(const MachineBasicBlock &MBB, | |||
const SmallVectorImpl<MachineOperand> &Cond, | const SmallVectorImpl<MachineOperand> &Cond, | |||
skipping to change at line 437 | skipping to change at line 432 | |||
/// @param MI Select instruction to analyze. | /// @param MI Select instruction to analyze. | |||
/// @param Cond Condition controlling the select. | /// @param Cond Condition controlling the select. | |||
/// @param TrueOp Operand number of the value selected when Cond is true . | /// @param TrueOp Operand number of the value selected when Cond is true . | |||
/// @param FalseOp Operand number of the value selected when Cond is fals e. | /// @param FalseOp Operand number of the value selected when Cond is fals e. | |||
/// @param Optimizable Returned as true if MI is optimizable. | /// @param Optimizable Returned as true if MI is optimizable. | |||
/// @returns False on success. | /// @returns False on success. | |||
virtual bool analyzeSelect(const MachineInstr *MI, | virtual bool analyzeSelect(const MachineInstr *MI, | |||
SmallVectorImpl<MachineOperand> &Cond, | SmallVectorImpl<MachineOperand> &Cond, | |||
unsigned &TrueOp, unsigned &FalseOp, | unsigned &TrueOp, unsigned &FalseOp, | |||
bool &Optimizable) const { | bool &Optimizable) const { | |||
assert(MI && MI->isSelect() && "MI must be a select instruction"); | assert(MI && MI->getDesc().isSelect() && "MI must be a select instructi on"); | |||
return true; | return true; | |||
} | } | |||
/// optimizeSelect - Given a select instruction that was understood by | /// optimizeSelect - Given a select instruction that was understood by | |||
/// analyzeSelect and returned Optimizable = true, attempt to optimize MI by | /// analyzeSelect and returned Optimizable = true, attempt to optimize MI by | |||
/// merging it with one of its operands. Returns NULL on failure. | /// merging it with one of its operands. Returns NULL on failure. | |||
/// | /// | |||
/// When successful, returns the new select instruction. The client is | /// When successful, returns the new select instruction. The client is | |||
/// responsible for deleting MI. | /// responsible for deleting MI. | |||
/// | /// | |||
skipping to change at line 571 | skipping to change at line 566 | |||
const SmallVectorImpl<unsigned> & Ops, | const SmallVectorImpl<unsigned> & Ops, | |||
MachineInstr* LoadMI) const { | MachineInstr* LoadMI) const { | |||
return 0; | return 0; | |||
} | } | |||
public: | public: | |||
/// canFoldMemoryOperand - Returns true for the specified load / store if | /// canFoldMemoryOperand - Returns true for the specified load / store if | |||
/// folding is possible. | /// folding is possible. | |||
virtual | virtual | |||
bool canFoldMemoryOperand(const MachineInstr *MI, | bool canFoldMemoryOperand(const MachineInstr *MI, | |||
const SmallVectorImpl<unsigned> &Ops) const =0; | const SmallVectorImpl<unsigned> &Ops) const; | |||
/// unfoldMemoryOperand - Separate a single instruction which folded a lo ad or | /// unfoldMemoryOperand - Separate a single instruction which folded a lo ad or | |||
/// a store or a load and a store into two or more instruction. If this i s | /// a store or a load and a store into two or more instruction. If this i s | |||
/// possible, returns true as well as the new instructions by reference. | /// possible, returns true as well as the new instructions by reference. | |||
virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, | virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, | |||
unsigned Reg, bool UnfoldLoad, bool UnfoldS tore, | unsigned Reg, bool UnfoldLoad, bool UnfoldS tore, | |||
SmallVectorImpl<MachineInstr*> &NewMIs) co nst{ | SmallVectorImpl<MachineInstr*> &NewMIs) co nst{ | |||
return false; | return false; | |||
} | } | |||
skipping to change at line 623 | skipping to change at line 618 | |||
/// together. This function takes two integers that represent the load of fsets | /// together. This function takes two integers that represent the load of fsets | |||
/// from the common base address. It returns true if it decides it's desi rable | /// from the common base address. It returns true if it decides it's desi rable | |||
/// to schedule the two loads together. "NumLoads" is the number of loads that | /// to schedule the two loads together. "NumLoads" is the number of loads that | |||
/// have already been scheduled after Load1. | /// have already been scheduled after Load1. | |||
virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, | virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, | |||
int64_t Offset1, int64_t Offset2, | int64_t Offset1, int64_t Offset2, | |||
unsigned NumLoads) const { | unsigned NumLoads) const { | |||
return false; | return false; | |||
} | } | |||
/// \brief Get the base register and byte offset of a load/store instr. | ||||
virtual bool getLdStBaseRegImmOfs(MachineInstr *LdSt, | ||||
unsigned &BaseReg, unsigned &Offset, | ||||
const TargetRegisterInfo *TRI) const { | ||||
return false; | ||||
} | ||||
virtual bool shouldClusterLoads(MachineInstr *FirstLdSt, | ||||
MachineInstr *SecondLdSt, | ||||
unsigned NumLoads) const { | ||||
return false; | ||||
} | ||||
/// \brief Can this target fuse the given instructions if they are schedu | ||||
led | ||||
/// adjacent. | ||||
virtual bool shouldScheduleAdjacent(MachineInstr* First, | ||||
MachineInstr *Second) const { | ||||
return false; | ||||
} | ||||
/// ReverseBranchCondition - Reverses the branch condition of the specifi ed | /// ReverseBranchCondition - Reverses the branch condition of the specifi ed | |||
/// condition list, returning false on success and true if it cannot be | /// condition list, returning false on success and true if it cannot be | |||
/// reversed. | /// reversed. | |||
virtual | virtual | |||
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { | bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { | |||
return true; | return true; | |||
} | } | |||
/// insertNoop - Insert a noop into the instruction stream at the specifi ed | /// insertNoop - Insert a noop into the instruction stream at the specifi ed | |||
/// point. | /// point. | |||
skipping to change at line 649 | skipping to change at line 664 | |||
} | } | |||
/// isPredicated - Returns true if the instruction is already predicated. | /// isPredicated - Returns true if the instruction is already predicated. | |||
/// | /// | |||
virtual bool isPredicated(const MachineInstr *MI) const { | virtual bool isPredicated(const MachineInstr *MI) const { | |||
return false; | return false; | |||
} | } | |||
/// isUnpredicatedTerminator - Returns true if the instruction is a | /// isUnpredicatedTerminator - Returns true if the instruction is a | |||
/// terminator instruction that has not been predicated. | /// terminator instruction that has not been predicated. | |||
virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const = 0; | virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; | |||
/// PredicateInstruction - Convert the instruction into a predicated | /// PredicateInstruction - Convert the instruction into a predicated | |||
/// instruction. It returns true if the operation was successful. | /// instruction. It returns true if the operation was successful. | |||
virtual | virtual | |||
bool PredicateInstruction(MachineInstr *MI, | bool PredicateInstruction(MachineInstr *MI, | |||
const SmallVectorImpl<MachineOperand> &Pred) const = 0; | const SmallVectorImpl<MachineOperand> &Pred) const; | |||
/// SubsumesPredicate - Returns true if the first specified predicate | /// SubsumesPredicate - Returns true if the first specified predicate | |||
/// subsumes the second, e.g. GE subsumes GT. | /// subsumes the second, e.g. GE subsumes GT. | |||
virtual | virtual | |||
bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, | bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, | |||
const SmallVectorImpl<MachineOperand> &Pred2) cons t { | const SmallVectorImpl<MachineOperand> &Pred2) cons t { | |||
return false; | return false; | |||
} | } | |||
/// DefinesPredicate - If the specified instruction defines any predicate | /// DefinesPredicate - If the specified instruction defines any predicate | |||
skipping to change at line 691 | skipping to change at line 706 | |||
/// instruction that defines the specified register class. | /// instruction that defines the specified register class. | |||
virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) cons t { | virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) cons t { | |||
return true; | return true; | |||
} | } | |||
/// isSchedulingBoundary - Test if the given instruction should be | /// isSchedulingBoundary - Test if the given instruction should be | |||
/// considered a scheduling boundary. This primarily includes labels and | /// considered a scheduling boundary. This primarily includes labels and | |||
/// terminators. | /// terminators. | |||
virtual bool isSchedulingBoundary(const MachineInstr *MI, | virtual bool isSchedulingBoundary(const MachineInstr *MI, | |||
const MachineBasicBlock *MBB, | const MachineBasicBlock *MBB, | |||
const MachineFunction &MF) const = 0; | const MachineFunction &MF) const; | |||
/// Measure the specified inline asm to determine an approximation of its | /// Measure the specified inline asm to determine an approximation of its | |||
/// length. | /// length. | |||
virtual unsigned getInlineAsmLength(const char *Str, | virtual unsigned getInlineAsmLength(const char *Str, | |||
const MCAsmInfo &MAI) const; | const MCAsmInfo &MAI) const; | |||
/// CreateTargetHazardRecognizer - Allocate and return a hazard recognize r to | /// CreateTargetHazardRecognizer - Allocate and return a hazard recognize r to | |||
/// use for this target when scheduling the machine instructions before | /// use for this target when scheduling the machine instructions before | |||
/// register allocation. | /// register allocation. | |||
virtual ScheduleHazardRecognizer* | virtual ScheduleHazardRecognizer* | |||
CreateTargetHazardRecognizer(const TargetMachine *TM, | CreateTargetHazardRecognizer(const TargetMachine *TM, | |||
const ScheduleDAG *DAG) const = 0; | const ScheduleDAG *DAG) const; | |||
/// CreateTargetMIHazardRecognizer - Allocate and return a hazard recogni zer | /// CreateTargetMIHazardRecognizer - Allocate and return a hazard recogni zer | |||
/// to use for this target when scheduling the machine instructions befor e | /// to use for this target when scheduling the machine instructions befor e | |||
/// register allocation. | /// register allocation. | |||
virtual ScheduleHazardRecognizer* | virtual ScheduleHazardRecognizer* | |||
CreateTargetMIHazardRecognizer(const InstrItineraryData*, | CreateTargetMIHazardRecognizer(const InstrItineraryData*, | |||
const ScheduleDAG *DAG) const = 0; | const ScheduleDAG *DAG) const; | |||
/// CreateTargetPostRAHazardRecognizer - Allocate and return a hazard | /// CreateTargetPostRAHazardRecognizer - Allocate and return a hazard | |||
/// recognizer to use for this target when scheduling the machine instruc tions | /// recognizer to use for this target when scheduling the machine instruc tions | |||
/// after register allocation. | /// after register allocation. | |||
virtual ScheduleHazardRecognizer* | virtual ScheduleHazardRecognizer* | |||
CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, | CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, | |||
const ScheduleDAG *DAG) const = 0; | const ScheduleDAG *DAG) const; | |||
/// Provide a global flag for disabling the PreRA hazard recognizer that | ||||
/// targets may choose to honor. | ||||
bool usePreRAHazardRecognizer() const; | ||||
/// analyzeCompare - For a comparison instruction, return the source regi sters | /// analyzeCompare - For a comparison instruction, return the source regi sters | |||
/// in SrcReg and SrcReg2 if having two register operands, and the value it | /// in SrcReg and SrcReg2 if having two register operands, and the value it | |||
/// compares against in CmpValue. Return true if the comparison instructi on | /// compares against in CmpValue. Return true if the comparison instructi on | |||
/// can be analyzed. | /// can be analyzed. | |||
virtual bool analyzeCompare(const MachineInstr *MI, | virtual bool analyzeCompare(const MachineInstr *MI, | |||
unsigned &SrcReg, unsigned &SrcReg2, | unsigned &SrcReg, unsigned &SrcReg2, | |||
int &Mask, int &Value) const { | int &Mask, int &Value) const { | |||
return false; | return false; | |||
} | } | |||
skipping to change at line 755 | skipping to change at line 774 | |||
/// the machine instruction generated due to folding. | /// the machine instruction generated due to folding. | |||
virtual MachineInstr* optimizeLoadInstr(MachineInstr *MI, | virtual MachineInstr* optimizeLoadInstr(MachineInstr *MI, | |||
const MachineRegisterInfo *MRI, | const MachineRegisterInfo *MRI, | |||
unsigned &FoldAsLoadDefReg, | unsigned &FoldAsLoadDefReg, | |||
MachineInstr *&DefMI) const { | MachineInstr *&DefMI) const { | |||
return 0; | return 0; | |||
} | } | |||
/// FoldImmediate - 'Reg' is known to be defined by a move immediate | /// FoldImmediate - 'Reg' is known to be defined by a move immediate | |||
/// instruction, try to fold the immediate into the use instruction. | /// instruction, try to fold the immediate into the use instruction. | |||
/// If MRI->hasOneNonDBGUse(Reg) is true, and this function returns true, | ||||
/// then the caller may assume that DefMI has been erased from its parent | ||||
/// block. The caller may assume that it will not be erased by this | ||||
/// function otherwise. | ||||
virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, | virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, | |||
unsigned Reg, MachineRegisterInfo *MRI) const { | unsigned Reg, MachineRegisterInfo *MRI) const { | |||
return false; | return false; | |||
} | } | |||
/// getNumMicroOps - Return the number of u-operations the given machine | /// getNumMicroOps - Return the number of u-operations the given machine | |||
/// instruction will be decoded to on the target cpu. The itinerary's | /// instruction will be decoded to on the target cpu. The itinerary's | |||
/// IssueWidth is the number of microops that can be dispatched each | /// IssueWidth is the number of microops that can be dispatched each | |||
/// cycle. An instruction with zero microops takes no dispatch resources. | /// cycle. An instruction with zero microops takes no dispatch resources. | |||
virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, | virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, | |||
const MachineInstr *MI) const = 0; | const MachineInstr *MI) const; | |||
/// isZeroCost - Return true for pseudo instructions that don't consume a ny | /// isZeroCost - Return true for pseudo instructions that don't consume a ny | |||
/// machine resources in their current form. These are common cases that the | /// machine resources in their current form. These are common cases that the | |||
/// scheduler should consider free, rather than conservatively handling t hem | /// scheduler should consider free, rather than conservatively handling t hem | |||
/// as instructions with no itinerary. | /// as instructions with no itinerary. | |||
bool isZeroCost(unsigned Opcode) const { | bool isZeroCost(unsigned Opcode) const { | |||
return Opcode <= TargetOpcode::COPY; | return Opcode <= TargetOpcode::COPY; | |||
} | } | |||
virtual int getOperandLatency(const InstrItineraryData *ItinData, | virtual int getOperandLatency(const InstrItineraryData *ItinData, | |||
SDNode *DefNode, unsigned DefIdx, | SDNode *DefNode, unsigned DefIdx, | |||
SDNode *UseNode, unsigned UseIdx) const = 0 ; | SDNode *UseNode, unsigned UseIdx) const; | |||
/// getOperandLatency - Compute and return the use operand latency of a g iven | /// getOperandLatency - Compute and return the use operand latency of a g iven | |||
/// pair of def and use. | /// pair of def and use. | |||
/// In most cases, the static scheduling itinerary was enough to determin e the | /// In most cases, the static scheduling itinerary was enough to determin e the | |||
/// operand latency. But it may not be possible for instructions with var iable | /// operand latency. But it may not be possible for instructions with var iable | |||
/// number of defs / uses. | /// number of defs / uses. | |||
/// | /// | |||
/// This is a raw interface to the itinerary that may be directly overrid en by | /// This is a raw interface to the itinerary that may be directly overrid en by | |||
/// a target. Use computeOperandLatency to get the best estimate of laten cy. | /// a target. Use computeOperandLatency to get the best estimate of laten cy. | |||
virtual int getOperandLatency(const InstrItineraryData *ItinData, | virtual int getOperandLatency(const InstrItineraryData *ItinData, | |||
const MachineInstr *DefMI, unsigned DefIdx, | const MachineInstr *DefMI, unsigned DefIdx, | |||
const MachineInstr *UseMI, | const MachineInstr *UseMI, | |||
unsigned UseIdx) const = 0; | unsigned UseIdx) const; | |||
/// computeOperandLatency - Compute and return the latency of the given d ata | /// computeOperandLatency - Compute and return the latency of the given d ata | |||
/// dependent def and use when the operand indices are already known. | /// dependent def and use when the operand indices are already known. | |||
/// | /// | |||
/// FindMin may be set to get the minimum vs. expected latency. | /// FindMin may be set to get the minimum vs. expected latency. | |||
unsigned computeOperandLatency(const InstrItineraryData *ItinData, | unsigned computeOperandLatency(const InstrItineraryData *ItinData, | |||
const MachineInstr *DefMI, unsigned DefIdx , | const MachineInstr *DefMI, unsigned DefIdx , | |||
const MachineInstr *UseMI, unsigned UseIdx , | const MachineInstr *UseMI, unsigned UseIdx , | |||
bool FindMin = false) const; | bool FindMin = false) const; | |||
/// getInstrLatency - Compute the instruction latency of a given instruct ion. | /// getInstrLatency - Compute the instruction latency of a given instruct ion. | |||
/// If the instruction has higher cost when predicated, it's returned via | /// If the instruction has higher cost when predicated, it's returned via | |||
/// PredCost. | /// PredCost. | |||
virtual unsigned getInstrLatency(const InstrItineraryData *ItinData, | virtual unsigned getInstrLatency(const InstrItineraryData *ItinData, | |||
const MachineInstr *MI, | const MachineInstr *MI, | |||
unsigned *PredCost = 0) const = 0; | unsigned *PredCost = 0) const; | |||
virtual int getInstrLatency(const InstrItineraryData *ItinData, | virtual int getInstrLatency(const InstrItineraryData *ItinData, | |||
SDNode *Node) const = 0; | SDNode *Node) const; | |||
/// Return the default expected latency for a def based on it's opcode. | /// Return the default expected latency for a def based on it's opcode. | |||
unsigned defaultDefLatency(const MCSchedModel *SchedModel, | unsigned defaultDefLatency(const MCSchedModel *SchedModel, | |||
const MachineInstr *DefMI) const; | const MachineInstr *DefMI) const; | |||
int computeDefOperandLatency(const InstrItineraryData *ItinData, | int computeDefOperandLatency(const InstrItineraryData *ItinData, | |||
const MachineInstr *DefMI, bool FindMin) con st; | const MachineInstr *DefMI, bool FindMin) con st; | |||
/// isHighLatencyDef - Return true if this opcode has high latency to its | /// isHighLatencyDef - Return true if this opcode has high latency to its | |||
/// result. | /// result. | |||
skipping to change at line 839 | skipping to change at line 862 | |||
const MachineRegisterInfo *MRI, | const MachineRegisterInfo *MRI, | |||
const MachineInstr *DefMI, unsigned DefIdx, | const MachineInstr *DefMI, unsigned DefIdx, | |||
const MachineInstr *UseMI, unsigned UseIdx) co nst { | const MachineInstr *UseMI, unsigned UseIdx) co nst { | |||
return false; | return false; | |||
} | } | |||
/// hasLowDefLatency - Compute operand latency of a def of 'Reg', return true | /// hasLowDefLatency - Compute operand latency of a def of 'Reg', return true | |||
/// if the target considered it 'low'. | /// if the target considered it 'low'. | |||
virtual | virtual | |||
bool hasLowDefLatency(const InstrItineraryData *ItinData, | bool hasLowDefLatency(const InstrItineraryData *ItinData, | |||
const MachineInstr *DefMI, unsigned DefIdx) const = 0; | const MachineInstr *DefMI, unsigned DefIdx) const; | |||
/// verifyInstruction - Perform target specific instruction verification. | /// verifyInstruction - Perform target specific instruction verification. | |||
virtual | virtual | |||
bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const { | bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const { | |||
return true; | return true; | |||
} | } | |||
/// getExecutionDomain - Return the current execution domain and bit mask of | /// getExecutionDomain - Return the current execution domain and bit mask of | |||
/// possible domains for instruction. | /// possible domains for instruction. | |||
/// | /// | |||
skipping to change at line 955 | skipping to change at line 978 | |||
/// Create machine specific model for scheduling. | /// Create machine specific model for scheduling. | |||
virtual DFAPacketizer* | virtual DFAPacketizer* | |||
CreateTargetScheduleState(const TargetMachine*, const ScheduleDAG*) con st { | CreateTargetScheduleState(const TargetMachine*, const ScheduleDAG*) con st { | |||
return NULL; | return NULL; | |||
} | } | |||
private: | private: | |||
int CallFrameSetupOpcode, CallFrameDestroyOpcode; | int CallFrameSetupOpcode, CallFrameDestroyOpcode; | |||
}; | }; | |||
/// TargetInstrInfoImpl - This is the default implementation of | ||||
/// TargetInstrInfo, which just provides a couple of default implementation | ||||
s | ||||
/// for various methods. This separated out because it is implemented in | ||||
/// libcodegen, not in libtarget. | ||||
class TargetInstrInfoImpl : public TargetInstrInfo { | ||||
protected: | ||||
TargetInstrInfoImpl(int CallFrameSetupOpcode = -1, | ||||
int CallFrameDestroyOpcode = -1) | ||||
: TargetInstrInfo(CallFrameSetupOpcode, CallFrameDestroyOpcode) {} | ||||
public: | ||||
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, | ||||
MachineBasicBlock *NewDest) const; | ||||
virtual MachineInstr *commuteInstruction(MachineInstr *MI, | ||||
bool NewMI = false) const; | ||||
virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, | ||||
unsigned &SrcOpIdx2) const; | ||||
virtual bool canFoldMemoryOperand(const MachineInstr *MI, | ||||
const SmallVectorImpl<unsigned> &Ops) c | ||||
onst; | ||||
virtual bool hasLoadFromStackSlot(const MachineInstr *MI, | ||||
const MachineMemOperand *&MMO, | ||||
int &FrameIndex) const; | ||||
virtual bool hasStoreToStackSlot(const MachineInstr *MI, | ||||
const MachineMemOperand *&MMO, | ||||
int &FrameIndex) const; | ||||
virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; | ||||
virtual bool PredicateInstruction(MachineInstr *MI, | ||||
const SmallVectorImpl<MachineOperand> &Pred) co | ||||
nst; | ||||
virtual void reMaterialize(MachineBasicBlock &MBB, | ||||
MachineBasicBlock::iterator MI, | ||||
unsigned DestReg, unsigned SubReg, | ||||
const MachineInstr *Orig, | ||||
const TargetRegisterInfo &TRI) const; | ||||
virtual MachineInstr *duplicate(MachineInstr *Orig, | ||||
MachineFunction &MF) const; | ||||
virtual bool produceSameValue(const MachineInstr *MI0, | ||||
const MachineInstr *MI1, | ||||
const MachineRegisterInfo *MRI) const; | ||||
virtual bool isSchedulingBoundary(const MachineInstr *MI, | ||||
const MachineBasicBlock *MBB, | ||||
const MachineFunction &MF) const; | ||||
virtual int getOperandLatency(const InstrItineraryData *ItinData, | ||||
SDNode *DefNode, unsigned DefIdx, | ||||
SDNode *UseNode, unsigned UseIdx) const; | ||||
virtual int getInstrLatency(const InstrItineraryData *ItinData, | ||||
SDNode *Node) const; | ||||
virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, | ||||
const MachineInstr *MI) const; | ||||
virtual unsigned getInstrLatency(const InstrItineraryData *ItinData, | ||||
const MachineInstr *MI, | ||||
unsigned *PredCost = 0) const; | ||||
virtual | ||||
bool hasLowDefLatency(const InstrItineraryData *ItinData, | ||||
const MachineInstr *DefMI, unsigned DefIdx) const; | ||||
virtual int getOperandLatency(const InstrItineraryData *ItinData, | ||||
const MachineInstr *DefMI, unsigned DefIdx, | ||||
const MachineInstr *UseMI, | ||||
unsigned UseIdx) const; | ||||
bool usePreRAHazardRecognizer() const; | ||||
virtual ScheduleHazardRecognizer * | ||||
CreateTargetHazardRecognizer(const TargetMachine*, const ScheduleDAG*) co | ||||
nst; | ||||
virtual ScheduleHazardRecognizer * | ||||
CreateTargetMIHazardRecognizer(const InstrItineraryData*, | ||||
const ScheduleDAG*) const; | ||||
virtual ScheduleHazardRecognizer * | ||||
CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, | ||||
const ScheduleDAG*) const; | ||||
}; | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 28 change blocks. | ||||
116 lines changed or deleted | 58 lines changed or added | |||
TargetJITInfo.h | TargetJITInfo.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file exposes an abstract interface used by the Just-In-Time code | // This file exposes an abstract interface used by the Just-In-Time code | |||
// generator to perform target-specific activities, such as emitting stubs. If | // generator to perform target-specific activities, such as emitting stubs. If | |||
// a TargetMachine supports JIT code generation, it should provide one of t hese | // a TargetMachine supports JIT code generation, it should provide one of t hese | |||
// objects through the getJITInfo() method. | // objects through the getJITInfo() method. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TARGET_TARGETJITINFO_H | #ifndef LLVM_TARGET_TARGETJITINFO_H | |||
#define LLVM_TARGET_TARGETJITINFO_H | #define LLVM_TARGET_TARGETJITINFO_H | |||
#include "llvm/Support/ErrorHandling.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/ErrorHandling.h" | ||||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
class Function; | class Function; | |||
class GlobalValue; | class GlobalValue; | |||
class JITCodeEmitter; | class JITCodeEmitter; | |||
class MachineRelocation; | class MachineRelocation; | |||
/// TargetJITInfo - Target specific information required by the Just-In-T ime | /// TargetJITInfo - Target specific information required by the Just-In-T ime | |||
/// code generator. | /// code generator. | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
TargetLibraryInfo.h | TargetLibraryInfo.h | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TARGET_TARGETLIBRARYINFO_H | #ifndef LLVM_TARGET_TARGETLIBRARYINFO_H | |||
#define LLVM_TARGET_TARGETLIBRARYINFO_H | #define LLVM_TARGET_TARGETLIBRARYINFO_H | |||
#include "llvm/Pass.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/Pass.h" | ||||
namespace llvm { | namespace llvm { | |||
class Triple; | class Triple; | |||
namespace LibFunc { | namespace LibFunc { | |||
enum Func { | enum Func { | |||
/// int _IO_getc(_IO_FILE * __fp); | ||||
under_IO_getc, | ||||
/// int _IO_putc(int __c, _IO_FILE * __fp); | ||||
under_IO_putc, | ||||
/// void operator delete[](void*); | /// void operator delete[](void*); | |||
ZdaPv, | ZdaPv, | |||
/// void operator delete(void*); | /// void operator delete(void*); | |||
ZdlPv, | ZdlPv, | |||
/// void *new[](unsigned int); | /// void *new[](unsigned int); | |||
Znaj, | Znaj, | |||
/// void *new[](unsigned int, nothrow); | /// void *new[](unsigned int, nothrow); | |||
ZnajRKSt9nothrow_t, | ZnajRKSt9nothrow_t, | |||
/// void *new[](unsigned long); | /// void *new[](unsigned long); | |||
Znam, | Znam, | |||
skipping to change at line 50 | skipping to change at line 54 | |||
ZnwmRKSt9nothrow_t, | ZnwmRKSt9nothrow_t, | |||
/// int __cxa_atexit(void (*f)(void *), void *p, void *d); | /// int __cxa_atexit(void (*f)(void *), void *p, void *d); | |||
cxa_atexit, | cxa_atexit, | |||
/// void __cxa_guard_abort(guard_t *guard); | /// void __cxa_guard_abort(guard_t *guard); | |||
/// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi. | /// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi. | |||
cxa_guard_abort, | cxa_guard_abort, | |||
/// int __cxa_guard_acquire(guard_t *guard); | /// int __cxa_guard_acquire(guard_t *guard); | |||
cxa_guard_acquire, | cxa_guard_acquire, | |||
/// void __cxa_guard_release(guard_t *guard); | /// void __cxa_guard_release(guard_t *guard); | |||
cxa_guard_release, | cxa_guard_release, | |||
/// int __isoc99_scanf (const char *format, ...) | ||||
dunder_isoc99_scanf, | ||||
/// int __isoc99_sscanf(const char *s, const char *format, ...) | ||||
dunder_isoc99_sscanf, | ||||
/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1s ize); | /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1s ize); | |||
memcpy_chk, | memcpy_chk, | |||
/// char * __strdup(const char *s); | ||||
dunder_strdup, | ||||
/// char *__strndup(const char *s, size_t n); | ||||
dunder_strndup, | ||||
/// char * __strtok_r(char *s, const char *delim, char **save_ptr); | ||||
dunder_strtok_r, | ||||
/// int abs(int j); | ||||
abs, | ||||
/// int access(const char *path, int amode); | ||||
access, | ||||
/// double acos(double x); | /// double acos(double x); | |||
acos, | acos, | |||
/// float acosf(float x); | /// float acosf(float x); | |||
acosf, | acosf, | |||
/// double acosh(double x); | /// double acosh(double x); | |||
acosh, | acosh, | |||
/// float acoshf(float x); | /// float acoshf(float x); | |||
acoshf, | acoshf, | |||
/// long double acoshl(long double x); | /// long double acoshl(long double x); | |||
acoshl, | acoshl, | |||
skipping to change at line 94 | skipping to change at line 112 | |||
/// float atanf(float x); | /// float atanf(float x); | |||
atanf, | atanf, | |||
/// double atanh(double x); | /// double atanh(double x); | |||
atanh, | atanh, | |||
/// float atanhf(float x); | /// float atanhf(float x); | |||
atanhf, | atanhf, | |||
/// long double atanhl(long double x); | /// long double atanhl(long double x); | |||
atanhl, | atanhl, | |||
/// long double atanl(long double x); | /// long double atanl(long double x); | |||
atanl, | atanl, | |||
/// double atof(const char *str); | ||||
atof, | ||||
/// int atoi(const char *str); | ||||
atoi, | ||||
/// long atol(const char *str); | ||||
atol, | ||||
/// long long atoll(const char *nptr); | ||||
atoll, | ||||
/// int bcmp(const void *s1, const void *s2, size_t n); | ||||
bcmp, | ||||
/// void bcopy(const void *s1, void *s2, size_t n); | ||||
bcopy, | ||||
/// void bzero(void *s, size_t n); | ||||
bzero, | ||||
/// void *calloc(size_t count, size_t size); | /// void *calloc(size_t count, size_t size); | |||
calloc, | calloc, | |||
/// double cbrt(double x); | /// double cbrt(double x); | |||
cbrt, | cbrt, | |||
/// float cbrtf(float x); | /// float cbrtf(float x); | |||
cbrtf, | cbrtf, | |||
/// long double cbrtl(long double x); | /// long double cbrtl(long double x); | |||
cbrtl, | cbrtl, | |||
/// double ceil(double x); | /// double ceil(double x); | |||
ceil, | ceil, | |||
/// float ceilf(float x); | /// float ceilf(float x); | |||
ceilf, | ceilf, | |||
/// long double ceill(long double x); | /// long double ceill(long double x); | |||
ceill, | ceill, | |||
/// int chmod(const char *path, mode_t mode); | ||||
chmod, | ||||
/// int chown(const char *path, uid_t owner, gid_t group); | ||||
chown, | ||||
/// void clearerr(FILE *stream); | ||||
clearerr, | ||||
/// int closedir(DIR *dirp); | ||||
closedir, | ||||
/// double copysign(double x, double y); | /// double copysign(double x, double y); | |||
copysign, | copysign, | |||
/// float copysignf(float x, float y); | /// float copysignf(float x, float y); | |||
copysignf, | copysignf, | |||
/// long double copysignl(long double x, long double y); | /// long double copysignl(long double x, long double y); | |||
copysignl, | copysignl, | |||
/// double cos(double x); | /// double cos(double x); | |||
cos, | cos, | |||
/// float cosf(float x); | /// float cosf(float x); | |||
cosf, | cosf, | |||
/// double cosh(double x); | /// double cosh(double x); | |||
cosh, | cosh, | |||
/// float coshf(float x); | /// float coshf(float x); | |||
coshf, | coshf, | |||
/// long double coshl(long double x); | /// long double coshl(long double x); | |||
coshl, | coshl, | |||
/// long double cosl(long double x); | /// long double cosl(long double x); | |||
cosl, | cosl, | |||
/// char *ctermid(char *s); | ||||
ctermid, | ||||
/// double exp(double x); | /// double exp(double x); | |||
exp, | exp, | |||
/// double exp10(double x); | /// double exp10(double x); | |||
exp10, | exp10, | |||
/// float exp10f(float x); | /// float exp10f(float x); | |||
exp10f, | exp10f, | |||
/// long double exp10l(long double x); | /// long double exp10l(long double x); | |||
exp10l, | exp10l, | |||
/// double exp2(double x); | /// double exp2(double x); | |||
exp2, | exp2, | |||
skipping to change at line 156 | skipping to change at line 198 | |||
/// float expm1f(float x); | /// float expm1f(float x); | |||
expm1f, | expm1f, | |||
/// long double expm1l(long double x); | /// long double expm1l(long double x); | |||
expm1l, | expm1l, | |||
/// double fabs(double x); | /// double fabs(double x); | |||
fabs, | fabs, | |||
/// float fabsf(float x); | /// float fabsf(float x); | |||
fabsf, | fabsf, | |||
/// long double fabsl(long double x); | /// long double fabsl(long double x); | |||
fabsl, | fabsl, | |||
/// int fclose(FILE *stream); | ||||
fclose, | ||||
/// FILE *fdopen(int fildes, const char *mode); | ||||
fdopen, | ||||
/// int feof(FILE *stream); | ||||
feof, | ||||
/// int ferror(FILE *stream); | ||||
ferror, | ||||
/// int fflush(FILE *stream); | ||||
fflush, | ||||
/// int ffs(int i); | ||||
ffs, | ||||
/// int ffsl(long int i); | ||||
ffsl, | ||||
/// int ffsll(long long int i); | ||||
ffsll, | ||||
/// int fgetc(FILE *stream); | ||||
fgetc, | ||||
/// int fgetpos(FILE *stream, fpos_t *pos); | ||||
fgetpos, | ||||
/// char *fgets(char *s, int n, FILE *stream); | ||||
fgets, | ||||
/// int fileno(FILE *stream); | ||||
fileno, | ||||
/// int fiprintf(FILE *stream, const char *format, ...); | /// int fiprintf(FILE *stream, const char *format, ...); | |||
fiprintf, | fiprintf, | |||
/// void flockfile(FILE *file); | ||||
flockfile, | ||||
/// double floor(double x); | /// double floor(double x); | |||
floor, | floor, | |||
/// float floorf(float x); | /// float floorf(float x); | |||
floorf, | floorf, | |||
/// long double floorl(long double x); | /// long double floorl(long double x); | |||
floorl, | floorl, | |||
/// double fmod(double x, double y); | /// double fmod(double x, double y); | |||
fmod, | fmod, | |||
/// float fmodf(float x, float y); | /// float fmodf(float x, float y); | |||
fmodf, | fmodf, | |||
/// long double fmodl(long double x, long double y); | /// long double fmodl(long double x, long double y); | |||
fmodl, | fmodl, | |||
/// FILE *fopen(const char *filename, const char *mode); | ||||
fopen, | ||||
/// FILE *fopen64(const char *filename, const char *opentype) | ||||
fopen64, | ||||
/// int fprintf(FILE *stream, const char *format, ...); | ||||
fprintf, | ||||
/// int fputc(int c, FILE *stream); | /// int fputc(int c, FILE *stream); | |||
fputc, | fputc, | |||
/// int fputs(const char *s, FILE *stream); | /// int fputs(const char *s, FILE *stream); | |||
fputs, | fputs, | |||
/// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream) | ||||
; | ||||
fread, | ||||
/// void free(void *ptr); | /// void free(void *ptr); | |||
free, | free, | |||
/// double frexp(double num, int *exp); | ||||
frexp, | ||||
/// float frexpf(float num, int *exp); | ||||
frexpf, | ||||
/// long double frexpl(long double num, int *exp); | ||||
frexpl, | ||||
/// int fscanf(FILE *stream, const char *format, ... ); | ||||
fscanf, | ||||
/// int fseek(FILE *stream, long offset, int whence); | ||||
fseek, | ||||
/// int fseeko(FILE *stream, off_t offset, int whence); | ||||
fseeko, | ||||
/// int fseeko64(FILE *stream, off64_t offset, int whence) | ||||
fseeko64, | ||||
/// int fsetpos(FILE *stream, const fpos_t *pos); | ||||
fsetpos, | ||||
/// int fstat(int fildes, struct stat *buf); | ||||
fstat, | ||||
/// int fstat64(int filedes, struct stat64 *buf) | ||||
fstat64, | ||||
/// int fstatvfs(int fildes, struct statvfs *buf); | ||||
fstatvfs, | ||||
/// int fstatvfs64(int fildes, struct statvfs64 *buf); | ||||
fstatvfs64, | ||||
/// long ftell(FILE *stream); | ||||
ftell, | ||||
/// off_t ftello(FILE *stream); | ||||
ftello, | ||||
/// off64_t ftello64(FILE *stream) | ||||
ftello64, | ||||
/// int ftrylockfile(FILE *file); | ||||
ftrylockfile, | ||||
/// void funlockfile(FILE *file); | ||||
funlockfile, | ||||
/// size_t fwrite(const void *ptr, size_t size, size_t nitems, | /// size_t fwrite(const void *ptr, size_t size, size_t nitems, | |||
/// FILE *stream); | /// FILE *stream); | |||
fwrite, | fwrite, | |||
/// int getc(FILE *stream); | ||||
getc, | ||||
/// int getc_unlocked(FILE *stream); | ||||
getc_unlocked, | ||||
/// int getchar(void); | ||||
getchar, | ||||
/// char *getenv(const char *name); | ||||
getenv, | ||||
/// int getitimer(int which, struct itimerval *value); | ||||
getitimer, | ||||
/// int getlogin_r(char *name, size_t namesize); | ||||
getlogin_r, | ||||
/// struct passwd *getpwnam(const char *name); | ||||
getpwnam, | ||||
/// char *gets(char *s); | ||||
gets, | ||||
/// uint32_t htonl(uint32_t hostlong); | ||||
htonl, | ||||
/// uint16_t htons(uint16_t hostshort); | ||||
htons, | ||||
/// int iprintf(const char *format, ...); | /// int iprintf(const char *format, ...); | |||
iprintf, | iprintf, | |||
/// int isascii(int c); | ||||
isascii, | ||||
/// int isdigit(int c); | ||||
isdigit, | ||||
/// long int labs(long int j); | ||||
labs, | ||||
/// int lchown(const char *path, uid_t owner, gid_t group); | ||||
lchown, | ||||
/// long long int llabs(long long int j); | ||||
llabs, | ||||
/// double log(double x); | /// double log(double x); | |||
log, | log, | |||
/// double log10(double x); | /// double log10(double x); | |||
log10, | log10, | |||
/// float log10f(float x); | /// float log10f(float x); | |||
log10f, | log10f, | |||
/// long double log10l(long double x); | /// long double log10l(long double x); | |||
log10l, | log10l, | |||
/// double log1p(double x); | /// double log1p(double x); | |||
log1p, | log1p, | |||
skipping to change at line 211 | skipping to change at line 351 | |||
/// double logb(double x); | /// double logb(double x); | |||
logb, | logb, | |||
/// float logbf(float x); | /// float logbf(float x); | |||
logbf, | logbf, | |||
/// long double logbl(long double x); | /// long double logbl(long double x); | |||
logbl, | logbl, | |||
/// float logf(float x); | /// float logf(float x); | |||
logf, | logf, | |||
/// long double logl(long double x); | /// long double logl(long double x); | |||
logl, | logl, | |||
/// int lstat(const char *path, struct stat *buf); | ||||
lstat, | ||||
/// int lstat64(const char *path, struct stat64 *buf); | ||||
lstat64, | ||||
/// void *malloc(size_t size); | /// void *malloc(size_t size); | |||
malloc, | malloc, | |||
/// void *memalign(size_t boundary, size_t size); | ||||
memalign, | ||||
/// void *memccpy(void *s1, const void *s2, int c, size_t n); | ||||
memccpy, | ||||
/// void *memchr(const void *s, int c, size_t n); | /// void *memchr(const void *s, int c, size_t n); | |||
memchr, | memchr, | |||
/// int memcmp(const void *s1, const void *s2, size_t n); | /// int memcmp(const void *s1, const void *s2, size_t n); | |||
memcmp, | memcmp, | |||
/// void *memcpy(void *s1, const void *s2, size_t n); | /// void *memcpy(void *s1, const void *s2, size_t n); | |||
memcpy, | memcpy, | |||
/// void *memmove(void *s1, const void *s2, size_t n); | /// void *memmove(void *s1, const void *s2, size_t n); | |||
memmove, | memmove, | |||
// void *memrchr(const void *s, int c, size_t n); | ||||
memrchr, | ||||
/// void *memset(void *b, int c, size_t len); | /// void *memset(void *b, int c, size_t len); | |||
memset, | memset, | |||
/// void memset_pattern16(void *b, const void *pattern16, size_t len) ; | /// void memset_pattern16(void *b, const void *pattern16, size_t len) ; | |||
memset_pattern16, | memset_pattern16, | |||
/// int mkdir(const char *path, mode_t mode); | ||||
mkdir, | ||||
/// time_t mktime(struct tm *timeptr); | ||||
mktime, | ||||
/// double modf(double x, double *iptr); | ||||
modf, | ||||
/// float modff(float, float *iptr); | ||||
modff, | ||||
/// long double modfl(long double value, long double *iptr); | ||||
modfl, | ||||
/// double nearbyint(double x); | /// double nearbyint(double x); | |||
nearbyint, | nearbyint, | |||
/// float nearbyintf(float x); | /// float nearbyintf(float x); | |||
nearbyintf, | nearbyintf, | |||
/// long double nearbyintl(long double x); | /// long double nearbyintl(long double x); | |||
nearbyintl, | nearbyintl, | |||
/// uint32_t ntohl(uint32_t netlong); | ||||
ntohl, | ||||
/// uint16_t ntohs(uint16_t netshort); | ||||
ntohs, | ||||
/// int open(const char *path, int oflag, ... ); | ||||
open, | ||||
/// int open64(const char *filename, int flags[, mode_t mode]) | ||||
open64, | ||||
/// DIR *opendir(const char *dirname); | ||||
opendir, | ||||
/// int pclose(FILE *stream); | ||||
pclose, | ||||
/// void perror(const char *s); | ||||
perror, | ||||
/// FILE *popen(const char *command, const char *mode); | ||||
popen, | ||||
/// int posix_memalign(void **memptr, size_t alignment, size_t size); | /// int posix_memalign(void **memptr, size_t alignment, size_t size); | |||
posix_memalign, | posix_memalign, | |||
/// double pow(double x, double y); | /// double pow(double x, double y); | |||
pow, | pow, | |||
/// float powf(float x, float y); | /// float powf(float x, float y); | |||
powf, | powf, | |||
/// long double powl(long double x, long double y); | /// long double powl(long double x, long double y); | |||
powl, | powl, | |||
/// ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset); | ||||
pread, | ||||
/// int printf(const char *format, ...); | ||||
printf, | ||||
/// int putc(int c, FILE *stream); | ||||
putc, | ||||
/// int putchar(int c); | /// int putchar(int c); | |||
putchar, | putchar, | |||
/// int puts(const char *s); | /// int puts(const char *s); | |||
puts, | puts, | |||
/// ssize_t pwrite(int fildes, const void *buf, size_t nbyte, | ||||
/// off_t offset); | ||||
pwrite, | ||||
/// void qsort(void *base, size_t nel, size_t width, | ||||
/// int (*compar)(const void *, const void *)); | ||||
qsort, | ||||
/// ssize_t read(int fildes, void *buf, size_t nbyte); | ||||
read, | ||||
/// ssize_t readlink(const char *path, char *buf, size_t bufsize); | ||||
readlink, | ||||
/// void *realloc(void *ptr, size_t size); | /// void *realloc(void *ptr, size_t size); | |||
realloc, | realloc, | |||
/// void *reallocf(void *ptr, size_t size); | /// void *reallocf(void *ptr, size_t size); | |||
reallocf, | reallocf, | |||
/// char *realpath(const char *file_name, char *resolved_name); | ||||
realpath, | ||||
/// int remove(const char *path); | ||||
remove, | ||||
/// int rename(const char *old, const char *new); | ||||
rename, | ||||
/// void rewind(FILE *stream); | ||||
rewind, | ||||
/// double rint(double x); | /// double rint(double x); | |||
rint, | rint, | |||
/// float rintf(float x); | /// float rintf(float x); | |||
rintf, | rintf, | |||
/// long double rintl(long double x); | /// long double rintl(long double x); | |||
rintl, | rintl, | |||
/// int rmdir(const char *path); | ||||
rmdir, | ||||
/// double round(double x); | /// double round(double x); | |||
round, | round, | |||
/// float roundf(float x); | /// float roundf(float x); | |||
roundf, | roundf, | |||
/// long double roundl(long double x); | /// long double roundl(long double x); | |||
roundl, | roundl, | |||
/// int scanf(const char *restrict format, ... ); | ||||
scanf, | ||||
/// void setbuf(FILE *stream, char *buf); | ||||
setbuf, | ||||
/// int setitimer(int which, const struct itimerval *value, | ||||
/// struct itimerval *ovalue); | ||||
setitimer, | ||||
/// int setvbuf(FILE *stream, char *buf, int type, size_t size); | ||||
setvbuf, | ||||
/// double sin(double x); | /// double sin(double x); | |||
sin, | sin, | |||
/// float sinf(float x); | /// float sinf(float x); | |||
sinf, | sinf, | |||
/// double sinh(double x); | /// double sinh(double x); | |||
sinh, | sinh, | |||
/// float sinhf(float x); | /// float sinhf(float x); | |||
sinhf, | sinhf, | |||
/// long double sinhl(long double x); | /// long double sinhl(long double x); | |||
sinhl, | sinhl, | |||
/// long double sinl(long double x); | /// long double sinl(long double x); | |||
sinl, | sinl, | |||
/// int siprintf(char *str, const char *format, ...); | /// int siprintf(char *str, const char *format, ...); | |||
siprintf, | siprintf, | |||
/// int snprintf(char *s, size_t n, const char *format, ...); | ||||
snprintf, | ||||
/// int sprintf(char *str, const char *format, ...); | ||||
sprintf, | ||||
/// double sqrt(double x); | /// double sqrt(double x); | |||
sqrt, | sqrt, | |||
/// float sqrtf(float x); | /// float sqrtf(float x); | |||
sqrtf, | sqrtf, | |||
/// long double sqrtl(long double x); | /// long double sqrtl(long double x); | |||
sqrtl, | sqrtl, | |||
/// int sscanf(const char *s, const char *format, ... ); | ||||
sscanf, | ||||
/// int stat(const char *path, struct stat *buf); | ||||
stat, | ||||
/// int stat64(const char *path, struct stat64 *buf); | ||||
stat64, | ||||
/// int statvfs(const char *path, struct statvfs *buf); | ||||
statvfs, | ||||
/// int statvfs64(const char *path, struct statvfs64 *buf) | ||||
statvfs64, | ||||
/// char *stpcpy(char *s1, const char *s2); | /// char *stpcpy(char *s1, const char *s2); | |||
stpcpy, | stpcpy, | |||
/// char *stpncpy(char *s1, const char *s2, size_t n); | ||||
stpncpy, | ||||
/// int strcasecmp(const char *s1, const char *s2); | ||||
strcasecmp, | ||||
/// char *strcat(char *s1, const char *s2); | /// char *strcat(char *s1, const char *s2); | |||
strcat, | strcat, | |||
/// char *strchr(const char *s, int c); | /// char *strchr(const char *s, int c); | |||
strchr, | strchr, | |||
/// int strcmp(const char *s1, const char *s2); | /// int strcmp(const char *s1, const char *s2); | |||
strcmp, | strcmp, | |||
/// int strcoll(const char *s1, const char *s2); | ||||
strcoll, | ||||
/// char *strcpy(char *s1, const char *s2); | /// char *strcpy(char *s1, const char *s2); | |||
strcpy, | strcpy, | |||
/// size_t strcspn(const char *s1, const char *s2); | /// size_t strcspn(const char *s1, const char *s2); | |||
strcspn, | strcspn, | |||
/// char *strdup(const char *s1); | /// char *strdup(const char *s1); | |||
strdup, | strdup, | |||
/// size_t strlen(const char *s); | /// size_t strlen(const char *s); | |||
strlen, | strlen, | |||
/// int strncasecmp(const char *s1, const char *s2, size_t n); | ||||
strncasecmp, | ||||
/// char *strncat(char *s1, const char *s2, size_t n); | /// char *strncat(char *s1, const char *s2, size_t n); | |||
strncat, | strncat, | |||
/// int strncmp(const char *s1, const char *s2, size_t n); | /// int strncmp(const char *s1, const char *s2, size_t n); | |||
strncmp, | strncmp, | |||
/// char *strncpy(char *s1, const char *s2, size_t n); | /// char *strncpy(char *s1, const char *s2, size_t n); | |||
strncpy, | strncpy, | |||
/// char *strndup(const char *s1, size_t n); | /// char *strndup(const char *s1, size_t n); | |||
strndup, | strndup, | |||
/// size_t strnlen(const char *s, size_t maxlen); | /// size_t strnlen(const char *s, size_t maxlen); | |||
strnlen, | strnlen, | |||
skipping to change at line 317 | skipping to change at line 550 | |||
/// char *strrchr(const char *s, int c); | /// char *strrchr(const char *s, int c); | |||
strrchr, | strrchr, | |||
/// size_t strspn(const char *s1, const char *s2); | /// size_t strspn(const char *s1, const char *s2); | |||
strspn, | strspn, | |||
/// char *strstr(const char *s1, const char *s2); | /// char *strstr(const char *s1, const char *s2); | |||
strstr, | strstr, | |||
/// double strtod(const char *nptr, char **endptr); | /// double strtod(const char *nptr, char **endptr); | |||
strtod, | strtod, | |||
/// float strtof(const char *nptr, char **endptr); | /// float strtof(const char *nptr, char **endptr); | |||
strtof, | strtof, | |||
// char *strtok(char *s1, const char *s2); | ||||
strtok, | ||||
// char *strtok_r(char *s, const char *sep, char **lasts); | ||||
strtok_r, | ||||
/// long int strtol(const char *nptr, char **endptr, int base); | /// long int strtol(const char *nptr, char **endptr, int base); | |||
strtol, | strtol, | |||
/// long double strtold(const char *nptr, char **endptr); | /// long double strtold(const char *nptr, char **endptr); | |||
strtold, | strtold, | |||
/// long long int strtoll(const char *nptr, char **endptr, int base); | /// long long int strtoll(const char *nptr, char **endptr, int base); | |||
strtoll, | strtoll, | |||
/// unsigned long int strtoul(const char *nptr, char **endptr, int ba se); | /// unsigned long int strtoul(const char *nptr, char **endptr, int ba se); | |||
strtoul, | strtoul, | |||
/// unsigned long long int strtoull(const char *nptr, char **endptr, | /// unsigned long long int strtoull(const char *nptr, char **endptr, | |||
/// int base); | /// int base); | |||
strtoull, | strtoull, | |||
/// size_t strxfrm(char *s1, const char *s2, size_t n); | ||||
strxfrm, | ||||
/// int system(const char *command); | ||||
system, | ||||
/// double tan(double x); | /// double tan(double x); | |||
tan, | tan, | |||
/// float tanf(float x); | /// float tanf(float x); | |||
tanf, | tanf, | |||
/// double tanh(double x); | /// double tanh(double x); | |||
tanh, | tanh, | |||
/// float tanhf(float x); | /// float tanhf(float x); | |||
tanhf, | tanhf, | |||
/// long double tanhl(long double x); | /// long double tanhl(long double x); | |||
tanhl, | tanhl, | |||
/// long double tanl(long double x); | /// long double tanl(long double x); | |||
tanl, | tanl, | |||
/// clock_t times(struct tms *buffer); | ||||
times, | ||||
/// FILE *tmpfile(void); | ||||
tmpfile, | ||||
/// FILE *tmpfile64(void) | ||||
tmpfile64, | ||||
/// int toascii(int c); | ||||
toascii, | ||||
/// double trunc(double x); | /// double trunc(double x); | |||
trunc, | trunc, | |||
/// float truncf(float x); | /// float truncf(float x); | |||
truncf, | truncf, | |||
/// long double truncl(long double x); | /// long double truncl(long double x); | |||
truncl, | truncl, | |||
/// int uname(struct utsname *name); | ||||
uname, | ||||
/// int ungetc(int c, FILE *stream); | ||||
ungetc, | ||||
/// int unlink(const char *path); | ||||
unlink, | ||||
/// int unsetenv(const char *name); | ||||
unsetenv, | ||||
/// int utime(const char *path, const struct utimbuf *times); | ||||
utime, | ||||
/// int utimes(const char *path, const struct timeval times[2]); | ||||
utimes, | ||||
/// void *valloc(size_t size); | /// void *valloc(size_t size); | |||
valloc, | valloc, | |||
/// int vfprintf(FILE *stream, const char *format, va_list ap); | ||||
vfprintf, | ||||
/// int vfscanf(FILE *stream, const char *format, va_list arg); | ||||
vfscanf, | ||||
/// int vprintf(const char *restrict format, va_list ap); | ||||
vprintf, | ||||
/// int vscanf(const char *format, va_list arg); | ||||
vscanf, | ||||
/// int vsnprintf(char *s, size_t n, const char *format, va_list ap); | ||||
vsnprintf, | ||||
/// int vsprintf(char *s, const char *format, va_list ap); | ||||
vsprintf, | ||||
/// int vsscanf(const char *s, const char *format, va_list arg); | ||||
vsscanf, | ||||
/// ssize_t write(int fildes, const void *buf, size_t nbyte); | ||||
write, | ||||
NumLibFuncs | NumLibFuncs | |||
}; | }; | |||
} | } | |||
/// TargetLibraryInfo - This immutable pass captures information about what | /// TargetLibraryInfo - This immutable pass captures information about what | |||
/// library functions are available for the current target, and allows a | /// library functions are available for the current target, and allows a | |||
/// frontend to disable optimizations through -fno-builtin etc. | /// frontend to disable optimizations through -fno-builtin etc. | |||
class TargetLibraryInfo : public ImmutablePass { | class TargetLibraryInfo : public ImmutablePass { | |||
virtual void anchor(); | virtual void anchor(); | |||
End of changes. 35 change blocks. | ||||
1 lines changed or deleted | 279 lines changed or added | |||
TargetLowering.h | TargetLowering.h | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
// 3. Cost thresholds for alternative implementations of certain operation s. | // 3. Cost thresholds for alternative implementations of certain operation s. | |||
// | // | |||
// In addition it has a few other components, like information about FP | // In addition it has a few other components, like information about FP | |||
// immediates. | // immediates. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TARGET_TARGETLOWERING_H | #ifndef LLVM_TARGET_TARGETLOWERING_H | |||
#define LLVM_TARGET_TARGETLOWERING_H | #define LLVM_TARGET_TARGETLOWERING_H | |||
#include "llvm/AddressingMode.h" | ||||
#include "llvm/CallingConv.h" | ||||
#include "llvm/InlineAsm.h" | ||||
#include "llvm/Attributes.h" | ||||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/Support/CallSite.h" | #include "llvm/CodeGen/DAGCombine.h" | |||
#include "llvm/CodeGen/SelectionDAGNodes.h" | ||||
#include "llvm/CodeGen/RuntimeLibcalls.h" | #include "llvm/CodeGen/RuntimeLibcalls.h" | |||
#include "llvm/CodeGen/SelectionDAGNodes.h" | ||||
#include "llvm/IR/Attributes.h" | ||||
#include "llvm/IR/CallingConv.h" | ||||
#include "llvm/IR/InlineAsm.h" | ||||
#include "llvm/Support/CallSite.h" | ||||
#include "llvm/Support/DebugLoc.h" | #include "llvm/Support/DebugLoc.h" | |||
#include "llvm/Target/TargetCallingConv.h" | #include "llvm/Target/TargetCallingConv.h" | |||
#include "llvm/Target/TargetMachine.h" | #include "llvm/Target/TargetMachine.h" | |||
#include <climits> | #include <climits> | |||
#include <map> | #include <map> | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class CallInst; | class CallInst; | |||
class CCState; | class CCState; | |||
skipping to change at line 71 | skipping to change at line 71 | |||
enum Preference { | enum Preference { | |||
None, // No preference | None, // No preference | |||
Source, // Follow source order. | Source, // Follow source order. | |||
RegPressure, // Scheduling for lowest register pressure. | RegPressure, // Scheduling for lowest register pressure. | |||
Hybrid, // Scheduling for both latency and register pressur e. | Hybrid, // Scheduling for both latency and register pressur e. | |||
ILP, // Scheduling for ILP in low register pressure mode . | ILP, // Scheduling for ILP in low register pressure mode . | |||
VLIW // Scheduling for VLIW targets. | VLIW // Scheduling for VLIW targets. | |||
}; | }; | |||
} | } | |||
//===---------------------------------------------------------------------- | /// TargetLoweringBase - This base class for TargetLowering contains the | |||
===// | /// SelectionDAG-independent parts that can be used from the rest of CodeGe | |||
/// TargetLowering - This class defines information used to lower LLVM code | n. | |||
to | class TargetLoweringBase { | |||
/// legal SelectionDAG operators that the target instruction selector can a | TargetLoweringBase(const TargetLoweringBase&) LLVM_DELETED_FUNCTION; | |||
ccept | void operator=(const TargetLoweringBase&) LLVM_DELETED_FUNCTION; | |||
/// natively. | ||||
/// | ||||
/// This class also defines callbacks that targets must implement to lower | ||||
/// target-specific constructs to SelectionDAG operators. | ||||
/// | ||||
class TargetLowering { | ||||
TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION; | ||||
void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION; | ||||
public: | public: | |||
/// LegalizeAction - This enum indicates whether operations are valid for a | /// LegalizeAction - This enum indicates whether operations are valid for a | |||
/// target, and if not, what action should be used to make them valid. | /// target, and if not, what action should be used to make them valid. | |||
enum LegalizeAction { | enum LegalizeAction { | |||
Legal, // The target natively supports this operation. | Legal, // The target natively supports this operation. | |||
Promote, // This operation should be executed in a larger type. | Promote, // This operation should be executed in a larger type. | |||
Expand, // Try to expand this to other ops, otherwise use a libcall . | Expand, // Try to expand this to other ops, otherwise use a libcall . | |||
Custom // Use the LowerOperation hook to implement custom lowering . | Custom // Use the LowerOperation hook to implement custom lowering . | |||
}; | }; | |||
skipping to change at line 139 | skipping to change at line 134 | |||
// Extend by adding zero bits. | // Extend by adding zero bits. | |||
return ISD::ZERO_EXTEND; | return ISD::ZERO_EXTEND; | |||
case ZeroOrNegativeOneBooleanContent: | case ZeroOrNegativeOneBooleanContent: | |||
// Extend by copying the sign bit. | // Extend by copying the sign bit. | |||
return ISD::SIGN_EXTEND; | return ISD::SIGN_EXTEND; | |||
} | } | |||
llvm_unreachable("Invalid content kind"); | llvm_unreachable("Invalid content kind"); | |||
} | } | |||
/// NOTE: The constructor takes ownership of TLOF. | /// NOTE: The constructor takes ownership of TLOF. | |||
explicit TargetLowering(const TargetMachine &TM, | explicit TargetLoweringBase(const TargetMachine &TM, | |||
const TargetLoweringObjectFile *TLOF); | const TargetLoweringObjectFile *TLOF); | |||
virtual ~TargetLowering(); | virtual ~TargetLoweringBase(); | |||
protected: | ||||
/// \brief Initialize all of the actions to default values. | ||||
void initActions(); | ||||
public: | ||||
const TargetMachine &getTargetMachine() const { return TM; } | const TargetMachine &getTargetMachine() const { return TM; } | |||
const DataLayout *getDataLayout() const { return TD; } | const DataLayout *getDataLayout() const { return TD; } | |||
const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; } | const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; } | |||
bool isBigEndian() const { return !IsLittleEndian; } | bool isBigEndian() const { return !IsLittleEndian; } | |||
bool isLittleEndian() const { return IsLittleEndian; } | bool isLittleEndian() const { return IsLittleEndian; } | |||
// Return the pointer type for the given address space, defaults to | // Return the pointer type for the given address space, defaults to | |||
// the pointer type from the data layout. | // the pointer type from the data layout. | |||
// FIXME: The default needs to be removed once all the code is updated. | // FIXME: The default needs to be removed once all the code is updated. | |||
virtual MVT getPointerTy(uint32_t AS = 0) const { return PointerTy; } | virtual MVT getPointerTy(uint32_t AS = 0) const { return PointerTy; } | |||
virtual MVT getShiftAmountTy(EVT LHSTy) const; | virtual MVT getScalarShiftAmountTy(EVT LHSTy) const; | |||
EVT getShiftAmountTy(EVT LHSTy) const; | ||||
/// isSelectExpensive - Return true if the select operation is expensive for | /// isSelectExpensive - Return true if the select operation is expensive for | |||
/// this target. | /// this target. | |||
bool isSelectExpensive() const { return SelectIsExpensive; } | bool isSelectExpensive() const { return SelectIsExpensive; } | |||
virtual bool isSelectSupported(SelectSupportKind kind) const { return tru e; } | virtual bool isSelectSupported(SelectSupportKind kind) const { return tru e; } | |||
/// shouldSplitVectorElementType - Return true if a vector of the given t | ||||
ype | ||||
/// 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 th an | /// isIntDivCheap() - Return true if integer divide is usually cheaper th an | |||
/// a sequence of several shifts, adds, and multiplies for this target. | /// a sequence of several shifts, adds, and multiplies for this target. | |||
bool isIntDivCheap() const { return IntDivIsCheap; } | bool isIntDivCheap() const { return IntDivIsCheap; } | |||
/// isSlowDivBypassed - Returns true if target has indicated at least one | /// isSlowDivBypassed - Returns true if target has indicated at least one | |||
/// type should be bypassed. | /// type should be bypassed. | |||
bool isSlowDivBypassed() const { return !BypassSlowDivWidths.empty(); } | bool isSlowDivBypassed() const { return !BypassSlowDivWidths.empty(); } | |||
/// getBypassSlowDivTypes - Returns map of slow types for division or | /// getBypassSlowDivTypes - Returns map of slow types for division or | |||
/// remainder with corresponding fast types | /// remainder with corresponding fast types | |||
skipping to change at line 186 | skipping to change at line 193 | |||
/// srl/add/sra. | /// srl/add/sra. | |||
bool isPow2DivCheap() const { return Pow2DivIsCheap; } | bool isPow2DivCheap() const { return Pow2DivIsCheap; } | |||
/// isJumpExpensive() - Return true if Flow Control is an expensive opera tion | /// isJumpExpensive() - Return true if Flow Control is an expensive opera tion | |||
/// that should be avoided. | /// that should be avoided. | |||
bool isJumpExpensive() const { return JumpIsExpensive; } | bool isJumpExpensive() const { return JumpIsExpensive; } | |||
/// isPredictableSelectExpensive - Return true if selects are only cheape r | /// isPredictableSelectExpensive - Return true if selects are only cheape r | |||
/// than branches if the branch is unlikely to be predicted right. | /// than branches if the branch is unlikely to be predicted right. | |||
bool isPredictableSelectExpensive() const { | bool isPredictableSelectExpensive() const { | |||
return predictableSelectIsExpensive; | return PredictableSelectIsExpensive; | |||
} | } | |||
/// getSetCCResultType - Return the ValueType of the result of SETCC | /// getSetCCResultType - Return the ValueType of the result of SETCC | |||
/// operations. Also used to obtain the target's preferred type for | /// operations. Also used to obtain the target's preferred type for | |||
/// the condition operand of SELECT and BRCOND nodes. In the case of | /// the condition operand of SELECT and BRCOND nodes. In the case of | |||
/// BRCOND the argument passed is MVT::Other since there are no other | /// BRCOND the argument passed is MVT::Other since there are no other | |||
/// operands to get a type hint from. | /// operands to get a type hint from. | |||
virtual EVT getSetCCResultType(EVT VT) const; | virtual EVT getSetCCResultType(EVT VT) const; | |||
/// getCmpLibcallReturnType - Return the ValueType for comparison | /// getCmpLibcallReturnType - Return the ValueType for comparison | |||
skipping to change at line 229 | skipping to change at line 236 | |||
/// getSchedulingPreference - Some scheduler, e.g. hybrid, can switch to | /// getSchedulingPreference - Some scheduler, e.g. hybrid, can switch to | |||
/// different scheduling heuristics for different nodes. This function re turns | /// different scheduling heuristics for different nodes. This function re turns | |||
/// the preference (or none) for the given node. | /// the preference (or none) for the given node. | |||
virtual Sched::Preference getSchedulingPreference(SDNode *) const { | virtual Sched::Preference getSchedulingPreference(SDNode *) const { | |||
return Sched::None; | return Sched::None; | |||
} | } | |||
/// getRegClassFor - Return the register class that should be used for th e | /// getRegClassFor - Return the register class that should be used for th e | |||
/// specified value type. | /// specified value type. | |||
virtual const TargetRegisterClass *getRegClassFor(EVT VT) const { | virtual const TargetRegisterClass *getRegClassFor(MVT VT) const { | |||
assert(VT.isSimple() && "getRegClassFor called on illegal type!"); | const TargetRegisterClass *RC = RegClassForVT[VT.SimpleTy]; | |||
const TargetRegisterClass *RC = RegClassForVT[VT.getSimpleVT().SimpleTy | ||||
]; | ||||
assert(RC && "This value type is not natively supported!"); | assert(RC && "This value type is not natively supported!"); | |||
return RC; | return RC; | |||
} | } | |||
/// getRepRegClassFor - Return the 'representative' register class for th e | /// getRepRegClassFor - Return the 'representative' register class for th e | |||
/// specified value type. The 'representative' register class is the larg est | /// specified value type. The 'representative' register class is the larg est | |||
/// legal super-reg register class for the register class of the value ty pe. | /// legal super-reg register class for the register class of the value ty pe. | |||
/// For example, on i386 the rep register class for i8, i16, and i32 are GR32; | /// 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. | /// while the rep register class is GR64 on x86_64. | |||
virtual const TargetRegisterClass *getRepRegClassFor(EVT VT) const { | virtual const TargetRegisterClass *getRepRegClassFor(MVT VT) const { | |||
assert(VT.isSimple() && "getRepRegClassFor called on illegal type!"); | const TargetRegisterClass *RC = RepRegClassForVT[VT.SimpleTy]; | |||
const TargetRegisterClass *RC = RepRegClassForVT[VT.getSimpleVT().Simpl | ||||
eTy]; | ||||
return RC; | return RC; | |||
} | } | |||
/// getRepRegClassCostFor - Return the cost of the 'representative' regis ter | /// getRepRegClassCostFor - Return the cost of the 'representative' regis ter | |||
/// class for the specified value type. | /// class for the specified value type. | |||
virtual uint8_t getRepRegClassCostFor(EVT VT) const { | virtual uint8_t getRepRegClassCostFor(MVT VT) const { | |||
assert(VT.isSimple() && "getRepRegClassCostFor called on illegal type!" | return RepRegClassCostForVT[VT.SimpleTy]; | |||
); | ||||
return RepRegClassCostForVT[VT.getSimpleVT().SimpleTy]; | ||||
} | } | |||
/// isTypeLegal - Return true if the target has native support for the | /// isTypeLegal - Return true if the target has native support for the | |||
/// specified value type. This means that it has a register that directl y | /// specified value type. This means that it has a register that directl y | |||
/// holds it without promotions or expansions. | /// holds it without promotions or expansions. | |||
bool isTypeLegal(EVT VT) const { | bool isTypeLegal(EVT VT) const { | |||
assert(!VT.isSimple() || | assert(!VT.isSimple() || | |||
(unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassFor VT)); | (unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassFor VT)); | |||
return VT.isSimple() && RegClassForVT[VT.getSimpleVT().SimpleTy] != 0; | return VT.isSimple() && RegClassForVT[VT.getSimpleVT().SimpleTy] != 0; | |||
} | } | |||
skipping to change at line 277 | skipping to change at line 281 | |||
public: | public: | |||
ValueTypeActionImpl() { | ValueTypeActionImpl() { | |||
std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0); | std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0); | |||
} | } | |||
LegalizeTypeAction getTypeAction(MVT VT) const { | LegalizeTypeAction getTypeAction(MVT VT) const { | |||
return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy]; | return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy]; | |||
} | } | |||
void setTypeAction(EVT VT, LegalizeTypeAction Action) { | void setTypeAction(MVT VT, LegalizeTypeAction Action) { | |||
unsigned I = VT.getSimpleVT().SimpleTy; | unsigned I = VT.SimpleTy; | |||
ValueTypeActions[I] = Action; | ValueTypeActions[I] = Action; | |||
} | } | |||
}; | }; | |||
const ValueTypeActionImpl &getValueTypeActions() const { | const ValueTypeActionImpl &getValueTypeActions() const { | |||
return ValueTypeActions; | return ValueTypeActions; | |||
} | } | |||
/// getTypeAction - Return how we should legalize values of this type, ei ther | /// getTypeAction - Return how we should legalize values of this type, ei ther | |||
/// it is already legal (return 'Legal') or we need to promote it to a la rger | /// it is already legal (return 'Legal') or we need to promote it to a la rger | |||
skipping to change at line 339 | skipping to change at line 343 | |||
/// with Altivec or SSE1, or 8 promoted EVT::f64 values with the X86 FP s tack. | /// with Altivec or SSE1, or 8 promoted EVT::f64 values with the X86 FP s tack. | |||
/// Similarly, EVT::v2i64 turns into 4 EVT::i32 values with both PPC and X86. | /// 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 ea ch | /// This method returns the number of registers needed, and the VT for ea ch | |||
/// register. It also returns the VT and quantity of the intermediate va lues | /// register. It also returns the VT and quantity of the intermediate va lues | |||
/// before they are promoted/expanded. | /// before they are promoted/expanded. | |||
/// | /// | |||
unsigned getVectorTypeBreakdown(LLVMContext &Context, EVT VT, | unsigned getVectorTypeBreakdown(LLVMContext &Context, EVT VT, | |||
EVT &IntermediateVT, | EVT &IntermediateVT, | |||
unsigned &NumIntermediates, | unsigned &NumIntermediates, | |||
EVT &RegisterVT) const; | MVT &RegisterVT) const; | |||
/// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the | /// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the | |||
/// intrinsic will need to map to a MemIntrinsicNode (touches memory). If | /// intrinsic will need to map to a MemIntrinsicNode (touches memory). If | |||
/// this is the case, it returns true and store the intrinsic | /// this is the case, it returns true and store the intrinsic | |||
/// information into the IntrinsicInfo that was passed to the function. | /// information into the IntrinsicInfo that was passed to the function. | |||
struct IntrinsicInfo { | struct IntrinsicInfo { | |||
unsigned opc; // target opcode | unsigned opc; // target opcode | |||
EVT memVT; // memory VT | EVT memVT; // memory VT | |||
const Value* ptrVal; // value representing memory location | const Value* ptrVal; // value representing memory location | |||
int offset; // offset off of ptrVal | int offset; // offset off of ptrVal | |||
skipping to change at line 413 | skipping to change at line 417 | |||
/// isOperationLegalOrCustom - Return true if the specified operation is | /// isOperationLegalOrCustom - Return true if the specified operation is | |||
/// legal on this target or can be made legal with custom lowering. This | /// legal on this target or can be made legal with custom lowering. This | |||
/// is used to help guide high-level lowering decisions. | /// is used to help guide high-level lowering decisions. | |||
bool isOperationLegalOrCustom(unsigned Op, EVT VT) const { | bool isOperationLegalOrCustom(unsigned Op, EVT VT) const { | |||
return (VT == MVT::Other || isTypeLegal(VT)) && | return (VT == MVT::Other || isTypeLegal(VT)) && | |||
(getOperationAction(Op, VT) == Legal || | (getOperationAction(Op, VT) == Legal || | |||
getOperationAction(Op, VT) == Custom); | 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. | ||||
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 | /// isOperationExpand - Return true if the specified operation is illegal on | |||
/// this target or unlikely to be made legal with custom lowering. This i s | /// this target or unlikely to be made legal with custom lowering. This i s | |||
/// used to help guide high-level lowering decisions. | /// used to help guide high-level lowering decisions. | |||
bool isOperationExpand(unsigned Op, EVT VT) const { | bool isOperationExpand(unsigned Op, EVT VT) const { | |||
return (!isTypeLegal(VT) || getOperationAction(Op, VT) == Expand); | return (!isTypeLegal(VT) || getOperationAction(Op, VT) == Expand); | |||
} | } | |||
/// isOperationLegal - Return true if the specified operation is legal on this | /// isOperationLegal - Return true if the specified operation is legal on this | |||
/// target. | /// target. | |||
bool isOperationLegal(unsigned Op, EVT VT) const { | bool isOperationLegal(unsigned Op, EVT VT) const { | |||
return (VT == MVT::Other || isTypeLegal(VT)) && | return (VT == MVT::Other || isTypeLegal(VT)) && | |||
getOperationAction(Op, VT) == Legal; | getOperationAction(Op, VT) == Legal; | |||
} | } | |||
/// getLoadExtAction - Return how this load with extension should be trea ted: | /// getLoadExtAction - Return how this load with extension should be trea ted: | |||
/// either it is legal, needs to be promoted to a larger size, needs to b e | /// either it is legal, needs to be promoted to a larger size, needs to b e | |||
/// expanded to some other code sequence, or the target has a custom expa nder | /// expanded to some other code sequence, or the target has a custom expa nder | |||
/// for it. | /// for it. | |||
LegalizeAction getLoadExtAction(unsigned ExtType, EVT VT) const { | LegalizeAction getLoadExtAction(unsigned ExtType, MVT VT) const { | |||
assert(ExtType < ISD::LAST_LOADEXT_TYPE && | assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE && | |||
VT.getSimpleVT() < MVT::LAST_VALUETYPE && | ||||
"Table isn't big enough!"); | "Table isn't big enough!"); | |||
return (LegalizeAction)LoadExtActions[VT.getSimpleVT().SimpleTy][ExtTyp e]; | return (LegalizeAction)LoadExtActions[VT.SimpleTy][ExtType]; | |||
} | } | |||
/// isLoadExtLegal - Return true if the specified load with extension is legal | /// isLoadExtLegal - Return true if the specified load with extension is legal | |||
/// on this target. | /// on this target. | |||
bool isLoadExtLegal(unsigned ExtType, EVT VT) const { | bool isLoadExtLegal(unsigned ExtType, EVT VT) const { | |||
return VT.isSimple() && getLoadExtAction(ExtType, VT) == Legal; | return VT.isSimple() && | |||
getLoadExtAction(ExtType, VT.getSimpleVT()) == Legal; | ||||
} | } | |||
/// getTruncStoreAction - Return how this store with truncation should be | /// getTruncStoreAction - Return how this store with truncation should be | |||
/// treated: either it is legal, needs to be promoted to a larger size, n eeds | /// treated: either it is legal, needs to be promoted to a larger size, n eeds | |||
/// to be expanded to some other code sequence, or the target has a custo m | /// to be expanded to some other code sequence, or the target has a custo m | |||
/// expander for it. | /// expander for it. | |||
LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const { | LegalizeAction getTruncStoreAction(MVT ValVT, MVT MemVT) const { | |||
assert(ValVT.getSimpleVT() < MVT::LAST_VALUETYPE && | assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE && | |||
MemVT.getSimpleVT() < MVT::LAST_VALUETYPE && | ||||
"Table isn't big enough!"); | "Table isn't big enough!"); | |||
return (LegalizeAction)TruncStoreActions[ValVT.getSimpleVT().SimpleTy] | return (LegalizeAction)TruncStoreActions[ValVT.SimpleTy] | |||
[MemVT.getSimpleVT().SimpleTy]; | [MemVT.SimpleTy]; | |||
} | } | |||
/// isTruncStoreLegal - Return true if the specified store with truncatio n is | /// isTruncStoreLegal - Return true if the specified store with truncatio n is | |||
/// legal on this target. | /// legal on this target. | |||
bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const { | bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const { | |||
return isTypeLegal(ValVT) && MemVT.isSimple() && | return isTypeLegal(ValVT) && MemVT.isSimple() && | |||
getTruncStoreAction(ValVT, MemVT) == Legal; | getTruncStoreAction(ValVT.getSimpleVT(), MemVT.getSimpleVT()) == Lega l; | |||
} | } | |||
/// getIndexedLoadAction - Return how the indexed load should be treated: | /// getIndexedLoadAction - Return how the indexed load should be treated: | |||
/// either it is legal, needs to be promoted to a larger size, needs to b e | /// either it is legal, needs to be promoted to a larger size, needs to b e | |||
/// expanded to some other code sequence, or the target has a custom expa nder | /// expanded to some other code sequence, or the target has a custom expa nder | |||
/// for it. | /// for it. | |||
LegalizeAction | LegalizeAction | |||
getIndexedLoadAction(unsigned IdxMode, EVT VT) const { | getIndexedLoadAction(unsigned IdxMode, MVT VT) const { | |||
assert(IdxMode < ISD::LAST_INDEXED_MODE && | assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE && | |||
VT.getSimpleVT() < MVT::LAST_VALUETYPE && | ||||
"Table isn't big enough!"); | "Table isn't big enough!"); | |||
unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy; | unsigned Ty = (unsigned)VT.SimpleTy; | |||
return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4); | return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4); | |||
} | } | |||
/// isIndexedLoadLegal - Return true if the specified indexed load is leg al | /// isIndexedLoadLegal - Return true if the specified indexed load is leg al | |||
/// on this target. | /// on this target. | |||
bool isIndexedLoadLegal(unsigned IdxMode, EVT VT) const { | bool isIndexedLoadLegal(unsigned IdxMode, EVT VT) const { | |||
return VT.isSimple() && | return VT.isSimple() && | |||
(getIndexedLoadAction(IdxMode, VT) == Legal || | (getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Legal || | |||
getIndexedLoadAction(IdxMode, VT) == Custom); | getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Custom); | |||
} | } | |||
/// getIndexedStoreAction - Return how the indexed store should be treate d: | /// getIndexedStoreAction - Return how the indexed store should be treate d: | |||
/// either it is legal, needs to be promoted to a larger size, needs to b e | /// either it is legal, needs to be promoted to a larger size, needs to b e | |||
/// expanded to some other code sequence, or the target has a custom expa nder | /// expanded to some other code sequence, or the target has a custom expa nder | |||
/// for it. | /// for it. | |||
LegalizeAction | LegalizeAction | |||
getIndexedStoreAction(unsigned IdxMode, EVT VT) const { | getIndexedStoreAction(unsigned IdxMode, MVT VT) const { | |||
assert(IdxMode < ISD::LAST_INDEXED_MODE && | assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE && | |||
VT.getSimpleVT() < MVT::LAST_VALUETYPE && | ||||
"Table isn't big enough!"); | "Table isn't big enough!"); | |||
unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy; | unsigned Ty = (unsigned)VT.SimpleTy; | |||
return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f); | return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f); | |||
} | } | |||
/// isIndexedStoreLegal - Return true if the specified indexed load is le gal | /// isIndexedStoreLegal - Return true if the specified indexed load is le gal | |||
/// on this target. | /// on this target. | |||
bool isIndexedStoreLegal(unsigned IdxMode, EVT VT) const { | bool isIndexedStoreLegal(unsigned IdxMode, EVT VT) const { | |||
return VT.isSimple() && | return VT.isSimple() && | |||
(getIndexedStoreAction(IdxMode, VT) == Legal || | (getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Legal || | |||
getIndexedStoreAction(IdxMode, VT) == Custom); | getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Custom); | |||
} | } | |||
/// getCondCodeAction - Return how the condition code should be treated: | /// getCondCodeAction - Return how the condition code should be treated: | |||
/// either it is legal, needs to be expanded to some other code sequence, | /// either it is legal, needs to be expanded to some other code sequence, | |||
/// or the target has a custom expander for it. | /// or the target has a custom expander for it. | |||
LegalizeAction | LegalizeAction | |||
getCondCodeAction(ISD::CondCode CC, EVT VT) const { | getCondCodeAction(ISD::CondCode CC, MVT VT) const { | |||
assert((unsigned)CC < array_lengthof(CondCodeActions) && | assert((unsigned)CC < array_lengthof(CondCodeActions) && | |||
(unsigned)VT.getSimpleVT().SimpleTy < sizeof(CondCodeActions[0]) *4 && | (unsigned)VT.SimpleTy < sizeof(CondCodeActions[0])*4 && | |||
"Table isn't big enough!"); | "Table isn't big enough!"); | |||
/// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 6 4bit | /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 6 4bit | |||
/// value and the upper 27 bits index into the second dimension of the | /// value and the upper 27 bits index into the second dimension of the | |||
/// array to select what 64bit value to use. | /// array to select what 64bit value to use. | |||
LegalizeAction Action = (LegalizeAction) | LegalizeAction Action = (LegalizeAction) | |||
((CondCodeActions[CC][VT.getSimpleVT().SimpleTy >> 5] | ((CondCodeActions[CC][VT.SimpleTy >> 5] >> (2*(VT.SimpleTy & 0x1F))) | |||
>> (2*(VT.getSimpleVT().SimpleTy & 0x1F))) & 3); | & 3); | |||
assert(Action != Promote && "Can't promote condition code!"); | assert(Action != Promote && "Can't promote condition code!"); | |||
return Action; | return Action; | |||
} | } | |||
/// isCondCodeLegal - Return true if the specified condition code is lega l | /// isCondCodeLegal - Return true if the specified condition code is lega l | |||
/// on this target. | /// on this target. | |||
bool isCondCodeLegal(ISD::CondCode CC, EVT VT) const { | bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const { | |||
return getCondCodeAction(CC, VT) == Legal || | return | |||
getCondCodeAction(CC, VT) == Custom; | getCondCodeAction(CC, VT) == Legal || | |||
getCondCodeAction(CC, VT) == Custom; | ||||
} | } | |||
/// getTypeToPromoteTo - If the action for this operation is to promote, this | /// getTypeToPromoteTo - If the action for this operation is to promote, this | |||
/// method returns the ValueType to promote to. | /// method returns the ValueType to promote to. | |||
EVT getTypeToPromoteTo(unsigned Op, EVT VT) const { | MVT getTypeToPromoteTo(unsigned Op, MVT VT) const { | |||
assert(getOperationAction(Op, VT) == Promote && | assert(getOperationAction(Op, VT) == Promote && | |||
"This operation isn't promoted!"); | "This operation isn't promoted!"); | |||
// See if this has an explicit type specified. | // See if this has an explicit type specified. | |||
std::map<std::pair<unsigned, MVT::SimpleValueType>, | std::map<std::pair<unsigned, MVT::SimpleValueType>, | |||
MVT::SimpleValueType>::const_iterator PTTI = | MVT::SimpleValueType>::const_iterator PTTI = | |||
PromoteToType.find(std::make_pair(Op, VT.getSimpleVT().SimpleTy)); | PromoteToType.find(std::make_pair(Op, VT.SimpleTy)); | |||
if (PTTI != PromoteToType.end()) return PTTI->second; | if (PTTI != PromoteToType.end()) return PTTI->second; | |||
assert((VT.isInteger() || VT.isFloatingPoint()) && | assert((VT.isInteger() || VT.isFloatingPoint()) && | |||
"Cannot autopromote this type, add it with AddPromotedToType."); | "Cannot autopromote this type, add it with AddPromotedToType."); | |||
EVT NVT = VT; | MVT NVT = VT; | |||
do { | do { | |||
NVT = (MVT::SimpleValueType)(NVT.getSimpleVT().SimpleTy+1); | NVT = (MVT::SimpleValueType)(NVT.SimpleTy+1); | |||
assert(NVT.isInteger() == VT.isInteger() && NVT != MVT::isVoid && | assert(NVT.isInteger() == VT.isInteger() && NVT != MVT::isVoid && | |||
"Didn't find type to promote to!"); | "Didn't find type to promote to!"); | |||
} while (!isTypeLegal(NVT) || | } while (!isTypeLegal(NVT) || | |||
getOperationAction(Op, NVT) == Promote); | getOperationAction(Op, NVT) == Promote); | |||
return NVT; | return NVT; | |||
} | } | |||
/// getValueType - Return the EVT corresponding to this LLVM type. | /// getValueType - Return the EVT corresponding to this LLVM type. | |||
/// This is fixed by the LLVM operations except for the pointer size. If | /// 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 E VT | /// AllowUnknown is true, this will return MVT::Other for types with no E VT | |||
skipping to change at line 575 | skipping to change at line 585 | |||
Type *Elm = VTy->getElementType(); | Type *Elm = VTy->getElementType(); | |||
// Lower vectors of pointers to native pointer types. | // Lower vectors of pointers to native pointer types. | |||
if (Elm->isPointerTy()) | if (Elm->isPointerTy()) | |||
Elm = EVT(PointerTy).getTypeForEVT(Ty->getContext()); | Elm = EVT(PointerTy).getTypeForEVT(Ty->getContext()); | |||
return EVT::getVectorVT(Ty->getContext(), EVT::getEVT(Elm, false), | return EVT::getVectorVT(Ty->getContext(), EVT::getEVT(Elm, false), | |||
VTy->getNumElements()); | VTy->getNumElements()); | |||
} | } | |||
return EVT::getEVT(Ty, AllowUnknown); | return EVT::getEVT(Ty, AllowUnknown); | |||
} | } | |||
/// Return the MVT corresponding to this LLVM type. See getValueType. | ||||
MVT getSimpleValueType(Type *Ty, bool AllowUnknown = false) const { | ||||
return getValueType(Ty, AllowUnknown).getSimpleVT(); | ||||
} | ||||
/// getByValTypeAlignment - Return the desired alignment for ByVal aggreg ate | /// getByValTypeAlignment - Return the desired alignment for ByVal aggreg ate | |||
/// function arguments in the caller parameter area. This is the actual | /// function arguments in the caller parameter area. This is the actual | |||
/// alignment, not its logarithm. | /// alignment, not its logarithm. | |||
virtual unsigned getByValTypeAlignment(Type *Ty) const; | virtual unsigned getByValTypeAlignment(Type *Ty) const; | |||
/// getRegisterType - Return the type of registers that this ValueType wi ll | /// getRegisterType - Return the type of registers that this ValueType wi ll | |||
/// eventually require. | /// eventually require. | |||
EVT getRegisterType(MVT VT) const { | MVT getRegisterType(MVT VT) const { | |||
assert((unsigned)VT.SimpleTy < array_lengthof(RegisterTypeForVT)); | assert((unsigned)VT.SimpleTy < array_lengthof(RegisterTypeForVT)); | |||
return RegisterTypeForVT[VT.SimpleTy]; | return RegisterTypeForVT[VT.SimpleTy]; | |||
} | } | |||
/// getRegisterType - Return the type of registers that this ValueType wi ll | /// getRegisterType - Return the type of registers that this ValueType wi ll | |||
/// eventually require. | /// eventually require. | |||
EVT getRegisterType(LLVMContext &Context, EVT VT) const { | MVT getRegisterType(LLVMContext &Context, EVT VT) const { | |||
if (VT.isSimple()) { | if (VT.isSimple()) { | |||
assert((unsigned)VT.getSimpleVT().SimpleTy < | assert((unsigned)VT.getSimpleVT().SimpleTy < | |||
array_lengthof(RegisterTypeForVT)); | array_lengthof(RegisterTypeForVT)); | |||
return RegisterTypeForVT[VT.getSimpleVT().SimpleTy]; | return RegisterTypeForVT[VT.getSimpleVT().SimpleTy]; | |||
} | } | |||
if (VT.isVector()) { | if (VT.isVector()) { | |||
EVT VT1, RegisterVT; | EVT VT1; | |||
MVT RegisterVT; | ||||
unsigned NumIntermediates; | unsigned NumIntermediates; | |||
(void)getVectorTypeBreakdown(Context, VT, VT1, | (void)getVectorTypeBreakdown(Context, VT, VT1, | |||
NumIntermediates, RegisterVT); | NumIntermediates, RegisterVT); | |||
return RegisterVT; | return RegisterVT; | |||
} | } | |||
if (VT.isInteger()) { | if (VT.isInteger()) { | |||
return getRegisterType(Context, getTypeToTransformTo(Context, VT)); | return getRegisterType(Context, getTypeToTransformTo(Context, VT)); | |||
} | } | |||
llvm_unreachable("Unsupported extended type!"); | llvm_unreachable("Unsupported extended type!"); | |||
} | } | |||
skipping to change at line 621 | skipping to change at line 637 | |||
/// into pieces. For types like i140, which are first promoted then expa nded, | /// into pieces. For types like i140, which are first promoted then expa nded, | |||
/// it is the number of registers needed to hold all the bits of the orig inal | /// it is the number of registers needed to hold all the bits of the orig inal | |||
/// type. For an i140 on a 32 bit machine this means 5 registers. | /// type. For an i140 on a 32 bit machine this means 5 registers. | |||
unsigned getNumRegisters(LLVMContext &Context, EVT VT) const { | unsigned getNumRegisters(LLVMContext &Context, EVT VT) const { | |||
if (VT.isSimple()) { | if (VT.isSimple()) { | |||
assert((unsigned)VT.getSimpleVT().SimpleTy < | assert((unsigned)VT.getSimpleVT().SimpleTy < | |||
array_lengthof(NumRegistersForVT)); | array_lengthof(NumRegistersForVT)); | |||
return NumRegistersForVT[VT.getSimpleVT().SimpleTy]; | return NumRegistersForVT[VT.getSimpleVT().SimpleTy]; | |||
} | } | |||
if (VT.isVector()) { | if (VT.isVector()) { | |||
EVT VT1, VT2; | EVT VT1; | |||
MVT VT2; | ||||
unsigned NumIntermediates; | unsigned NumIntermediates; | |||
return getVectorTypeBreakdown(Context, VT, VT1, NumIntermediates, VT2 ); | return getVectorTypeBreakdown(Context, VT, VT1, NumIntermediates, VT2 ); | |||
} | } | |||
if (VT.isInteger()) { | if (VT.isInteger()) { | |||
unsigned BitWidth = VT.getSizeInBits(); | unsigned BitWidth = VT.getSizeInBits(); | |||
unsigned RegWidth = getRegisterType(Context, VT).getSizeInBits(); | unsigned RegWidth = getRegisterType(Context, VT).getSizeInBits(); | |||
return (BitWidth + RegWidth - 1) / RegWidth; | return (BitWidth + RegWidth - 1) / RegWidth; | |||
} | } | |||
llvm_unreachable("Unsupported extended type!"); | llvm_unreachable("Unsupported extended type!"); | |||
} | } | |||
skipping to change at line 651 | skipping to change at line 668 | |||
assert(unsigned(NT >> 3) < array_lengthof(TargetDAGCombineArray)); | assert(unsigned(NT >> 3) < array_lengthof(TargetDAGCombineArray)); | |||
return TargetDAGCombineArray[NT >> 3] & (1 << (NT&7)); | return TargetDAGCombineArray[NT >> 3] & (1 << (NT&7)); | |||
} | } | |||
/// This function returns the maximum number of store operations permitte d | /// This function returns the maximum number of store operations permitte d | |||
/// to replace a call to llvm.memset. The value is set by the target at t he | /// to replace a call to llvm.memset. The value is set by the target at t he | |||
/// performance threshold for such a replacement. If OptSize is true, | /// performance threshold for such a replacement. If OptSize is true, | |||
/// return the limit for functions that have OptSize attribute. | /// return the limit for functions that have OptSize attribute. | |||
/// @brief Get maximum # of store operations permitted for llvm.memset | /// @brief Get maximum # of store operations permitted for llvm.memset | |||
unsigned getMaxStoresPerMemset(bool OptSize) const { | unsigned getMaxStoresPerMemset(bool OptSize) const { | |||
return OptSize ? maxStoresPerMemsetOptSize : maxStoresPerMemset; | return OptSize ? MaxStoresPerMemsetOptSize : MaxStoresPerMemset; | |||
} | } | |||
/// This function returns the maximum number of store operations permitte d | /// This function returns the maximum number of store operations permitte d | |||
/// to replace a call to llvm.memcpy. The value is set by the target at t he | /// to replace a call to llvm.memcpy. The value is set by the target at t he | |||
/// performance threshold for such a replacement. If OptSize is true, | /// performance threshold for such a replacement. If OptSize is true, | |||
/// return the limit for functions that have OptSize attribute. | /// return the limit for functions that have OptSize attribute. | |||
/// @brief Get maximum # of store operations permitted for llvm.memcpy | /// @brief Get maximum # of store operations permitted for llvm.memcpy | |||
unsigned getMaxStoresPerMemcpy(bool OptSize) const { | unsigned getMaxStoresPerMemcpy(bool OptSize) const { | |||
return OptSize ? maxStoresPerMemcpyOptSize : maxStoresPerMemcpy; | return OptSize ? MaxStoresPerMemcpyOptSize : MaxStoresPerMemcpy; | |||
} | } | |||
/// This function returns the maximum number of store operations permitte d | /// This function returns the maximum number of store operations permitte d | |||
/// to replace a call to llvm.memmove. The value is set by the target at the | /// 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, | /// performance threshold for such a replacement. If OptSize is true, | |||
/// return the limit for functions that have OptSize attribute. | /// return the limit for functions that have OptSize attribute. | |||
/// @brief Get maximum # of store operations permitted for llvm.memmove | /// @brief Get maximum # of store operations permitted for llvm.memmove | |||
unsigned getMaxStoresPerMemmove(bool OptSize) const { | unsigned getMaxStoresPerMemmove(bool OptSize) const { | |||
return OptSize ? maxStoresPerMemmoveOptSize : maxStoresPerMemmove; | return OptSize ? MaxStoresPerMemmoveOptSize : MaxStoresPerMemmove; | |||
} | } | |||
/// This function returns true if the target allows unaligned memory acce sses. | /// This function returns true if the target allows unaligned memory acce sses. | |||
/// of the specified type. This is used, for example, in situations where | /// of the specified type. If true, it also returns whether the unaligned | |||
an | /// memory access is "fast" in the second argument by reference. This is | |||
/// array copy/move/set is converted to a sequence of store operations. | used, | |||
It's | /// for example, in situations where an array copy/move/set is converted | |||
/// use helps to ensure that such replacements don't generate code that c | to a | |||
auses | /// sequence of store operations. It's use helps to ensure that such | |||
/// an alignment error (trap) on the target machine. | /// replacements don't generate code that causes an alignment error (tra | |||
p) on | ||||
/// the target machine. | ||||
/// @brief Determine if the target supports unaligned memory accesses. | /// @brief Determine if the target supports unaligned memory accesses. | |||
virtual bool allowsUnalignedMemoryAccesses(EVT) const { | virtual bool allowsUnalignedMemoryAccesses(EVT, bool *Fast = 0) const { | |||
return false; | return false; | |||
} | } | |||
/// This function returns true if the target would benefit from code plac | ||||
ement | ||||
/// optimization. | ||||
/// @brief Determine if the target should perform code placement optimiza | ||||
tion. | ||||
bool shouldOptimizeCodePlacement() const { | ||||
return benefitFromCodePlacementOpt; | ||||
} | ||||
/// getOptimalMemOpType - Returns the target specific optimal type for lo ad | /// getOptimalMemOpType - Returns the target specific optimal type for lo ad | |||
/// and store operations as a result of memset, memcpy, and memmove | /// and store operations as a result of memset, memcpy, and memmove | |||
/// lowering. If DstAlign is zero that means it's safe to destination | /// lowering. If DstAlign is zero that means it's safe to destination | |||
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero i t | /// alignment can satisfy any constraint. Similarly if SrcAlign is zero i t | |||
/// means there isn't a need to check it against alignment requirement, | /// means there isn't a need to check it against alignment requirement, | |||
/// probably because the source does not need to be loaded. If | /// probably because the source does not need to be loaded. If 'IsMemset' | |||
/// 'IsZeroVal' is true, that means it's safe to return a | is | |||
/// non-scalar-integer type, e.g. empty string source, constant, or loade | /// true, that means it's expanding a memset. If 'ZeroMemset' is true, th | |||
d | at | |||
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is | /// means it's a memset of zero. 'MemcpyStrSrc' indicates whether the mem | |||
/// constant so it does not need to be loaded. | cpy | |||
/// source is constant so it does not need to be loaded. | ||||
/// It returns EVT::Other if the type should be determined using generic | /// It returns EVT::Other if the type should be determined using generic | |||
/// target-independent logic. | /// target-independent logic. | |||
virtual EVT getOptimalMemOpType(uint64_t /*Size*/, | virtual EVT getOptimalMemOpType(uint64_t /*Size*/, | |||
unsigned /*DstAlign*/, unsigned /*SrcAlig n*/, | unsigned /*DstAlign*/, unsigned /*SrcAlig n*/, | |||
bool /*IsZeroVal*/, | bool /*IsMemset*/, | |||
bool /*ZeroMemset*/, | ||||
bool /*MemcpyStrSrc*/, | bool /*MemcpyStrSrc*/, | |||
MachineFunction &/*MF*/) const { | MachineFunction &/*MF*/) const { | |||
return MVT::Other; | return MVT::Other; | |||
} | } | |||
/// isSafeMemOpType - Returns true if it's safe to use load / store of th | ||||
e | ||||
/// 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 whic | ||||
h | ||||
/// 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 | /// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp | |||
/// to implement llvm.setjmp. | /// to implement llvm.setjmp. | |||
bool usesUnderscoreSetJmp() const { | bool usesUnderscoreSetJmp() const { | |||
return UseUnderscoreSetJmp; | return UseUnderscoreSetJmp; | |||
} | } | |||
/// usesUnderscoreLongJmp - Determine if we should use _longjmp or longjm p | /// usesUnderscoreLongJmp - Determine if we should use _longjmp or longjm p | |||
/// to implement llvm.longjmp. | /// to implement llvm.longjmp. | |||
bool usesUnderscoreLongJmp() const { | bool usesUnderscoreLongJmp() const { | |||
return UseUnderscoreLongJmp; | return UseUnderscoreLongJmp; | |||
skipping to change at line 790 | skipping to change at line 812 | |||
unsigned getPrefFunctionAlignment() const { | unsigned getPrefFunctionAlignment() const { | |||
return PrefFunctionAlignment; | return PrefFunctionAlignment; | |||
} | } | |||
/// getPrefLoopAlignment - return the preferred loop alignment. | /// getPrefLoopAlignment - return the preferred loop alignment. | |||
/// | /// | |||
unsigned getPrefLoopAlignment() const { | unsigned getPrefLoopAlignment() const { | |||
return PrefLoopAlignment; | return PrefLoopAlignment; | |||
} | } | |||
/// getShouldFoldAtomicFences - return whether the combiner should fold | ||||
/// fence MEMBARRIER instructions into the atomic intrinsic instructions. | ||||
/// | ||||
bool getShouldFoldAtomicFences() const { | ||||
return ShouldFoldAtomicFences; | ||||
} | ||||
/// getInsertFencesFor - return whether the DAG builder should automatica lly | /// getInsertFencesFor - return whether the DAG builder should automatica lly | |||
/// insert fences and reduce ordering for atomics. | /// insert fences and reduce ordering for atomics. | |||
/// | /// | |||
bool getInsertFencesForAtomic() const { | bool getInsertFencesForAtomic() const { | |||
return InsertFencesForAtomic; | return InsertFencesForAtomic; | |||
} | } | |||
/// 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. | ||||
virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/, | ||||
SDValue &/*Offset*/, | ||||
ISD::MemIndexedMode &/*AM*/, | ||||
SelectionDAG &/*DAG*/) const { | ||||
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. | ||||
virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/, | ||||
SDValue &/*Base*/, SDValue &/*Off | ||||
set*/, | ||||
ISD::MemIndexedMode &/*AM*/, | ||||
SelectionDAG &/*DAG*/) const { | ||||
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. | ||||
virtual unsigned getJumpTableEncoding() const; | ||||
virtual const MCExpr * | ||||
LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/, | ||||
const MachineBasicBlock * /*MBB*/, unsigned /*u | ||||
id*/, | ||||
MCContext &/*Ctx*/) const { | ||||
llvm_unreachable("Need to implement this hook if target has custom JTIs | ||||
"); | ||||
} | ||||
/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC | ||||
/// jumptable. | ||||
virtual SDValue getPICJumpTableRelocBase(SDValue Table, | ||||
SelectionDAG &DAG) const; | ||||
/// getPICJumpTableRelocBaseExpr - This returns the relocation base for t | ||||
he | ||||
/// 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. | ||||
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; | ||||
/// getStackCookieLocation - Return true if the target stores stack | /// getStackCookieLocation - Return true if the target stores stack | |||
/// protector cookies at a fixed offset in some non-standard address | /// protector cookies at a fixed offset in some non-standard address | |||
/// space, and populates the address space and offset as | /// space, and populates the address space and offset as | |||
/// appropriate. | /// appropriate. | |||
virtual bool getStackCookieLocation(unsigned &/*AddressSpace*/, | virtual bool getStackCookieLocation(unsigned &/*AddressSpace*/, | |||
unsigned &/*Offset*/) const { | unsigned &/*Offset*/) const { | |||
return false; | return false; | |||
} | } | |||
/// getMaximalGlobalOffset - Returns the maximal possible offset which ca n be | /// getMaximalGlobalOffset - Returns the maximal possible offset which ca n be | |||
/// used for loads / stores from the global. | /// used for loads / stores from the global. | |||
virtual unsigned getMaximalGlobalOffset() const { | virtual unsigned getMaximalGlobalOffset() const { | |||
return 0; | return 0; | |||
} | } | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// TargetLowering Optimization Methods | /// \name Helpers for TargetTransformInfo implementations | |||
// | /// @{ | |||
/// TargetLoweringOpt - 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; | ||||
bool LegalOps; | ||||
SDValue Old; | ||||
SDValue New; | ||||
explicit TargetLoweringOpt(SelectionDAG &InDAG, | ||||
bool LT, bool LO) : | ||||
DAG(InDAG), LegalTys(LT), LegalOps(LO) {} | ||||
bool LegalTypes() const { return LegalTys; } | ||||
bool LegalOperations() const { return LegalOps; } | ||||
bool CombineTo(SDValue O, SDValue N) { | ||||
Old = O; | ||||
New = N; | ||||
return true; | ||||
} | ||||
/// ShrinkDemandedConstant - Check to see if the specified operand of t | ||||
he | ||||
/// specified instruction is a constant integer. If so, check to see i | ||||
f | ||||
/// there are any bits set in the constant that are not demanded. If s | ||||
o, | ||||
/// shrink the constant and return true. | ||||
bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded); | ||||
/// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if th | ||||
e | ||||
/// casts are free. This uses isZExtFree and ZERO_EXTEND for the widen | ||||
ing | ||||
/// cast, but it could be generalized for targets with other types of | ||||
/// implicit widening casts. | ||||
bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Deman | ||||
ded, | ||||
DebugLoc dl); | ||||
}; | ||||
/// SimplifyDemandedBits - Look at Op. At this point, we know that only | /// Get the ISD node that corresponds to the Instruction class opcode. | |||
the | int InstructionOpcodeToISD(unsigned Opcode) const; | |||
/// DemandedMask bits of the result of Op are ever used downstream. If w | ||||
e 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) con | ||||
st; | ||||
/// computeMaskedBitsForTargetNode - Determine which of the bits specifie | ||||
d 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. | ||||
virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op, | ||||
unsigned Depth = 0) cons | ||||
t; | ||||
struct DAGCombinerInfo { | ||||
void *DC; // The DAG Combiner object. | ||||
bool BeforeLegalize; | ||||
bool BeforeLegalizeOps; | ||||
bool CalledByLegalizer; | ||||
public: | ||||
SelectionDAG &DAG; | ||||
DAGCombinerInfo(SelectionDAG &dag, bool bl, bool blo, bool cl, void *dc | ||||
) | ||||
: DC(dc), BeforeLegalize(bl), BeforeLegalizeOps(blo), | ||||
CalledByLegalizer(cl), DAG(dag) {} | ||||
bool isBeforeLegalize() const { return BeforeLegalize; } | ||||
bool isBeforeLegalizeOps() const { return BeforeLegalizeOps; } | ||||
bool isCalledByLegalizer() const { return CalledByLegalizer; } | ||||
void AddToWorklist(SDNode *N); | ||||
void RemoveFromWorklist(SDNode *N); | ||||
SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To, | ||||
bool AddTo = true); | ||||
SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true); | ||||
SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = t | ||||
rue); | ||||
void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO); | ||||
}; | ||||
/// SimplifySetCC - Try to simplify a setcc built with the specified oper | ||||
ands | ||||
/// 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, DebugLoc dl) const; | ||||
/// isGAPlusOffset - 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. | ||||
/// | ||||
/// The semantics are as follows: | ||||
/// Return Value: | ||||
/// SDValue.Val == 0 - No change was made | ||||
/// SDValue.Val == N - N was replaced, is dead, and is already handle | ||||
d. | ||||
/// otherwise - N should be replaced by the returned Operand. | ||||
/// | ||||
/// In addition, methods provided by DAGCombinerInfo may be used to perfo | ||||
rm | ||||
/// more complex transformations. | ||||
/// | ||||
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; | ||||
/// isTypeDesirableForOp - Return true if the target has native support f | ||||
or | ||||
/// the specified value type and it is 'desirable' to use the type for th | ||||
e | ||||
/// 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 comb | /// Estimate the cost of type-legalization and the legalized type. | |||
iner | std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const; | |||
/// 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, i | ||||
t | ||||
/// should return the desired promotion type by reference. | ||||
virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const { | ||||
return false; | ||||
} | ||||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// TargetLowering Configuration Methods - These methods should be invoked by | // TargetLowering Configuration Methods - These methods should be invoked by | |||
// the derived class constructor to configure this object for the target. | // the derived class constructor to configure this object for the target. | |||
// | // | |||
/// \brief Reset the operation actions based on target options. | ||||
virtual void resetOperationActions() {} | ||||
protected: | protected: | |||
/// setBooleanContents - Specify how the target extends the result of a | /// setBooleanContents - Specify how the target extends the result of a | |||
/// boolean value from i1 to a wider type. See getBooleanContents. | /// boolean value from i1 to a wider type. See getBooleanContents. | |||
void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; } | void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; } | |||
/// setBooleanVectorContents - Specify how the target extends the result | /// setBooleanVectorContents - Specify how the target extends the result | |||
/// of a vector boolean value from a vector of i1 to a wider type. See | /// of a vector boolean value from a vector of i1 to a wider type. See | |||
/// getBooleanContents. | /// getBooleanContents. | |||
void setBooleanVectorContents(BooleanContent Ty) { | void setBooleanVectorContents(BooleanContent Ty) { | |||
BooleanVectorContents = Ty; | BooleanVectorContents = Ty; | |||
} | } | |||
skipping to change at line 1111 | skipping to change at line 948 | |||
} | } | |||
/// setPow2DivIsCheap - Tells the code generator that it shouldn't genera te | /// setPow2DivIsCheap - Tells the code generator that it shouldn't genera te | |||
/// srl/add/sra for a signed divide by power of two, and let the target h andle | /// srl/add/sra for a signed divide by power of two, and let the target h andle | |||
/// it. | /// it. | |||
void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; } | void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; } | |||
/// addRegisterClass - Add the specified register class as an available | /// addRegisterClass - Add the specified register class as an available | |||
/// regclass for the specified value type. This indicates the selector c an | /// regclass for the specified value type. This indicates the selector c an | |||
/// handle values of that class natively. | /// handle values of that class natively. | |||
void addRegisterClass(EVT VT, const TargetRegisterClass *RC) { | void addRegisterClass(MVT VT, const TargetRegisterClass *RC) { | |||
assert((unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassFor | assert((unsigned)VT.SimpleTy < array_lengthof(RegClassForVT)); | |||
VT)); | ||||
AvailableRegClasses.push_back(std::make_pair(VT, RC)); | AvailableRegClasses.push_back(std::make_pair(VT, RC)); | |||
RegClassForVT[VT.getSimpleVT().SimpleTy] = RC; | RegClassForVT[VT.SimpleTy] = RC; | |||
} | ||||
/// clearRegisterClasses - Remove all register classes. | ||||
void clearRegisterClasses() { | ||||
memset(RegClassForVT, 0,MVT::LAST_VALUETYPE * sizeof(TargetRegisterClas | ||||
s*)); | ||||
AvailableRegClasses.clear(); | ||||
} | ||||
/// \brief Remove all operation actions. | ||||
void clearOperationActions() { | ||||
} | } | |||
/// findRepresentativeClass - Return the largest legal super-reg register class | /// findRepresentativeClass - Return the largest legal super-reg register class | |||
/// of the register class for the specified type and its associated "cost ". | /// of the register class for the specified type and its associated "cost ". | |||
virtual std::pair<const TargetRegisterClass*, uint8_t> | virtual std::pair<const TargetRegisterClass*, uint8_t> | |||
findRepresentativeClass(EVT VT) const; | findRepresentativeClass(MVT VT) const; | |||
/// computeRegisterProperties - Once all of the register classes are adde d, | /// computeRegisterProperties - Once all of the register classes are adde d, | |||
/// this allows us to compute derived properties we expose. | /// this allows us to compute derived properties we expose. | |||
void computeRegisterProperties(); | void computeRegisterProperties(); | |||
/// setOperationAction - Indicate that the specified operation does not w ork | /// setOperationAction - Indicate that the specified operation does not w ork | |||
/// with the specified type and indicate what to do about it. | /// with the specified type and indicate what to do about it. | |||
void setOperationAction(unsigned Op, MVT VT, | void setOperationAction(unsigned Op, MVT VT, | |||
LegalizeAction Action) { | LegalizeAction Action) { | |||
assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!"); | assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!"); | |||
skipping to change at line 1248 | skipping to change at line 1096 | |||
void setPrefLoopAlignment(unsigned Align) { | void setPrefLoopAlignment(unsigned Align) { | |||
PrefLoopAlignment = Align; | PrefLoopAlignment = Align; | |||
} | } | |||
/// setMinStackArgumentAlignment - Set the minimum stack alignment of an | /// setMinStackArgumentAlignment - Set the minimum stack alignment of an | |||
/// argument (in log2(bytes)). | /// argument (in log2(bytes)). | |||
void setMinStackArgumentAlignment(unsigned Align) { | void setMinStackArgumentAlignment(unsigned Align) { | |||
MinStackArgumentAlignment = Align; | MinStackArgumentAlignment = Align; | |||
} | } | |||
/// setShouldFoldAtomicFences - Set if the target's implementation of the | ||||
/// atomic operation intrinsics includes locking. Default is false. | ||||
void setShouldFoldAtomicFences(bool fold) { | ||||
ShouldFoldAtomicFences = fold; | ||||
} | ||||
/// setInsertFencesForAtomic - Set if the DAG builder should | /// setInsertFencesForAtomic - Set if the DAG builder should | |||
/// automatically insert fences and reduce the order of atomic memory | /// automatically insert fences and reduce the order of atomic memory | |||
/// operations to Monotonic. | /// operations to Monotonic. | |||
void setInsertFencesForAtomic(bool fence) { | void setInsertFencesForAtomic(bool fence) { | |||
InsertFencesForAtomic = fence; | InsertFencesForAtomic = fence; | |||
} | } | |||
public: | public: | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Lowering methods - These methods must be implemented by targets so tha | // Addressing mode description hooks (used by LSR etc). | |||
t | ||||
// the SelectionDAGBuilder code knows how to lower these. | ||||
// | // | |||
/// LowerFormalArguments - This hook must be implemented to lower the | /// GetAddrModeArguments - CodeGenPrepare sinks address calculations into | |||
/// incoming (formal) arguments, described by the Ins array, into the | the | |||
/// specified DAG. The implementation should fill in the InVals array | /// same BB as Load/Store instructions reading the address. This allows | |||
/// with legal-type argument values, and return the resulting token | as | |||
/// chain value. | /// 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 d | |||
virtual SDValue | one | |||
LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, | /// on intrinsics which load/store. | |||
bool /*isVarArg*/, | virtual bool GetAddrModeArguments(IntrinsicInst *I, | |||
const SmallVectorImpl<ISD::InputArg> &/*Ins*/, | SmallVectorImpl<Value*> &Ops, | |||
DebugLoc /*dl*/, SelectionDAG &/*DAG*/, | Type *&AccessTy) const { | |||
SmallVectorImpl<SDValue> &/*InVals*/) const { | return false; | |||
llvm_unreachable("Not Implemented"); | ||||
} | } | |||
struct ArgListEntry { | /// AddrMode - This represents an addressing mode of: | |||
SDValue Node; | /// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg | |||
Type* Ty; | /// If BaseGV is null, there is no BaseGV. | |||
bool isSExt : 1; | /// If BaseOffs is zero, there is no base offset. | |||
bool isZExt : 1; | /// If HasBaseReg is false, there is no base register. | |||
bool isInReg : 1; | /// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg w | |||
bool isSRet : 1; | ith | |||
bool isNest : 1; | /// no scale. | |||
bool isByVal : 1; | /// | |||
uint16_t Alignment; | struct AddrMode { | |||
GlobalValue *BaseGV; | ||||
ArgListEntry() : isSExt(false), isZExt(false), isInReg(false), | int64_t BaseOffs; | |||
isSRet(false), isNest(false), isByVal(false), Alignment(0) { } | bool HasBaseReg; | |||
int64_t Scale; | ||||
AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {} | ||||
}; | }; | |||
typedef std::vector<ArgListEntry> ArgListTy; | ||||
/// CallLoweringInfo - This structure contains all information that is | ||||
/// necessary for lowering calls. It is passed to TLI::LowerCallTo when t | ||||
he | ||||
/// SelectionDAG builder needs to lower a call, and targets will see this | ||||
/// struct in their LowerCall implementation. | ||||
struct CallLoweringInfo { | ||||
SDValue Chain; | ||||
Type *RetTy; | ||||
bool RetSExt : 1; | ||||
bool RetZExt : 1; | ||||
bool IsVarArg : 1; | ||||
bool IsInReg : 1; | ||||
bool DoesNotReturn : 1; | ||||
bool IsReturnValueUsed : 1; | ||||
// IsTailCall should be modified by implementations of | ||||
// TargetLowering::LowerCall that perform tail call conversions. | ||||
bool IsTailCall; | ||||
unsigned NumFixedArgs; | /// isLegalAddressingMode - Return true if the addressing mode represente | |||
CallingConv::ID CallConv; | d by | |||
SDValue Callee; | /// AM is legal for this target, for a load/store of the specified type. | |||
ArgListTy &Args; | /// The type may be VoidTy, in which case only return true if the address | |||
SelectionDAG &DAG; | ing | |||
DebugLoc DL; | /// mode is legal for a load/store of any legal type. | |||
ImmutableCallSite *CS; | /// TODO: Handle pre/postinc as well. | |||
SmallVector<ISD::OutputArg, 32> Outs; | virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const; | |||
SmallVector<SDValue, 32> OutVals; | ||||
SmallVector<ISD::InputArg, 32> Ins; | ||||
/// CallLoweringInfo - Constructs a call lowering context based on the | /// isLegalICmpImmediate - Return true if the specified immediate is lega | |||
/// ImmutableCallSite \p cs. | l | |||
CallLoweringInfo(SDValue chain, Type *retTy, | /// icmp immediate, that is the target has icmp instructions which can co | |||
FunctionType *FTy, bool isTailCall, SDValue callee, | mpare | |||
ArgListTy &args, SelectionDAG &dag, DebugLoc dl, | /// a register against the immediate without having to materialize the | |||
ImmutableCallSite &cs) | /// immediate into a register. | |||
: Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attributes::SE | virtual bool isLegalICmpImmediate(int64_t) const { | |||
xt)), | return true; | |||
RetZExt(cs.paramHasAttr(0, Attributes::ZExt)), IsVarArg(FTy->isVarArg | } | |||
()), | ||||
IsInReg(cs.paramHasAttr(0, Attributes::InReg)), | ||||
DoesNotReturn(cs.doesNotReturn()), | ||||
IsReturnValueUsed(!cs.getInstruction()->use_empty()), | ||||
IsTailCall(isTailCall), NumFixedArgs(FTy->getNumParams()), | ||||
CallConv(cs.getCallingConv()), Callee(callee), Args(args), DAG(dag), | ||||
DL(dl), CS(&cs) {} | ||||
/// CallLoweringInfo - Constructs a call lowering context based on the | /// isLegalAddImmediate - Return true if the specified immediate is legal | |||
/// provided call information. | /// add immediate, that is the target has add instructions which can add | |||
CallLoweringInfo(SDValue chain, Type *retTy, bool retSExt, bool retZExt | /// a register with the immediate without having to materialize the | |||
, | /// immediate into a register. | |||
bool isVarArg, bool isInReg, unsigned numFixedArgs, | virtual bool isLegalAddImmediate(int64_t) const { | |||
CallingConv::ID callConv, bool isTailCall, | return true; | |||
bool doesNotReturn, bool isReturnValueUsed, SDValue ca | } | |||
llee, | ||||
ArgListTy &args, SelectionDAG &dag, DebugLoc dl) | ||||
: Chain(chain), RetTy(retTy), RetSExt(retSExt), RetZExt(retZExt), | ||||
IsVarArg(isVarArg), IsInReg(isInReg), DoesNotReturn(doesNotReturn), | ||||
IsReturnValueUsed(isReturnValueUsed), IsTailCall(isTailCall), | ||||
NumFixedArgs(numFixedArgs), CallConv(callConv), Callee(callee), | ||||
Args(args), DAG(dag), DL(dl), CS(NULL) {} | ||||
}; | ||||
/// LowerCallTo - This function lowers an abstract call to a function int | /// isTruncateFree - Return true if it's free to truncate a value of | |||
o an | /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value i | |||
/// actual call. This returns a pair of operands. The first element is | n | |||
the | /// register EAX to i16 by referencing its sub-register AX. | |||
/// return value for the function (if RetTy is not VoidTy). The second | virtual bool isTruncateFree(Type * /*Ty1*/, Type * /*Ty2*/) const { | |||
/// element is the outgoing token chain. It calls LowerCall to do the act | return false; | |||
ual | } | |||
/// lowering. | ||||
std::pair<SDValue, SDValue> LowerCallTo(CallLoweringInfo &CLI) const; | ||||
/// LowerCall - This hook must be implemented to lower calls into the | virtual bool isTruncateFree(EVT /*VT1*/, EVT /*VT2*/) const { | |||
/// the specified DAG. The outgoing arguments to the call are described | return false; | |||
/// 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. | /// isZExtFree - Return true if any actual instruction that defines a | |||
virtual void HandleByVal(CCState *, unsigned &, unsigned) const {} | /// value of type Ty1 implicitly zero-extends the value to Ty2 in the res | |||
ult | ||||
/// 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; | ||||
} | ||||
/// CanLowerReturn - This hook should be implemented to check whether the | virtual bool isZExtFree(EVT /*VT1*/, EVT /*VT2*/) const { | |||
/// return values described by the Outs array can fit into the return | return false; | |||
/// 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*/, | ||||
LLVMContext &/*Context*/) const | ||||
{ | ||||
// Return true by default to get preexisting behavior. | ||||
return true; | ||||
} | } | |||
/// LowerReturn - This hook must be implemented to lower outgoing | /// isZExtFree - Return true if zero-extending the specific node Val to t | |||
/// return values, described by the Outs array, into the specified | ype | |||
/// DAG. The implementation should return the resulting token chain | /// VT2 is free (either because it's implicitly zero-extended such as ARM | |||
/// value. | /// ldrb / ldrh or because it's folded such as X86 zero-extending loads). | |||
/// | virtual bool isZExtFree(SDValue Val, EVT VT2) const { | |||
virtual SDValue | return isZExtFree(Val.getValueType(), VT2); | |||
LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, | ||||
bool /*isVarArg*/, | ||||
const SmallVectorImpl<ISD::OutputArg> &/*Outs*/, | ||||
const SmallVectorImpl<SDValue> &/*OutVals*/, | ||||
DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const { | ||||
llvm_unreachable("Not Implemented"); | ||||
} | } | |||
/// isUsedByReturnOnly - Return true if result of the specified node is u | /// isFNegFree - Return true if an fneg operation is free to the point wh | |||
sed | ere | |||
/// by a return node only. It also compute and return the input chain for | /// it is never worthwhile to replace it with a bitwise operation. | |||
the | virtual bool isFNegFree(EVT) const { | |||
/// 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; | return false; | |||
} | } | |||
/// mayBeEmittedAsTailCall - Return true if the target may be able emit t | /// isFAbsFree - Return true if an fneg operation is free to the point wh | |||
he | ere | |||
/// call instruction as a tail call. This is used by optimization passes | /// it is never worthwhile to replace it with a bitwise operation. | |||
to | virtual bool isFAbsFree(EVT) const { | |||
/// determine if it's profitable to duplicate return instructions to enab | ||||
le | ||||
/// tailcall optimization. | ||||
virtual bool mayBeEmittedAsTailCall(CallInst *) const { | ||||
return false; | return false; | |||
} | } | |||
/// getTypeForExtArgOrReturn - Return the type that should be used to zer | /// isFMAFasterThanMulAndAdd - Return true if an FMA operation is faster | |||
o or | than | |||
/// sign extend a zeroext/signext integer argument or return value. | /// a pair of mul and add instructions. fmuladd intrinsics will be expand | |||
/// FIXME: Most C calling convention requires the return type to be promo | ed to | |||
ted, | /// FMAs when this method returns true (and FMAs are legal), otherwise fm | |||
/// but this is not true all the time, e.g. i1 on x86-64. It is also not | uladd | |||
/// necessary for non-C calling conventions. The frontend should handle t | /// is expanded to mul + add. | |||
his | virtual bool isFMAFasterThanMulAndAdd(EVT) const { | |||
/// and include all of the necessary information. | return false; | |||
virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, | ||||
ISD::NodeType /*ExtendKind*/) const | ||||
{ | ||||
EVT MinVT = getRegisterType(Context, MVT::i32); | ||||
return VT.bitsLT(MinVT) ? MinVT : VT; | ||||
} | } | |||
/// LowerOperationWrapper - This callback is invoked by the type legalize | /// isNarrowingProfitable - Return true if it's profitable to narrow | |||
r | /// operations of type VT1 to VT2. e.g. on x86, it's profitable to narrow | |||
/// to legalize nodes with an illegal operand type but legal result types | /// from i32 to i8 but not from i32 to i16. | |||
. | virtual bool isNarrowingProfitable(EVT /*VT1*/, EVT /*VT2*/) const { | |||
/// It replaces the LowerOperation callback in the type Legalizer. | return false; | |||
/// 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 nu | //===-------------------------------------------------------------------- | |||
mber | ===// | |||
/// and types must exactly match those of the original return values of | // Runtime Library hooks | |||
/// the node), or leaves Results empty, which indicates that the node is | // | |||
not | ||||
/// to be custom lowered after all. | ||||
/// The default implementation calls LowerOperation. | ||||
virtual void LowerOperationWrapper(SDNode *N, | ||||
SmallVectorImpl<SDValue> &Results, | ||||
SelectionDAG &DAG) const; | ||||
/// LowerOperation - This callback is invoked for operations that are | /// setLibcallName - Rename the default libcall routine name for the spec | |||
/// unsupported by the target, which are registered to use 'custom' lower | ified | |||
ing, | /// libcall. | |||
/// and whose defined values are all legal. | void setLibcallName(RTLIB::Libcall Call, const char *Name) { | |||
/// If the target has no operations that require custom lowering, it need | LibcallRoutineNames[Call] = Name; | |||
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 | /// getLibcallName - Get the libcall routine name for the specified libca | |||
is | ll. | |||
/// illegal for the target, and the operation was registered to use 'cust | ||||
om' | ||||
/// lowering for that result type. The target places new result values f | ||||
or | ||||
/// the node in Results (their number and types must exactly match those | ||||
of | ||||
/// the original return values of the node), or leaves Results empty, whi | ||||
ch | ||||
/// indicates that the node is not to be custom lowered after all. | ||||
/// | /// | |||
/// If the target has no operations that require custom lowering, it need | const char *getLibcallName(RTLIB::Libcall Call) const { | |||
not | return LibcallRoutineNames[Call]; | |||
/// implement this. The default implementation aborts. | ||||
virtual void ReplaceNodeResults(SDNode * /*N*/, | ||||
SmallVectorImpl<SDValue> &/*Results*/, | ||||
SelectionDAG &/*DAG*/) const { | ||||
llvm_unreachable("ReplaceNodeResults not implemented for this target!") | ||||
; | ||||
} | } | |||
/// getTargetNodeName() - This method returns the name of a target specif | /// setCmpLibcallCC - Override the default CondCode to be used to test th | |||
ic | e | |||
/// DAG node. | /// result of the comparison libcall against zero. | |||
virtual const char *getTargetNodeName(unsigned Opcode) const; | void setCmpLibcallCC(RTLIB::Libcall Call, ISD::CondCode CC) { | |||
CmpLibcallCCs[Call] = CC; | ||||
} | ||||
/// createFastISel - This method returns a target specific FastISel objec | /// getCmpLibcallCC - Get the CondCode that's to be used to test the resu | |||
t, | lt of | |||
/// or null if the target does not support "fast" ISel. | /// the comparison libcall against zero. | |||
virtual FastISel *createFastISel(FunctionLoweringInfo &, | ISD::CondCode getCmpLibcallCC(RTLIB::Libcall Call) const { | |||
const TargetLibraryInfo *) const { | return CmpLibcallCCs[Call]; | |||
return 0; | ||||
} | } | |||
//===-------------------------------------------------------------------- | /// setLibcallCallingConv - Set the CallingConv that should be used for t | |||
===// | he | |||
// Inline Asm Support hooks | /// specified libcall. | |||
// | void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) { | |||
LibcallCallingConvs[Call] = CC; | ||||
} | ||||
/// ExpandInlineAsm - This hook allows the target to expand an inline asm | /// getLibcallCallingConv - Get the CallingConv that should be used for t | |||
/// call to be explicit llvm code if it wants to. This is useful for | he | |||
/// turning simple inline asms into LLVM intrinsics, which gives the | /// specified libcall. | |||
/// compiler more information about the behavior of the code. | CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const { | |||
virtual bool ExpandInlineAsm(CallInst *) const { | return LibcallCallingConvs[Call]; | |||
return false; | ||||
} | } | |||
enum ConstraintType { | private: | |||
C_Register, // Constraint represents specific register(s). | const TargetMachine &TM; | |||
C_RegisterClass, // Constraint represents any of register(s) in c | const DataLayout *TD; | |||
lass. | const TargetLoweringObjectFile &TLOF; | |||
C_Memory, // Memory constraint. | ||||
C_Other, // Something else. | ||||
C_Unknown // Unsupported constraint. | ||||
}; | ||||
enum ConstraintWeight { | /// PointerTy - The type to use for pointers for the default address spac | |||
// Generic weights. | e, | |||
CW_Invalid = -1, // No match. | /// usually i32 or i64. | |||
CW_Okay = 0, // Acceptable. | /// | |||
CW_Good = 1, // Good weight. | MVT PointerTy; | |||
CW_Better = 2, // Better weight. | ||||
CW_Best = 3, // Best weight. | ||||
// Well-known weights. | /// IsLittleEndian - True if this is a little endian target. | |||
CW_SpecificReg = CW_Okay, // Specific register operands. | /// | |||
CW_Register = CW_Good, // Register operands. | bool IsLittleEndian; | |||
CW_Memory = CW_Better, // Memory operands. | ||||
CW_Constant = CW_Best, // Constant operand. | ||||
CW_Default = CW_Okay // Default or don't know type. | ||||
}; | ||||
/// AsmOperandInfo - This contains information for each constraint that w | /// SelectIsExpensive - Tells the code generator not to expand operations | |||
e are | /// into sequences that use the select operations if possible. | |||
/// lowering. | bool SelectIsExpensive; | |||
struct AsmOperandInfo : public InlineAsm::ConstraintInfo { | ||||
/// ConstraintCode - This contains the actual string for the code, like | ||||
"m". | ||||
/// TargetLowering picks the 'best' code from ConstraintInfo::Codes tha | ||||
t | ||||
/// most closely matches the operand. | ||||
std::string ConstraintCode; | ||||
/// ConstraintType - Information about the constraint code, e.g. Regist | /// IntDivIsCheap - Tells the code generator not to expand integer divide | |||
er, | s by | |||
/// RegisterClass, Memory, Other, Unknown. | /// constants into a sequence of muls, adds, and shifts. This is a hack | |||
TargetLowering::ConstraintType ConstraintType; | until | |||
/// a real cost model is in place. If we ever optimize for size, this wi | ||||
ll be | ||||
/// set to true unconditionally. | ||||
bool IntDivIsCheap; | ||||
/// CallOperandval - If this is the result output operand or a | /// BypassSlowDivMap - Tells the code generator to bypass slow divide or | |||
/// clobber, this is null, otherwise it is the incoming operand to the | /// remainder instructions. For example, BypassSlowDivWidths[32,8] tells | |||
/// CallInst. This gets modified as the asm is processed. | the | |||
Value *CallOperandVal; | /// code generator to bypass 32-bit integer div/rem with an 8-bit unsigne | |||
d | ||||
/// integer div/rem when the operands are positive and less than 256. | ||||
DenseMap <unsigned int, unsigned int> BypassSlowDivWidths; | ||||
/// ConstraintVT - The ValueType for the operand value. | /// Pow2DivIsCheap - Tells the code generator that it shouldn't generate | |||
EVT ConstraintVT; | /// srl/add/sra for a signed divide by power of two, and let the target h | |||
andle | ||||
/// it. | ||||
bool Pow2DivIsCheap; | ||||
/// isMatchingInputConstraint - Return true of this is an input operand | /// JumpIsExpensive - Tells the code generator that it shouldn't generate | |||
that | /// extra flow control instructions and should attempt to combine flow | |||
/// is a matching constraint like "4". | /// control instructions via predication. | |||
bool isMatchingInputConstraint() const; | bool JumpIsExpensive; | |||
/// getMatchedOperand - If this is an input matching constraint, this m | /// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement | |||
ethod | /// llvm.setjmp. Defaults to false. | |||
/// returns the output operand it matches. | bool UseUnderscoreSetJmp; | |||
unsigned getMatchedOperand() const; | ||||
/// Copy constructor for copying from an AsmOperandInfo. | /// UseUnderscoreLongJmp - This target prefers to use _longjmp to impleme | |||
AsmOperandInfo(const AsmOperandInfo &info) | nt | |||
: InlineAsm::ConstraintInfo(info), | /// llvm.longjmp. Defaults to false. | |||
ConstraintCode(info.ConstraintCode), | bool UseUnderscoreLongJmp; | |||
ConstraintType(info.ConstraintType), | ||||
CallOperandVal(info.CallOperandVal), | ||||
ConstraintVT(info.ConstraintVT) { | ||||
} | ||||
/// Copy constructor for copying from a ConstraintInfo. | /// SupportJumpTables - Whether the target can generate code for jumptabl | |||
AsmOperandInfo(const InlineAsm::ConstraintInfo &info) | es. | |||
: InlineAsm::ConstraintInfo(info), | /// If it's not true, then each jumptable must be lowered into if-then-el | |||
ConstraintType(TargetLowering::C_Unknown), | se's. | |||
CallOperandVal(0), ConstraintVT(MVT::Other) { | bool SupportJumpTables; | |||
} | ||||
}; | ||||
typedef std::vector<AsmOperandInfo> AsmOperandInfoVector; | /// MinimumJumpTableEntries - Number of blocks threshold to use jump tabl | |||
es. | ||||
int MinimumJumpTableEntries; | ||||
/// ParseConstraints - Split up the constraint string from the inline | /// BooleanContents - Information about the contents of the high-bits in | |||
/// assembly value into the specific constraints and their prefixes, | /// boolean values held in a type wider than i1. See getBooleanContents. | |||
/// and also tie in the associated operand values. | BooleanContent BooleanContents; | |||
/// If this returns an empty vector, and if the constraint string itself | /// BooleanVectorContents - Information about the contents of the high-bi | |||
/// isn't empty, there was an error parsing. | ts | |||
virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const | /// in boolean vector values when the element type is wider than i1. See | |||
; | /// getBooleanContents. | |||
BooleanContent BooleanVectorContents; | ||||
/// Examine constraint type and operand type and determine a weight value | /// SchedPreferenceInfo - The target scheduling preference: shortest poss | |||
. | ible | |||
/// The operand object must already have been set up with the operand typ | /// total cycles or lowest register usage. | |||
e. | Sched::Preference SchedPreferenceInfo; | |||
virtual ConstraintWeight getMultipleConstraintMatchWeight( | ||||
AsmOperandInfo &info, int maIndex) const; | ||||
/// Examine constraint string and operand type and determine a weight val | /// JumpBufSize - The size, in bytes, of the target's jmp_buf buffers | |||
ue. | unsigned JumpBufSize; | |||
/// The operand object must already have been set up with the operand typ | ||||
e. | ||||
virtual ConstraintWeight getSingleConstraintMatchWeight( | ||||
AsmOperandInfo &info, const char *constraint) const; | ||||
/// ComputeConstraintToUse - Determines the constraint code and constrain | /// JumpBufAlignment - The alignment, in bytes, of the target's jmp_buf | |||
t | /// buffers | |||
/// type to use for the specific AsmOperandInfo, setting | unsigned JumpBufAlignment; | |||
/// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual opera | ||||
nd | ||||
/// 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 | /// MinStackArgumentAlignment - The minimum alignment that any argument | |||
it | /// on the stack needs to have. | |||
/// is for this target. | /// | |||
virtual ConstraintType getConstraintType(const std::string &Constraint) c | unsigned MinStackArgumentAlignment; | |||
onst; | ||||
/// getRegForInlineAsmConstraint - Given a physical register constraint ( | /// MinFunctionAlignment - The minimum function alignment (used when | |||
e.g. | /// optimizing for size, and to prevent explicitly provided alignment | |||
/// {edx}), return the register number and the register class for the | /// from leading to incorrect code). | |||
/// register. | ||||
/// | /// | |||
/// Given a register class constraint, like 'r', if this corresponds dire | unsigned MinFunctionAlignment; | |||
ctly | ||||
/// to an LLVM register class, return a register of 0 and the register cl | /// PrefFunctionAlignment - The preferred function alignment (used when | |||
ass | /// alignment unspecified and optimizing for speed). | |||
/// pointer. | ||||
/// | /// | |||
/// This should only be used for C_Register constraints. On error, | unsigned PrefFunctionAlignment; | |||
/// 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; | ||||
/// LowerXConstraint - try to replace an X constraint, which matches anyt | /// PrefLoopAlignment - The preferred loop alignment. | |||
hing, | /// | |||
/// with another that has more specific requirements based on the type of | unsigned PrefLoopAlignment; | |||
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 O | /// InsertFencesForAtomic - Whether the DAG builder should automatically | |||
ps | /// insert fences and reduce ordering for atomics. (This will be set for | |||
/// vector. If it is invalid, don't add anything to Ops. | /// for most architectures with weak memory ordering.) | |||
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constr | bool InsertFencesForAtomic; | |||
aint, | ||||
std::vector<SDValue> &Ops, | ||||
SelectionDAG &DAG) const; | ||||
//===-------------------------------------------------------------------- | /// StackPointerRegisterToSaveRestore - If set to a physical register, th | |||
===// | is | |||
// Instruction Emitting Hooks | /// specifies the register that llvm.savestack/llvm.restorestack should s | |||
// | ave | |||
/// and restore. | ||||
unsigned StackPointerRegisterToSaveRestore; | ||||
// EmitInstrWithCustomInserter - This method should be implemented by tar | /// ExceptionPointerRegister - If set to a physical register, this specif | |||
gets | ies | |||
// that mark instructions with the 'usesCustomInserter' flag. These | /// the register that receives the exception address on entry to a landin | |||
// instructions are special in various ways, which require special suppor | g | |||
t to | /// pad. | |||
// insert. The specified MachineInstr is created but not inserted into a | unsigned ExceptionPointerRegister; | |||
ny | ||||
// basic blocks, and this method is called to expand it into a sequence o | ||||
f | ||||
// instructions, potentially also creating new basic blocks and control f | ||||
low. | ||||
virtual MachineBasicBlock * | ||||
EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) c | ||||
onst; | ||||
/// AdjustInstrPostInstrSelection - This method should be implemented by | /// ExceptionSelectorRegister - If set to a physical register, this speci | |||
/// targets that mark instructions with the 'hasPostISelHook' flag. These | fies | |||
/// instructions must be adjusted after instruction selection by target h | /// the register that receives the exception typeid on entry to a landing | |||
ooks. | /// pad. | |||
/// e.g. To fill in optional defs for ARM 's' setting instructions. | unsigned ExceptionSelectorRegister; | |||
virtual void | ||||
AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const; | ||||
//===-------------------------------------------------------------------- | /// RegClassForVT - This indicates the default register class to use for | |||
===// | /// each ValueType the target supports natively. | |||
// Addressing mode description hooks (used by LSR etc). | const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE]; | |||
// | unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE]; | |||
MVT RegisterTypeForVT[MVT::LAST_VALUETYPE]; | ||||
/// GetAddrModeArguments - CodeGenPrepare sinks address calculations into | /// RepRegClassForVT - This indicates the "representative" register class | |||
the | to | |||
/// same BB as Load/Store instructions reading the address. This allows | /// use for each ValueType the target supports natively. This information | |||
as | is | |||
/// much computation as possible to be done in the address mode for that | /// used by the scheduler to track register pressure. By default, the | |||
/// operand. This hook lets targets also pass back when this should be d | /// representative register class is the largest legal super-reg register | |||
one | /// class of the register class of the specified type. e.g. On x86, i8, i | |||
/// on intrinsics which load/store. | 16, | |||
virtual bool GetAddrModeArguments(IntrinsicInst *I, | /// and i32's representative class would be GR32. | |||
SmallVectorImpl<Value*> &Ops, | const TargetRegisterClass *RepRegClassForVT[MVT::LAST_VALUETYPE]; | |||
Type *&AccessTy) const { | ||||
return false; | ||||
} | ||||
/// isLegalAddressingMode - Return true if the addressing mode represente | /// RepRegClassCostForVT - This indicates the "cost" of the "representati | |||
d by | ve" | |||
/// AM is legal for this target, for a load/store of the specified type. | /// register class for each ValueType. The cost is used by the scheduler | |||
/// The type may be VoidTy, in which case only return true if the address | to | |||
ing | /// approximate register pressure. | |||
/// mode is legal for a load/store of any legal type. | uint8_t RepRegClassCostForVT[MVT::LAST_VALUETYPE]; | |||
/// TODO: Handle pre/postinc as well. | ||||
virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const; | ||||
/// isLegalICmpImmediate - Return true if the specified immediate is lega | /// TransformToType - For any value types we are promoting or expanding, | |||
l | this | |||
/// icmp immediate, that is the target has icmp instructions which can co | /// contains the value type that we are changing to. For Expanded types, | |||
mpare | this | |||
/// a register against the immediate without having to materialize the | /// contains one step of the expand (e.g. i64 -> i32), even if there are | |||
/// immediate into a register. | /// multiple steps required (e.g. i64 -> i16). For types natively suppor | |||
virtual bool isLegalICmpImmediate(int64_t) const { | ted | |||
return true; | /// by the system, this holds the same type (e.g. i32 -> i32). | |||
} | MVT TransformToType[MVT::LAST_VALUETYPE]; | |||
/// 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. | ||||
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 i | ||||
n | ||||
/// register EAX to i16 by referencing its sub-register AX. | ||||
virtual bool isTruncateFree(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 res | ||||
ult | ||||
/// 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; | ||||
} | ||||
virtual bool isZExtFree(EVT /*VT1*/, EVT /*VT2*/) const { | ||||
return false; | ||||
} | ||||
/// isFNegFree - Return true if an fneg operation is free to the point wh | ||||
ere | ||||
/// it is never worthwhile to replace it with a bitwise operation. | ||||
virtual bool isFNegFree(EVT) const { | ||||
return false; | ||||
} | ||||
/// isFAbsFree - Return true if an fneg operation is free to the point wh | ||||
ere | ||||
/// it is never worthwhile to replace it with a bitwise operation. | ||||
virtual bool isFAbsFree(EVT) const { | ||||
return false; | ||||
} | ||||
/// isFMAFasterThanMulAndAdd - Return true if an FMA operation is faster | ||||
than | ||||
/// a pair of mul and add instructions. fmuladd intrinsics will be expand | ||||
ed to | ||||
/// FMAs when this method returns true (and FMAs are legal), otherwise fm | ||||
uladd | ||||
/// is expanded to mul + add. | ||||
virtual bool isFMAFasterThanMulAndAdd(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. | ||||
virtual bool isNarrowingProfitable(EVT /*VT1*/, EVT /*VT2*/) const { | ||||
return false; | ||||
} | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
// Div utility functions | ||||
// | ||||
SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl, | ||||
SelectionDAG &DAG) const; | ||||
SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, | ||||
std::vector<SDNode*>* Created) const; | ||||
SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, | ||||
std::vector<SDNode*>* Created) const; | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
// Runtime Library hooks | ||||
// | ||||
/// setLibcallName - Rename the default libcall routine name for the spec | ||||
ified | ||||
/// libcall. | ||||
void setLibcallName(RTLIB::Libcall Call, const char *Name) { | ||||
LibcallRoutineNames[Call] = Name; | ||||
} | ||||
/// getLibcallName - Get the libcall routine name for the specified libca | ||||
ll. | ||||
/// | ||||
const char *getLibcallName(RTLIB::Libcall Call) const { | ||||
return LibcallRoutineNames[Call]; | ||||
} | ||||
/// setCmpLibcallCC - Override the default CondCode to be used to test th | ||||
e | ||||
/// 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 resu | ||||
lt 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 t | ||||
he | ||||
/// specified libcall. | ||||
void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) { | ||||
LibcallCallingConvs[Call] = CC; | ||||
} | ||||
/// getLibcallCallingConv - Get the CallingConv that should be used for t | ||||
he | ||||
/// specified libcall. | ||||
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const { | ||||
return LibcallCallingConvs[Call]; | ||||
} | ||||
private: | ||||
const TargetMachine &TM; | ||||
const DataLayout *TD; | ||||
const TargetLoweringObjectFile &TLOF; | ||||
/// PointerTy - The type to use for pointers for the default address spac | ||||
e, | ||||
/// usually i32 or i64. | ||||
/// | ||||
MVT PointerTy; | ||||
/// IsLittleEndian - 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. | ||||
bool SelectIsExpensive; | ||||
/// IntDivIsCheap - Tells the code generator not to expand integer divide | ||||
s 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 wi | ||||
ll 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 unsigne | ||||
d | ||||
/// 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 h | ||||
andle | ||||
/// it. | ||||
bool Pow2DivIsCheap; | ||||
/// JumpIsExpensive - Tells the code generator that it shouldn't generate | ||||
/// extra flow control instructions and should attempt to combine flow | ||||
/// control instructions via predication. | ||||
bool JumpIsExpensive; | ||||
/// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement | ||||
/// llvm.setjmp. Defaults to false. | ||||
bool UseUnderscoreSetJmp; | ||||
/// UseUnderscoreLongJmp - This target prefers to use _longjmp to impleme | ||||
nt | ||||
/// llvm.longjmp. Defaults to false. | ||||
bool UseUnderscoreLongJmp; | ||||
/// SupportJumpTables - Whether the target can generate code for jumptabl | ||||
es. | ||||
/// If it's not true, then each jumptable must be lowered into if-then-el | ||||
se's. | ||||
bool SupportJumpTables; | ||||
/// MinimumJumpTableEntries - Number of blocks threshold to use jump tabl | ||||
es. | ||||
int MinimumJumpTableEntries; | ||||
/// BooleanContents - 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-bi | ||||
ts | ||||
/// in boolean vector values when the element type is wider than i1. See | ||||
/// getBooleanContents. | ||||
BooleanContent BooleanVectorContents; | ||||
/// SchedPreferenceInfo - The target scheduling preference: shortest poss | ||||
ible | ||||
/// total cycles or lowest register usage. | ||||
Sched::Preference SchedPreferenceInfo; | ||||
/// JumpBufSize - 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 | ||||
unsigned JumpBufAlignment; | ||||
/// MinStackArgumentAlignment - 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). | ||||
/// | ||||
unsigned MinFunctionAlignment; | ||||
/// PrefFunctionAlignment - The preferred function alignment (used when | ||||
/// alignment unspecified and optimizing for speed). | ||||
/// | ||||
unsigned PrefFunctionAlignment; | ||||
/// PrefLoopAlignment - The preferred loop alignment. | ||||
/// | ||||
unsigned PrefLoopAlignment; | ||||
/// ShouldFoldAtomicFences - Whether fencing MEMBARRIER instructions shou | ||||
ld | ||||
/// be folded into the enclosed atomic intrinsic instruction by the | ||||
/// combiner. | ||||
bool ShouldFoldAtomicFences; | ||||
/// 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.) | ||||
bool InsertFencesForAtomic; | ||||
/// StackPointerRegisterToSaveRestore - If set to a physical register, th | ||||
is | ||||
/// specifies the register that llvm.savestack/llvm.restorestack should s | ||||
ave | ||||
/// and restore. | ||||
unsigned StackPointerRegisterToSaveRestore; | ||||
/// ExceptionPointerRegister - If set to a physical register, this specif | ||||
ies | ||||
/// the register that receives the exception address on entry to a landin | ||||
g | ||||
/// pad. | ||||
unsigned ExceptionPointerRegister; | ||||
/// ExceptionSelectorRegister - If set to a physical register, this speci | ||||
fies | ||||
/// 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. | ||||
const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE]; | ||||
unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE]; | ||||
EVT 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, i | ||||
16, | ||||
/// and i32's representative class would be GR32. | ||||
const TargetRegisterClass *RepRegClassForVT[MVT::LAST_VALUETYPE]; | ||||
/// RepRegClassCostForVT - This indicates the "cost" of the "representati | ||||
ve" | ||||
/// 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 suppor | ||||
ted | ||||
/// by the system, this holds the same type (e.g. i32 -> i32). | ||||
EVT TransformToType[MVT::LAST_VALUETYPE]; | ||||
/// OpActions - For each operation and each value type, keep a LegalizeAc tion | /// OpActions - For each operation and each value type, keep a LegalizeAc tion | |||
/// that indicates how instruction selection should deal with the operati on. | /// that indicates how instruction selection should deal with the operati on. | |||
/// Most operations are Legal (aka, supported natively by the target), bu t | /// Most operations are Legal (aka, supported natively by the target), bu t | |||
/// operations that are not should be described. Note that operations on | /// operations that are not should be described. Note that operations on | |||
/// non-legal value types are not described here. | /// non-legal value types are not described here. | |||
uint8_t OpActions[MVT::LAST_VALUETYPE][ISD::BUILTIN_OP_END]; | uint8_t OpActions[MVT::LAST_VALUETYPE][ISD::BUILTIN_OP_END]; | |||
/// LoadExtActions - For each load extension type and each value type, | /// LoadExtActions - For each load extension type and each value type, | |||
/// keep a LegalizeAction that indicates how instruction selection should deal | /// keep a LegalizeAction that indicates how instruction selection should deal | |||
skipping to change at line 1968 | skipping to change at line 1438 | |||
/// dividing the MVT::LAST_VALUETYPE by 32 and adding one. | /// dividing the MVT::LAST_VALUETYPE by 32 and adding one. | |||
uint64_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE / 32) + 1]; | uint64_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE / 32) + 1]; | |||
ValueTypeActionImpl ValueTypeActions; | ValueTypeActionImpl ValueTypeActions; | |||
public: | public: | |||
LegalizeKind | LegalizeKind | |||
getTypeConversion(LLVMContext &Context, EVT VT) const { | getTypeConversion(LLVMContext &Context, EVT VT) const { | |||
// If this is a simple type, use the ComputeRegisterProp mechanism. | // If this is a simple type, use the ComputeRegisterProp mechanism. | |||
if (VT.isSimple()) { | if (VT.isSimple()) { | |||
assert((unsigned)VT.getSimpleVT().SimpleTy < | MVT SVT = VT.getSimpleVT(); | |||
array_lengthof(TransformToType)); | assert((unsigned)SVT.SimpleTy < array_lengthof(TransformToType)); | |||
EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy]; | MVT NVT = TransformToType[SVT.SimpleTy]; | |||
LegalizeTypeAction LA = ValueTypeActions.getTypeAction(VT.getSimpleVT | LegalizeTypeAction LA = ValueTypeActions.getTypeAction(SVT); | |||
()); | ||||
assert( | assert( | |||
(!(NVT.isSimple() && LA != TypeLegal) || | (LA == TypeLegal || | |||
ValueTypeActions.getTypeAction(NVT.getSimpleVT()) != TypePromoteIn | ValueTypeActions.getTypeAction(NVT) != TypePromoteInteger) | |||
teger) | ||||
&& "Promote may not follow Expand or Promote"); | && "Promote may not follow Expand or Promote"); | |||
if (LA == TypeSplitVector) | if (LA == TypeSplitVector) | |||
NVT = EVT::getVectorVT(Context, VT.getVectorElementType(), | return LegalizeKind(LA, EVT::getVectorVT(Context, | |||
VT.getVectorNumElements() / 2); | SVT.getVectorElementType() | |||
, | ||||
SVT.getVectorNumElements() | ||||
/2)); | ||||
if (LA == TypeScalarizeVector) | ||||
return LegalizeKind(LA, SVT.getVectorElementType()); | ||||
return LegalizeKind(LA, NVT); | return LegalizeKind(LA, NVT); | |||
} | } | |||
// Handle Extended Scalar Types. | // Handle Extended Scalar Types. | |||
if (!VT.isVector()) { | if (!VT.isVector()) { | |||
assert(VT.isInteger() && "Float types must be simple"); | assert(VT.isInteger() && "Float types must be simple"); | |||
unsigned BitSize = VT.getSizeInBits(); | unsigned BitSize = VT.getSizeInBits(); | |||
// First promote to a power-of-two size, then expand if necessary. | // First promote to a power-of-two size, then expand if necessary. | |||
if (BitSize < 8 || !isPowerOf2_32(BitSize)) { | if (BitSize < 8 || !isPowerOf2_32(BitSize)) { | |||
EVT NVT = VT.getRoundIntegerType(Context); | EVT NVT = VT.getRoundIntegerType(Context); | |||
skipping to change at line 2034 | skipping to change at line 1507 | |||
// If type is to be expanded, split the vector. | // If type is to be expanded, split the vector. | |||
// <4 x i140> -> <2 x i140> | // <4 x i140> -> <2 x i140> | |||
if (LK.first == TypeExpandInteger) | if (LK.first == TypeExpandInteger) | |||
return LegalizeKind(TypeSplitVector, | return LegalizeKind(TypeSplitVector, | |||
EVT::getVectorVT(Context, EltVT, NumElts / 2)); | EVT::getVectorVT(Context, EltVT, NumElts / 2)); | |||
// Promote the integer element types until a legal vector type is fou nd | // Promote the integer element types until a legal vector type is fou nd | |||
// or until the element integer type is too big. If a legal type was not | // or until the element integer type is too big. If a legal type was not | |||
// found, fallback to the usual mechanism of widening/splitting the | // found, fallback to the usual mechanism of widening/splitting the | |||
// vector. | // vector. | |||
EVT OldEltVT = EltVT; | ||||
while (1) { | while (1) { | |||
// Increase the bitwidth of the element to the next pow-of-two | // Increase the bitwidth of the element to the next pow-of-two | |||
// (which is greater than 8 bits). | // (which is greater than 8 bits). | |||
EltVT = EVT::getIntegerVT(Context, 1 + EltVT.getSizeInBits() | EltVT = EVT::getIntegerVT(Context, 1 + EltVT.getSizeInBits() | |||
).getRoundIntegerType(Context); | ).getRoundIntegerType(Context); | |||
// Stop trying when getting a non-simple element type. | // Stop trying when getting a non-simple element type. | |||
// Note that vector elements may be greater than legal vector eleme nt | // Note that vector elements may be greater than legal vector eleme nt | |||
// types. Example: X86 XMM registers hold 64bit element on 32bit sy stems. | // types. Example: X86 XMM registers hold 64bit element on 32bit sy stems. | |||
if (!EltVT.isSimple()) break; | if (!EltVT.isSimple()) break; | |||
// Build a new vector type and check if it is legal. | // Build a new vector type and check if it is legal. | |||
MVT NVT = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); | MVT NVT = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); | |||
// Found a legal promoted vector type. | // Found a legal promoted vector type. | |||
if (NVT != MVT() && ValueTypeActions.getTypeAction(NVT) == TypeLega l) | if (NVT != MVT() && ValueTypeActions.getTypeAction(NVT) == TypeLega l) | |||
return LegalizeKind(TypePromoteInteger, | return LegalizeKind(TypePromoteInteger, | |||
EVT::getVectorVT(Context, EltVT, NumElts)); | EVT::getVectorVT(Context, EltVT, NumElts)); | |||
} | } | |||
// Reset the type to the unexpanded type if we did not find a legal v | ||||
ector | ||||
// type with a promoted vector element type. | ||||
EltVT = OldEltVT; | ||||
} | } | |||
// Try to widen the vector until a legal type is found. | // Try to widen the vector until a legal type is found. | |||
// If there is no wider legal type, split the vector. | // If there is no wider legal type, split the vector. | |||
while (1) { | while (1) { | |||
// Round up to the next power of 2. | // Round up to the next power of 2. | |||
NumElts = (unsigned)NextPowerOf2(NumElts); | NumElts = (unsigned)NextPowerOf2(NumElts); | |||
// If there is no simple vector type with this many elements then the re | // If there is no simple vector type with this many elements then the re | |||
// cannot be a larger legal vector type. Note that this assumes that | // cannot be a larger legal vector type. Note that this assumes that | |||
skipping to change at line 2084 | skipping to change at line 1562 | |||
EVT NVT = VT.getPow2VectorType(Context); | EVT NVT = VT.getPow2VectorType(Context); | |||
return LegalizeKind(TypeWidenVector, NVT); | return LegalizeKind(TypeWidenVector, NVT); | |||
} | } | |||
// Vectors with illegal element types are expanded. | // Vectors with illegal element types are expanded. | |||
EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2); | EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2); | |||
return LegalizeKind(TypeSplitVector, NVT); | return LegalizeKind(TypeSplitVector, NVT); | |||
} | } | |||
private: | private: | |||
std::vector<std::pair<EVT, const TargetRegisterClass*> > AvailableRegClas ses; | std::vector<std::pair<MVT, const TargetRegisterClass*> > AvailableRegClas ses; | |||
/// TargetDAGCombineArray - Targets can specify ISD nodes that they would | /// TargetDAGCombineArray - Targets can specify ISD nodes that they would | |||
/// like PerformDAGCombine callbacks for by calling setTargetDAGCombine() , | /// like PerformDAGCombine callbacks for by calling setTargetDAGCombine() , | |||
/// which sets a bit in this array. | /// which sets a bit in this array. | |||
unsigned char | unsigned char | |||
TargetDAGCombineArray[(ISD::BUILTIN_OP_END+CHAR_BIT-1)/CHAR_BIT]; | TargetDAGCombineArray[(ISD::BUILTIN_OP_END+CHAR_BIT-1)/CHAR_BIT]; | |||
/// PromoteToType - For operations that must be promoted to a specific ty pe, | /// PromoteToType - For operations that must be promoted to a specific ty pe, | |||
/// this holds the destination type. This map should be sparse, so don't hold | /// this holds the destination type. This map should be sparse, so don't hold | |||
/// it as an array. | /// it as an array. | |||
skipping to change at line 2123 | skipping to change at line 1601 | |||
protected: | protected: | |||
/// When lowering \@llvm.memset this field specifies the maximum number o f | /// When lowering \@llvm.memset this field specifies the maximum number o f | |||
/// store operations that may be substituted for the call to memset. Targ ets | /// store operations that may be substituted for the call to memset. Targ ets | |||
/// must set this value based on the cost threshold for that target. Targ ets | /// must set this value based on the cost threshold for that target. Targ ets | |||
/// should assume that the memset will be done using as many of the large st | /// should assume that the memset will be done using as many of the large st | |||
/// store operations first, followed by smaller ones, if necessary, per | /// store operations first, followed by smaller ones, if necessary, per | |||
/// alignment restrictions. For example, storing 9 bytes on a 32-bit mach ine | /// alignment restrictions. For example, storing 9 bytes on a 32-bit mach ine | |||
/// with 16-bit alignment would result in four 2-byte stores and one 1-by te | /// with 16-bit alignment would result in four 2-byte stores and one 1-by te | |||
/// store. This only applies to setting a constant array of a constant s ize. | /// store. This only applies to setting a constant array of a constant s ize. | |||
/// @brief Specify maximum number of store instructions per memset call. | /// @brief Specify maximum number of store instructions per memset call. | |||
unsigned maxStoresPerMemset; | unsigned MaxStoresPerMemset; | |||
/// Maximum number of stores operations that may be substituted for the c all | /// Maximum number of stores operations that may be substituted for the c all | |||
/// to memset, used for functions with OptSize attribute. | /// to memset, used for functions with OptSize attribute. | |||
unsigned maxStoresPerMemsetOptSize; | unsigned MaxStoresPerMemsetOptSize; | |||
/// When lowering \@llvm.memcpy this field specifies the maximum number o f | /// When lowering \@llvm.memcpy this field specifies the maximum number o f | |||
/// store operations that may be substituted for a call to memcpy. Target s | /// store operations that may be substituted for a call to memcpy. Target s | |||
/// must set this value based on the cost threshold for that target. Targ ets | /// must set this value based on the cost threshold for that target. Targ ets | |||
/// should assume that the memcpy will be done using as many of the large st | /// should assume that the memcpy will be done using as many of the large st | |||
/// store operations first, followed by smaller ones, if necessary, per | /// store operations first, followed by smaller ones, if necessary, per | |||
/// alignment restrictions. For example, storing 7 bytes on a 32-bit mach ine | /// alignment restrictions. For example, storing 7 bytes on a 32-bit mach ine | |||
/// with 32-bit alignment would result in one 4-byte store, a one 2-byte store | /// 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 o f | /// and one 1-byte store. This only applies to copying a constant array o f | |||
/// constant size. | /// constant size. | |||
/// @brief Specify maximum bytes of store instructions per memcpy call. | /// @brief Specify maximum bytes of store instructions per memcpy call. | |||
unsigned maxStoresPerMemcpy; | unsigned MaxStoresPerMemcpy; | |||
/// Maximum number of store operations that may be substituted for a call | /// Maximum number of store operations that may be substituted for a call | |||
/// to memcpy, used for functions with OptSize attribute. | /// to memcpy, used for functions with OptSize attribute. | |||
unsigned maxStoresPerMemcpyOptSize; | unsigned MaxStoresPerMemcpyOptSize; | |||
/// When lowering \@llvm.memmove this field specifies the maximum number of | /// When lowering \@llvm.memmove this field specifies the maximum number of | |||
/// store instructions that may be substituted for a call to memmove. Tar gets | /// store instructions that may be substituted for a call to memmove. Tar gets | |||
/// must set this value based on the cost threshold for that target. Targ ets | /// must set this value based on the cost threshold for that target. Targ ets | |||
/// should assume that the memmove will be done using as many of the larg est | /// should assume that the memmove will be done using as many of the larg est | |||
/// store operations first, followed by smaller ones, if necessary, per | /// store operations first, followed by smaller ones, if necessary, per | |||
/// alignment restrictions. For example, moving 9 bytes on a 32-bit machi ne | /// alignment restrictions. For example, moving 9 bytes on a 32-bit machi ne | |||
/// with 8-bit alignment would result in nine 1-byte stores. This only | /// with 8-bit alignment would result in nine 1-byte stores. This only | |||
/// applies to copying a constant array of constant size. | /// applies to copying a constant array of constant size. | |||
/// @brief Specify maximum bytes of store instructions per memmove call. | /// @brief Specify maximum bytes of store instructions per memmove call. | |||
unsigned maxStoresPerMemmove; | unsigned MaxStoresPerMemmove; | |||
/// Maximum number of store instructions that may be substituted for a ca ll | /// Maximum number of store instructions that may be substituted for a ca ll | |||
/// to memmove, used for functions with OpSize attribute. | /// to memmove, used for functions with OpSize attribute. | |||
unsigned maxStoresPerMemmoveOptSize; | unsigned MaxStoresPerMemmoveOptSize; | |||
/// This field specifies whether the target can benefit from code placeme | ||||
nt | ||||
/// optimization. | ||||
bool benefitFromCodePlacementOpt; | ||||
/// predictableSelectIsExpensive - Tells the code generator that select i s | /// PredictableSelectIsExpensive - Tells the code generator that select i s | |||
/// more expensive than a branch if the branch is usually predicted right . | /// more expensive than a branch if the branch is usually predicted right . | |||
bool predictableSelectIsExpensive; | bool PredictableSelectIsExpensive; | |||
private: | protected: | |||
/// isLegalRC - Return true if the value types that can be represented by the | /// isLegalRC - Return true if the value types that can be represented by the | |||
/// specified register class are all legal. | /// specified register class are all legal. | |||
bool isLegalRC(const TargetRegisterClass *RC) const; | 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 a | ||||
ccept | ||||
/// 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; | ||||
public: | ||||
/// NOTE: The constructor takes ownership of TLOF. | ||||
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. | ||||
virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/, | ||||
SDValue &/*Offset*/, | ||||
ISD::MemIndexedMode &/*AM*/, | ||||
SelectionDAG &/*DAG*/) const { | ||||
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. | ||||
virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/, | ||||
SDValue &/*Base*/, SDValue &/*Off | ||||
set*/, | ||||
ISD::MemIndexedMode &/*AM*/, | ||||
SelectionDAG &/*DAG*/) const { | ||||
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. | ||||
virtual unsigned getJumpTableEncoding() const; | ||||
virtual const MCExpr * | ||||
LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/, | ||||
const MachineBasicBlock * /*MBB*/, unsigned /*u | ||||
id*/, | ||||
MCContext &/*Ctx*/) const { | ||||
llvm_unreachable("Need to implement this hook if target has custom JTIs | ||||
"); | ||||
} | ||||
/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC | ||||
/// jumptable. | ||||
virtual SDValue getPICJumpTableRelocBase(SDValue Table, | ||||
SelectionDAG &DAG) const; | ||||
/// getPICJumpTableRelocBaseExpr - This returns the relocation base for t | ||||
he | ||||
/// 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. | ||||
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; | ||||
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, | ||||
SDValue &Chain) const; | ||||
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, | ||||
SDValue &NewLHS, SDValue &NewRHS, | ||||
ISD::CondCode &CCCode, DebugLoc DL) const; | ||||
SDValue makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, | ||||
const SDValue *Ops, unsigned NumOps, | ||||
bool isSigned, DebugLoc dl) const; | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
// 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 | ||||
struct TargetLoweringOpt { | ||||
SelectionDAG &DAG; | ||||
bool LegalTys; | ||||
bool LegalOps; | ||||
SDValue Old; | ||||
SDValue New; | ||||
explicit TargetLoweringOpt(SelectionDAG &InDAG, | ||||
bool LT, bool LO) : | ||||
DAG(InDAG), LegalTys(LT), LegalOps(LO) {} | ||||
bool LegalTypes() const { return LegalTys; } | ||||
bool LegalOperations() const { return LegalOps; } | ||||
bool CombineTo(SDValue O, SDValue N) { | ||||
Old = O; | ||||
New = N; | ||||
return true; | ||||
} | ||||
/// ShrinkDemandedConstant - Check to see if the specified operand of t | ||||
he | ||||
/// specified instruction is a constant integer. If so, check to see i | ||||
f | ||||
/// there are any bits set in the constant that are not demanded. If s | ||||
o, | ||||
/// shrink the constant and return true. | ||||
bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded); | ||||
/// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if th | ||||
e | ||||
/// casts are free. This uses isZExtFree and ZERO_EXTEND for the widen | ||||
ing | ||||
/// cast, but it could be generalized for targets with other types of | ||||
/// implicit widening casts. | ||||
bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Deman | ||||
ded, | ||||
DebugLoc 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 w | ||||
e 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) con | ||||
st; | ||||
/// computeMaskedBitsForTargetNode - Determine which of the bits specifie | ||||
d 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. | ||||
virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op, | ||||
unsigned Depth = 0) cons | ||||
t; | ||||
struct DAGCombinerInfo { | ||||
void *DC; // The DAG Combiner object. | ||||
CombineLevel Level; | ||||
bool CalledByLegalizer; | ||||
public: | ||||
SelectionDAG &DAG; | ||||
DAGCombinerInfo(SelectionDAG &dag, CombineLevel level, bool cl, void * | ||||
dc) | ||||
: DC(dc), Level(level), CalledByLegalizer(cl), DAG(dag) {} | ||||
bool isBeforeLegalize() const { return Level == BeforeLegalizeTypes; } | ||||
bool isBeforeLegalizeOps() const { return Level < AfterLegalizeVectorOp | ||||
s; } | ||||
bool isAfterLegalizeVectorOps() const { | ||||
return Level == AfterLegalizeDAG; | ||||
} | ||||
CombineLevel getDAGCombineLevel() { return Level; } | ||||
bool isCalledByLegalizer() const { return CalledByLegalizer; } | ||||
void AddToWorklist(SDNode *N); | ||||
void RemoveFromWorklist(SDNode *N); | ||||
SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To, | ||||
bool AddTo = true); | ||||
SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true); | ||||
SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = t | ||||
rue); | ||||
void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO); | ||||
}; | ||||
/// SimplifySetCC - Try to simplify a setcc built with the specified oper | ||||
ands | ||||
/// 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, DebugLoc dl) const; | ||||
/// isGAPlusOffset - 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. | ||||
/// | ||||
/// The semantics are as follows: | ||||
/// Return Value: | ||||
/// SDValue.Val == 0 - No change was made | ||||
/// SDValue.Val == N - N was replaced, is dead, and is already handle | ||||
d. | ||||
/// otherwise - N should be replaced by the returned Operand. | ||||
/// | ||||
/// In addition, methods provided by DAGCombinerInfo may be used to perfo | ||||
rm | ||||
/// more complex transformations. | ||||
/// | ||||
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; | ||||
/// isTypeDesirableForOp - Return true if the target has native support f | ||||
or | ||||
/// the specified value type and it is 'desirable' to use the type for th | ||||
e | ||||
/// 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 comb | ||||
iner | ||||
/// 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, i | ||||
t | ||||
/// should return the desired promotion type by reference. | ||||
virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const { | ||||
return false; | ||||
} | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
// Lowering methods - These methods must be implemented by targets so tha | ||||
t | ||||
// 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. | ||||
/// | ||||
virtual SDValue | ||||
LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, | ||||
bool /*isVarArg*/, | ||||
const SmallVectorImpl<ISD::InputArg> &/*Ins*/, | ||||
DebugLoc /*dl*/, SelectionDAG &/*DAG*/, | ||||
SmallVectorImpl<SDValue> &/*InVals*/) const { | ||||
llvm_unreachable("Not Implemented"); | ||||
} | ||||
struct ArgListEntry { | ||||
SDValue Node; | ||||
Type* Ty; | ||||
bool isSExt : 1; | ||||
bool isZExt : 1; | ||||
bool isInReg : 1; | ||||
bool isSRet : 1; | ||||
bool isNest : 1; | ||||
bool isByVal : 1; | ||||
bool isReturned : 1; | ||||
uint16_t Alignment; | ||||
ArgListEntry() : isSExt(false), isZExt(false), isInReg(false), | ||||
isSRet(false), isNest(false), isByVal(false), isReturned(false), | ||||
Alignment(0) { } | ||||
}; | ||||
typedef std::vector<ArgListEntry> ArgListTy; | ||||
/// CallLoweringInfo - This structure contains all information that is | ||||
/// necessary for lowering calls. It is passed to TLI::LowerCallTo when t | ||||
he | ||||
/// SelectionDAG builder needs to lower a call, and targets will see this | ||||
/// struct in their LowerCall implementation. | ||||
struct CallLoweringInfo { | ||||
SDValue Chain; | ||||
Type *RetTy; | ||||
bool RetSExt : 1; | ||||
bool RetZExt : 1; | ||||
bool IsVarArg : 1; | ||||
bool IsInReg : 1; | ||||
bool DoesNotReturn : 1; | ||||
bool IsReturnValueUsed : 1; | ||||
// IsTailCall should be modified by implementations of | ||||
// TargetLowering::LowerCall that perform tail call conversions. | ||||
bool IsTailCall; | ||||
unsigned NumFixedArgs; | ||||
CallingConv::ID CallConv; | ||||
SDValue Callee; | ||||
ArgListTy &Args; | ||||
SelectionDAG &DAG; | ||||
DebugLoc DL; | ||||
ImmutableCallSite *CS; | ||||
SmallVector<ISD::OutputArg, 32> Outs; | ||||
SmallVector<SDValue, 32> OutVals; | ||||
SmallVector<ISD::InputArg, 32> Ins; | ||||
/// CallLoweringInfo - 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, DebugLoc dl, | ||||
ImmutableCallSite &cs) | ||||
: Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attribute::SEx | ||||
t)), | ||||
RetZExt(cs.paramHasAttr(0, Attribute::ZExt)), IsVarArg(FTy->isVarArg( | ||||
)), | ||||
IsInReg(cs.paramHasAttr(0, Attribute::InReg)), | ||||
DoesNotReturn(cs.doesNotReturn()), | ||||
IsReturnValueUsed(!cs.getInstruction()->use_empty()), | ||||
IsTailCall(isTailCall), NumFixedArgs(FTy->getNumParams()), | ||||
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. | ||||
CallLoweringInfo(SDValue chain, Type *retTy, bool retSExt, bool retZExt | ||||
, | ||||
bool isVarArg, bool isInReg, unsigned numFixedArgs, | ||||
CallingConv::ID callConv, bool isTailCall, | ||||
bool doesNotReturn, bool isReturnValueUsed, SDValue ca | ||||
llee, | ||||
ArgListTy &args, SelectionDAG &dag, DebugLoc dl) | ||||
: Chain(chain), RetTy(retTy), RetSExt(retSExt), RetZExt(retZExt), | ||||
IsVarArg(isVarArg), IsInReg(isInReg), DoesNotReturn(doesNotReturn), | ||||
IsReturnValueUsed(isReturnValueUsed), IsTailCall(isTailCall), | ||||
NumFixedArgs(numFixedArgs), CallConv(callConv), Callee(callee), | ||||
Args(args), DAG(dag), DL(dl), CS(NULL) {} | ||||
}; | ||||
/// LowerCallTo - This function lowers an abstract call to a function int | ||||
o 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 act | ||||
ual | ||||
/// 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. | ||||
virtual SDValue | ||||
LowerCall(CallLoweringInfo &/*CLI*/, | ||||
SmallVectorImpl<SDValue> &/*InVals*/) const { | ||||
llvm_unreachable("Not Implemented"); | ||||
} | ||||
/// HandleByVal - 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. | ||||
/// | ||||
virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/, | ||||
MachineFunction &/*MF*/, bool /*isVarArg*/, | ||||
const SmallVectorImpl<ISD::OutputArg> &/*Outs*/, | ||||
LLVMContext &/*Context*/) const | ||||
{ | ||||
// Return true by default to get preexisting behavior. | ||||
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. | ||||
/// | ||||
virtual SDValue | ||||
LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, | ||||
bool /*isVarArg*/, | ||||
const SmallVectorImpl<ISD::OutputArg> &/*Outs*/, | ||||
const SmallVectorImpl<SDValue> &/*OutVals*/, | ||||
DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const { | ||||
llvm_unreachable("Not Implemented"); | ||||
} | ||||
/// isUsedByReturnOnly - Return true if result of the specified node is u | ||||
sed | ||||
/// 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 t | ||||
he | ||||
/// call instruction as a tail call. This is used by optimization passes | ||||
to | ||||
/// determine if it's profitable to duplicate return instructions to enab | ||||
le | ||||
/// tailcall optimization. | ||||
virtual bool mayBeEmittedAsTailCall(CallInst *) const { | ||||
return false; | ||||
} | ||||
/// getTypeForExtArgOrReturn - Return the type that should be used to zer | ||||
o or | ||||
/// sign extend a zeroext/signext integer argument or return value. | ||||
/// FIXME: Most C calling convention requires the return type to be promo | ||||
ted, | ||||
/// 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 t | ||||
his | ||||
/// 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 legalize | ||||
r | ||||
/// 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 nu | ||||
mber | ||||
/// 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. | ||||
/// The default implementation calls LowerOperation. | ||||
virtual void LowerOperationWrapper(SDNode *N, | ||||
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' lower | ||||
ing, | ||||
/// 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 'cust | ||||
om' | ||||
/// lowering for that result type. The target places new result values f | ||||
or | ||||
/// the node in Results (their number and types must exactly match those | ||||
of | ||||
/// the original return values of the node), or leaves Results empty, whi | ||||
ch | ||||
/// 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. | ||||
virtual void ReplaceNodeResults(SDNode * /*N*/, | ||||
SmallVectorImpl<SDValue> &/*Results*/, | ||||
SelectionDAG &/*DAG*/) const { | ||||
llvm_unreachable("ReplaceNodeResults not implemented for this target!") | ||||
; | ||||
} | ||||
/// getTargetNodeName() - This method returns the name of a target specif | ||||
ic | ||||
/// DAG node. | ||||
virtual const char *getTargetNodeName(unsigned Opcode) const; | ||||
/// createFastISel - This method returns a target specific FastISel objec | ||||
t, | ||||
/// or null if the target does not support "fast" ISel. | ||||
virtual FastISel *createFastISel(FunctionLoweringInfo &, | ||||
const TargetLibraryInfo *) const { | ||||
return 0; | ||||
} | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
// 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. | ||||
virtual bool ExpandInlineAsm(CallInst *) const { | ||||
return false; | ||||
} | ||||
enum ConstraintType { | ||||
C_Register, // Constraint represents specific register(s). | ||||
C_RegisterClass, // Constraint represents any of register(s) in c | ||||
lass. | ||||
C_Memory, // Memory constraint. | ||||
C_Other, // Something else. | ||||
C_Unknown // Unsupported constraint. | ||||
}; | ||||
enum ConstraintWeight { | ||||
// Generic weights. | ||||
CW_Invalid = -1, // No match. | ||||
CW_Okay = 0, // Acceptable. | ||||
CW_Good = 1, // Good weight. | ||||
CW_Better = 2, // Better weight. | ||||
CW_Best = 3, // Best weight. | ||||
// Well-known weights. | ||||
CW_SpecificReg = CW_Okay, // Specific register operands. | ||||
CW_Register = CW_Good, // Register operands. | ||||
CW_Memory = CW_Better, // Memory operands. | ||||
CW_Constant = CW_Best, // Constant operand. | ||||
CW_Default = CW_Okay // Default or don't know type. | ||||
}; | ||||
/// AsmOperandInfo - This contains information for each constraint that w | ||||
e 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 tha | ||||
t | ||||
/// most closely matches the operand. | ||||
std::string ConstraintCode; | ||||
/// ConstraintType - Information about the constraint code, e.g. Regist | ||||
er, | ||||
/// 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. | ||||
Value *CallOperandVal; | ||||
/// ConstraintVT - The ValueType for the operand value. | ||||
MVT ConstraintVT; | ||||
/// isMatchingInputConstraint - 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 m | ||||
ethod | ||||
/// returns the output operand it matches. | ||||
unsigned getMatchedOperand() const; | ||||
/// Copy constructor for copying from an AsmOperandInfo. | ||||
AsmOperandInfo(const AsmOperandInfo &info) | ||||
: InlineAsm::ConstraintInfo(info), | ||||
ConstraintCode(info.ConstraintCode), | ||||
ConstraintType(info.ConstraintType), | ||||
CallOperandVal(info.CallOperandVal), | ||||
ConstraintVT(info.ConstraintVT) { | ||||
} | ||||
/// Copy constructor for copying from a ConstraintInfo. | ||||
AsmOperandInfo(const InlineAsm::ConstraintInfo &info) | ||||
: InlineAsm::ConstraintInfo(info), | ||||
ConstraintType(TargetLowering::C_Unknown), | ||||
CallOperandVal(0), ConstraintVT(MVT::Other) { | ||||
} | ||||
}; | ||||
typedef std::vector<AsmOperandInfo> AsmOperandInfoVector; | ||||
/// ParseConstraints - Split up the constraint string from the inline | ||||
/// assembly value into the specific constraints and their prefixes, | ||||
/// and also tie in the associated operand values. | ||||
/// If this returns an empty vector, and if the constraint string itself | ||||
/// isn't empty, there was an error parsing. | ||||
virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const | ||||
; | ||||
/// Examine constraint type and operand type and determine a weight value | ||||
. | ||||
/// The operand object must already have been set up with the operand typ | ||||
e. | ||||
virtual ConstraintWeight getMultipleConstraintMatchWeight( | ||||
AsmOperandInfo &info, int maIndex) const; | ||||
/// Examine constraint string and operand type and determine a weight val | ||||
ue. | ||||
/// The operand object must already have been set up with the operand typ | ||||
e. | ||||
virtual ConstraintWeight getSingleConstraintMatchWeight( | ||||
AsmOperandInfo &info, const char *constraint) const; | ||||
/// ComputeConstraintToUse - Determines the constraint code and constrain | ||||
t | ||||
/// type to use for the specific AsmOperandInfo, setting | ||||
/// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual opera | ||||
nd | ||||
/// 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. | ||||
virtual ConstraintType getConstraintType(const std::string &Constraint) c | ||||
onst; | ||||
/// getRegForInlineAsmConstraint - 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 dire | ||||
ctly | ||||
/// to an LLVM register class, return a register of 0 and the register cl | ||||
ass | ||||
/// 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; | ||||
/// LowerXConstraint - try to replace an X constraint, which matches anyt | ||||
hing, | ||||
/// 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 O | ||||
ps | ||||
/// vector. If it is invalid, don't add anything to Ops. | ||||
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constr | ||||
aint, | ||||
std::vector<SDValue> &Ops, | ||||
SelectionDAG &DAG) const; | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
// Div utility functions | ||||
// | ||||
SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl, | ||||
SelectionDAG &DAG) const; | ||||
SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, | ||||
std::vector<SDNode*> *Created) const; | ||||
SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, | ||||
std::vector<SDNode*> *Created) const; | ||||
//===-------------------------------------------------------------------- | ||||
===// | ||||
// Instruction Emitting Hooks | ||||
// | ||||
// EmitInstrWithCustomInserter - This method should be implemented by tar | ||||
gets | ||||
// that mark instructions with the 'usesCustomInserter' flag. These | ||||
// instructions are special in various ways, which require special suppor | ||||
t to | ||||
// insert. The specified MachineInstr is created but not inserted into a | ||||
ny | ||||
// basic blocks, and this method is called to expand it into a sequence o | ||||
f | ||||
// instructions, potentially also creating new basic blocks and control f | ||||
low. | ||||
virtual MachineBasicBlock * | ||||
EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) c | ||||
onst; | ||||
/// 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 h | ||||
ooks. | ||||
/// 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, | /// GetReturnInfo - Given an LLVM IR type and return type attributes, | |||
/// compute the return value EVTs and flags, and optionally also | /// compute the return value EVTs and flags, and optionally also | |||
/// the offsets, if the return value is being lowered to memory. | /// the offsets, if the return value is being lowered to memory. | |||
void GetReturnInfo(Type* ReturnType, Attributes attr, | void GetReturnInfo(Type* ReturnType, AttributeSet attr, | |||
SmallVectorImpl<ISD::OutputArg> &Outs, | SmallVectorImpl<ISD::OutputArg> &Outs, | |||
const TargetLowering &TLI); | const TargetLowering &TLI); | |||
} // end llvm namespace | } // end llvm namespace | |||
#endif | #endif | |||
End of changes. 130 change blocks. | ||||
1085 lines changed or deleted | 1180 lines changed or added | |||
TargetLoweringObjectFile.h | TargetLoweringObjectFile.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements classes used to handle lowerings specific to common | // This file implements classes used to handle lowerings specific to common | |||
// object file formats. | // object file formats. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H | #ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H | |||
#define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H | #define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H | |||
#include "llvm/Module.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/IR/Module.h" | ||||
#include "llvm/MC/MCObjectFileInfo.h" | #include "llvm/MC/MCObjectFileInfo.h" | |||
#include "llvm/MC/SectionKind.h" | #include "llvm/MC/SectionKind.h" | |||
#include "llvm/ADT/ArrayRef.h" | ||||
namespace llvm { | namespace llvm { | |||
class MachineModuleInfo; | class MachineModuleInfo; | |||
class Mangler; | class Mangler; | |||
class MCContext; | class MCContext; | |||
class MCExpr; | class MCExpr; | |||
class MCSection; | class MCSection; | |||
class MCSymbol; | class MCSymbol; | |||
class MCSymbolRefExpr; | ||||
class MCStreamer; | class MCStreamer; | |||
class GlobalValue; | class GlobalValue; | |||
class TargetMachine; | class TargetMachine; | |||
class TargetLoweringObjectFile : public MCObjectFileInfo { | class TargetLoweringObjectFile : public MCObjectFileInfo { | |||
MCContext *Ctx; | MCContext *Ctx; | |||
TargetLoweringObjectFile( | TargetLoweringObjectFile( | |||
const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION; | const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION; | |||
void operator=(const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION; | void operator=(const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION; | |||
skipping to change at line 111 | skipping to change at line 112 | |||
Mangler *Mang, const TargetMachine &TM) const = 0; | Mangler *Mang, const TargetMachine &TM) const = 0; | |||
/// getSpecialCasedSectionGlobals - Allow the target to completely overri de | /// getSpecialCasedSectionGlobals - Allow the target to completely overri de | |||
/// section assignment of a global. | /// section assignment of a global. | |||
virtual const MCSection * | virtual const MCSection * | |||
getSpecialCasedSectionGlobals(const GlobalValue *GV, Mangler *Mang, | getSpecialCasedSectionGlobals(const GlobalValue *GV, Mangler *Mang, | |||
SectionKind Kind) const { | SectionKind Kind) const { | |||
return 0; | return 0; | |||
} | } | |||
/// getExprForDwarfGlobalReference - Return an MCExpr to use for a refere nce | /// getTTypeGlobalReference - Return an MCExpr to use for a reference | |||
/// to the specified global variable from exception handling information. | /// to the specified global variable from exception handling information. | |||
/// | /// | |||
virtual const MCExpr * | virtual const MCExpr * | |||
getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, | getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, | |||
MachineModuleInfo *MMI, unsigned Encoding, | MachineModuleInfo *MMI, unsigned Encoding, | |||
MCStreamer &Streamer) const; | MCStreamer &Streamer) const; | |||
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personal ity. | // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personal ity. | |||
virtual MCSymbol * | virtual MCSymbol * | |||
getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, | getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, | |||
MachineModuleInfo *MMI) const; | MachineModuleInfo *MMI) const; | |||
/// | /// | |||
const MCExpr * | const MCExpr * | |||
getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding, | getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding, | |||
MCStreamer &Streamer) const; | MCStreamer &Streamer) const; | |||
virtual const MCSection * | virtual const MCSection * | |||
getStaticCtorSection(unsigned Priority = 65535) const { | getStaticCtorSection(unsigned Priority = 65535) const { | |||
(void)Priority; | (void)Priority; | |||
return StaticCtorSection; | return StaticCtorSection; | |||
} | } | |||
virtual const MCSection * | virtual const MCSection * | |||
getStaticDtorSection(unsigned Priority = 65535) const { | getStaticDtorSection(unsigned Priority = 65535) const { | |||
(void)Priority; | (void)Priority; | |||
return StaticDtorSection; | return StaticDtorSection; | |||
End of changes. 6 change blocks. | ||||
8 lines changed or deleted | 9 lines changed or added | |||
TargetLoweringObjectFileImpl.h | TargetLoweringObjectFileImpl.h | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements classes used to handle lowerings specific to common | // This file implements classes used to handle lowerings specific to common | |||
// object file formats. | // object file formats. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H | #ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H | |||
#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H | #define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H | |||
#include "llvm/ADT/StringRef.h" | ||||
#include "llvm/MC/SectionKind.h" | #include "llvm/MC/SectionKind.h" | |||
#include "llvm/Target/TargetLoweringObjectFile.h" | #include "llvm/Target/TargetLoweringObjectFile.h" | |||
#include "llvm/ADT/StringRef.h" | ||||
namespace llvm { | namespace llvm { | |||
class MachineModuleInfo; | class MachineModuleInfo; | |||
class Mangler; | class Mangler; | |||
class MCAsmInfo; | class MCAsmInfo; | |||
class MCExpr; | class MCExpr; | |||
class MCSection; | class MCSection; | |||
class MCSectionMachO; | class MCSectionMachO; | |||
class MCSymbol; | class MCSymbol; | |||
class MCContext; | class MCContext; | |||
skipping to change at line 56 | skipping to change at line 56 | |||
virtual const MCSection *getSectionForConstant(SectionKind Kind) const; | virtual const MCSection *getSectionForConstant(SectionKind Kind) const; | |||
virtual const MCSection * | virtual const MCSection * | |||
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, | getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, | |||
Mangler *Mang, const TargetMachine &TM) const; | Mangler *Mang, const TargetMachine &TM) const; | |||
virtual const MCSection * | virtual const MCSection * | |||
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, | SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, | |||
Mangler *Mang, const TargetMachine &TM) const; | Mangler *Mang, const TargetMachine &TM) const; | |||
/// getExprForDwarfGlobalReference - Return an MCExpr to use for a refere | /// getTTypeGlobalReference - Return an MCExpr to use for a reference to | |||
nce | the | |||
/// to the specified global variable from exception handling information. | /// specified type info global variable from exception handling informati | |||
/// | on. | |||
virtual const MCExpr * | virtual const MCExpr * | |||
getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, | getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, | |||
MachineModuleInfo *MMI, unsigned Encoding, | MachineModuleInfo *MMI, unsigned Encoding, | |||
MCStreamer &Streamer) const; | MCStreamer &Streamer) const; | |||
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personal ity. | // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personal ity. | |||
virtual MCSymbol * | virtual MCSymbol * | |||
getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, | getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, | |||
MachineModuleInfo *MMI) const; | MachineModuleInfo *MMI) const; | |||
void InitializeELF(bool UseInitArray_); | void InitializeELF(bool UseInitArray_); | |||
virtual const MCSection * | virtual const MCSection * | |||
getStaticCtorSection(unsigned Priority = 65535) const; | getStaticCtorSection(unsigned Priority = 65535) const; | |||
virtual const MCSection * | virtual const MCSection * | |||
skipping to change at line 102 | skipping to change at line 101 | |||
Mangler *Mang, const TargetMachine &TM) const; | Mangler *Mang, const TargetMachine &TM) const; | |||
virtual const MCSection *getSectionForConstant(SectionKind Kind) const; | virtual const MCSection *getSectionForConstant(SectionKind Kind) const; | |||
/// shouldEmitUsedDirectiveFor - This hook allows targets to selectively | /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively | |||
/// decide not to emit the UsedDirective for some symbols in llvm.used. | /// decide not to emit the UsedDirective for some symbols in llvm.used. | |||
/// FIXME: REMOVE this (rdar://7071300) | /// FIXME: REMOVE this (rdar://7071300) | |||
virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, | virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, | |||
Mangler *) const; | Mangler *) const; | |||
/// getExprForDwarfGlobalReference - The mach-o version of this method | /// getTTypeGlobalReference - The mach-o version of this method | |||
/// defaults to returning a stub reference. | /// defaults to returning a stub reference. | |||
virtual const MCExpr * | virtual const MCExpr * | |||
getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, | getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, | |||
MachineModuleInfo *MMI, unsigned Encoding, | MachineModuleInfo *MMI, unsigned Encoding, | |||
MCStreamer &Streamer) const; | MCStreamer &Streamer) const; | |||
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personal ity. | // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personal ity. | |||
virtual MCSymbol * | virtual MCSymbol * | |||
getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, | getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, | |||
MachineModuleInfo *MMI) const; | MachineModuleInfo *MMI) const; | |||
}; | }; | |||
class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { | class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { | |||
public: | public: | |||
virtual ~TargetLoweringObjectFileCOFF() {} | virtual ~TargetLoweringObjectFileCOFF() {} | |||
virtual const MCSection * | virtual const MCSection * | |||
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, | getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, | |||
Mangler *Mang, const TargetMachine &TM) const; | Mangler *Mang, const TargetMachine &TM) const; | |||
virtual const MCSection * | virtual const MCSection * | |||
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, | SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, | |||
Mangler *Mang, const TargetMachine &TM) const; | Mangler *Mang, const TargetMachine &TM) const; | |||
/// emitModuleFlags - Emit Obj-C garbage collection and linker options. | ||||
Only | ||||
/// linker option emission is implemented for COFF. | ||||
virtual void emitModuleFlags(MCStreamer &Streamer, | ||||
ArrayRef<Module::ModuleFlagEntry> ModuleFlag | ||||
s, | ||||
Mangler *Mang, const TargetMachine &TM) cons | ||||
t; | ||||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 7 change blocks. | ||||
12 lines changed or deleted | 21 lines changed or added | |||
TargetMachine.h | TargetMachine.h | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
|* Many exotic languages can interoperate with C code but have a harder tim e *| | |* Many exotic languages can interoperate with C code but have a harder tim e *| | |||
|* with C++ due to name mangling. So in addition to C, this interface enabl es *| | |* with C++ due to name mangling. So in addition to C, this interface enabl es *| | |||
|* tools written in such languages. *| | |* tools written in such languages. *| | |||
|* *| | |* *| | |||
\*===---------------------------------------------------------------------- ===*/ | \*===---------------------------------------------------------------------- ===*/ | |||
#ifndef LLVM_C_TARGETMACHINE_H | #ifndef LLVM_C_TARGETMACHINE_H | |||
#define LLVM_C_TARGETMACHINE_H | #define LLVM_C_TARGETMACHINE_H | |||
#include "llvm-c/Core.h" | #include "llvm-c/Core.h" | |||
#include "llvm-c/Target.h" | ||||
#ifdef __cplusplus | #ifdef __cplusplus | |||
extern "C" { | extern "C" { | |||
#endif | #endif | |||
typedef struct LLVMTargetMachine *LLVMTargetMachineRef; | typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef; | |||
typedef struct LLVMTarget *LLVMTargetRef; | typedef struct LLVMTarget *LLVMTargetRef; | |||
typedef enum { | typedef enum { | |||
LLVMCodeGenLevelNone, | LLVMCodeGenLevelNone, | |||
LLVMCodeGenLevelLess, | LLVMCodeGenLevelLess, | |||
LLVMCodeGenLevelDefault, | LLVMCodeGenLevelDefault, | |||
LLVMCodeGenLevelAggressive | LLVMCodeGenLevelAggressive | |||
} LLVMCodeGenOptLevel; | } LLVMCodeGenOptLevel; | |||
typedef enum { | typedef enum { | |||
skipping to change at line 116 | skipping to change at line 117 | |||
/** Returns the llvm::DataLayout used for this llvm:TargetMachine. */ | /** Returns the llvm::DataLayout used for this llvm:TargetMachine. */ | |||
LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T); | LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T); | |||
/** Emits an asm or object file for the given module to the filename. This | /** Emits an asm or object file for the given module to the filename. This | |||
wraps several c++ only classes (among them a file stream). Returns any | wraps several c++ only classes (among them a file stream). Returns any | |||
error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */ | error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */ | |||
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, | LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, | |||
char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage); | char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage); | |||
/** Compile the LLVM IR stored in \p M and store the result in \p OutMemBuf | ||||
. */ | ||||
LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMMo | ||||
duleRef M, | ||||
LLVMCodeGenFileType codegen, char** ErrorMessage, LLVMMemoryBufferRef *Ou | ||||
tMemBuf); | ||||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} | } | |||
namespace llvm { | ||||
class TargetMachine; | ||||
class Target; | ||||
inline TargetMachine *unwrap(LLVMTargetMachineRef P) { | ||||
return reinterpret_cast<TargetMachine*>(P); | ||||
} | ||||
inline Target *unwrap(LLVMTargetRef P) { | ||||
return reinterpret_cast<Target*>(P); | ||||
} | ||||
inline LLVMTargetMachineRef wrap(const TargetMachine *P) { | ||||
return reinterpret_cast<LLVMTargetMachineRef>( | ||||
const_cast<TargetMachine*>(P)); | ||||
} | ||||
inline LLVMTargetRef wrap(const Target * P) { | ||||
return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P)); | ||||
} | ||||
} | ||||
#endif | #endif | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
20 lines changed or deleted | 8 lines changed or added | |||
TargetOptions.h | TargetOptions.h | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
#include <string> | #include <string> | |||
namespace llvm { | namespace llvm { | |||
class MachineFunction; | class MachineFunction; | |||
class StringRef; | class StringRef; | |||
// Possible float ABI settings. Used with FloatABIType in TargetOptions.h . | // Possible float ABI settings. Used with FloatABIType in TargetOptions.h . | |||
namespace FloatABI { | namespace FloatABI { | |||
enum ABIType { | enum ABIType { | |||
Default, // Target-specific (either soft or hard depending on triple, etc). | Default, // Target-specific (either soft or hard depending on triple, etc). | |||
Soft, // Soft float. | Soft, // Soft float. | |||
Hard // Hard float. | Hard // Hard float. | |||
}; | }; | |||
} | } | |||
namespace FPOpFusion { | namespace FPOpFusion { | |||
enum FPOpFusionMode { | enum FPOpFusionMode { | |||
Fast, // Enable fusion of FP ops wherever it's profitable. | Fast, // Enable fusion of FP ops wherever it's profitable. | |||
Standard, // Only allow fusion of 'blessed' ops (currently just fmula dd). | Standard, // Only allow fusion of 'blessed' ops (currently just fmula dd). | |||
Strict // Never fuse FP-ops. | Strict // Never fuse FP-ops. | |||
skipping to change at line 51 | skipping to change at line 51 | |||
class TargetOptions { | class TargetOptions { | |||
public: | public: | |||
TargetOptions() | TargetOptions() | |||
: PrintMachineCode(false), NoFramePointerElim(false), | : PrintMachineCode(false), NoFramePointerElim(false), | |||
NoFramePointerElimNonLeaf(false), LessPreciseFPMADOption(false), | NoFramePointerElimNonLeaf(false), LessPreciseFPMADOption(false), | |||
UnsafeFPMath(false), NoInfsFPMath(false), | UnsafeFPMath(false), NoInfsFPMath(false), | |||
NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false ), | NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false ), | |||
UseSoftFloat(false), NoZerosInBSS(false), JITExceptionHandling(fa lse), | UseSoftFloat(false), NoZerosInBSS(false), JITExceptionHandling(fa lse), | |||
JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false), | JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false), | |||
GuaranteedTailCallOpt(false), DisableTailCalls(false), | GuaranteedTailCallOpt(false), DisableTailCalls(false), | |||
StackAlignmentOverride(0), RealignStack(true), EnableFastISel(fal | StackAlignmentOverride(0), RealignStack(true), SSPBufferSize(0), | |||
se), | EnableFastISel(false), PositionIndependentExecutable(false), | |||
PositionIndependentExecutable(false), EnableSegmentedStacks(false | EnableSegmentedStacks(false), UseInitArray(false), TrapFuncName(" | |||
), | "), | |||
UseInitArray(false), TrapFuncName(""), FloatABIType(FloatABI::Def | FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Stan | |||
ault), | dard) | |||
AllowFPOpFusion(FPOpFusion::Standard) | ||||
{} | {} | |||
/// PrintMachineCode - This flag is enabled when the -print-machineinst rs | /// PrintMachineCode - This flag is enabled when the -print-machineinst rs | |||
/// option is specified on the command line, and should enable debuggin g | /// option is specified on the command line, and should enable debuggin g | |||
/// output from the code generator. | /// output from the code generator. | |||
unsigned PrintMachineCode : 1; | unsigned PrintMachineCode : 1; | |||
/// NoFramePointerElim - This flag is enabled when the -disable-fp-elim is | /// NoFramePointerElim - This flag is enabled when the -disable-fp-elim is | |||
/// specified on the command line. If the target supports the frame po inter | /// specified on the command line. If the target supports the frame po inter | |||
/// elimination optimization, this option should disable it. | /// elimination optimization, this option should disable it. | |||
skipping to change at line 205 | skipping to change at line 205 | |||
/// results in higher precision than IEEE allows (E.g. FMAs). | /// results in higher precision than IEEE allows (E.g. FMAs). | |||
/// | /// | |||
/// Fast mode - allows formation of fused FP ops whenever they're | /// Fast mode - allows formation of fused FP ops whenever they're | |||
/// profitable. | /// profitable. | |||
/// Standard mode - allow fusion only for 'blessed' FP ops. At present the | /// Standard mode - allow fusion only for 'blessed' FP ops. At present the | |||
/// only blessed op is the fmuladd intrinsic. In the future more blesse d ops | /// only blessed op is the fmuladd intrinsic. In the future more blesse d ops | |||
/// may be added. | /// may be added. | |||
/// Strict mode - allow fusion only if/when it can be proven that the e xcess | /// Strict mode - allow fusion only if/when it can be proven that the e xcess | |||
/// precision won't effect the result. | /// precision won't effect the result. | |||
/// | /// | |||
/// Note: This option only controls formation of fused ops by the optim | /// Note: This option only controls formation of fused ops by the | |||
izers. | /// optimizers. Fused operations that are explicitly specified (e.g. F | |||
/// Fused operations that are explicitly specified (e.g. FMA via the | MA | |||
/// llvm.fma.* intrinsic) will always be honored, regardless of the val | /// via the llvm.fma.* intrinsic) will always be honored, regardless of | |||
ue of | /// the value of this option. | |||
/// this option. | ||||
FPOpFusion::FPOpFusionMode AllowFPOpFusion; | FPOpFusion::FPOpFusionMode AllowFPOpFusion; | |||
bool operator==(const TargetOptions &); | ||||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
14 lines changed or deleted | 13 lines changed or added | |||
TargetRegisterInfo.h | TargetRegisterInfo.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file describes an abstract interface used to get information about a | // This file describes an abstract interface used to get information about a | |||
// target machines register file. This information is used for a variety o f | // target machines register file. This information is used for a variety o f | |||
// purposed, especially register allocation. | // purposed, especially register allocation. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TARGET_TARGETREGISTERINFO_H | #ifndef LLVM_TARGET_TARGETREGISTERINFO_H | |||
#define LLVM_TARGET_TARGETREGISTERINFO_H | #define LLVM_TARGET_TARGETREGISTERINFO_H | |||
#include "llvm/MC/MCRegisterInfo.h" | #include "llvm/ADT/ArrayRef.h" | |||
#include "llvm/CodeGen/MachineBasicBlock.h" | #include "llvm/CodeGen/MachineBasicBlock.h" | |||
#include "llvm/CodeGen/ValueTypes.h" | #include "llvm/CodeGen/ValueTypes.h" | |||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/IR/CallingConv.h" | |||
#include "llvm/CallingConv.h" | #include "llvm/MC/MCRegisterInfo.h" | |||
#include <cassert> | #include <cassert> | |||
#include <functional> | #include <functional> | |||
namespace llvm { | namespace llvm { | |||
class BitVector; | class BitVector; | |||
class MachineFunction; | class MachineFunction; | |||
class RegScavenger; | class RegScavenger; | |||
template<class T> class SmallVectorImpl; | template<class T> class SmallVectorImpl; | |||
class VirtRegMap; | ||||
class raw_ostream; | class raw_ostream; | |||
class TargetRegisterClass { | class TargetRegisterClass { | |||
public: | public: | |||
typedef const uint16_t* iterator; | typedef const MCPhysReg* iterator; | |||
typedef const uint16_t* const_iterator; | typedef const MCPhysReg* const_iterator; | |||
typedef const MVT::SimpleValueType* vt_iterator; | typedef const MVT::SimpleValueType* vt_iterator; | |||
typedef const TargetRegisterClass* const * sc_iterator; | typedef const TargetRegisterClass* const * sc_iterator; | |||
// Instance variables filled by tablegen, do not use! | // Instance variables filled by tablegen, do not use! | |||
const MCRegisterClass *MC; | const MCRegisterClass *MC; | |||
const vt_iterator VTs; | const vt_iterator VTs; | |||
const uint32_t *SubClassMask; | const uint32_t *SubClassMask; | |||
const uint16_t *SuperRegIndices; | const uint16_t *SuperRegIndices; | |||
const sc_iterator SuperClasses; | const sc_iterator SuperClasses; | |||
ArrayRef<uint16_t> (*OrderFunc)(const MachineFunction&); | ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&); | |||
/// getID() - Return the register class ID number. | /// getID() - Return the register class ID number. | |||
/// | /// | |||
unsigned getID() const { return MC->getID(); } | unsigned getID() const { return MC->getID(); } | |||
/// getName() - Return the register class name for debugging. | /// getName() - Return the register class name for debugging. | |||
/// | /// | |||
const char *getName() const { return MC->getName(); } | const char *getName() const { return MC->getName(); } | |||
/// begin/end - Return all of the registers in this class. | /// begin/end - Return all of the registers in this class. | |||
skipping to change at line 193 | skipping to change at line 194 | |||
/// callee-saved registers only after all the volatiles are used. The | /// callee-saved registers only after all the volatiles are used. The | |||
/// RegisterClassInfo class provides filtered allocation orders with | /// RegisterClassInfo class provides filtered allocation orders with | |||
/// callee-saved registers moved to the end. | /// callee-saved registers moved to the end. | |||
/// | /// | |||
/// The MachineFunction argument can be used to tune the allocatable | /// The MachineFunction argument can be used to tune the allocatable | |||
/// registers based on the characteristics of the function, subtarget, or | /// registers based on the characteristics of the function, subtarget, or | |||
/// other criteria. | /// other criteria. | |||
/// | /// | |||
/// By default, this method returns all registers in the class. | /// By default, this method returns all registers in the class. | |||
/// | /// | |||
ArrayRef<uint16_t> getRawAllocationOrder(const MachineFunction &MF) const { | ArrayRef<MCPhysReg> getRawAllocationOrder(const MachineFunction &MF) cons t { | |||
return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs()); | return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs()); | |||
} | } | |||
}; | }; | |||
/// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, abou t | /// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, abou t | |||
/// registers. These are used by codegen, not by MC. | /// registers. These are used by codegen, not by MC. | |||
struct TargetRegisterInfoDesc { | struct TargetRegisterInfoDesc { | |||
unsigned CostPerUse; // Extra cost of instructions using registe r. | unsigned CostPerUse; // Extra cost of instructions using registe r. | |||
bool inAllocatableClass; // Register belongs to an allocatable regcl ass. | bool inAllocatableClass; // Register belongs to an allocatable regcl ass. | |||
}; | }; | |||
skipping to change at line 390 | skipping to change at line 391 | |||
} | } | |||
/// hasRegUnit - Returns true if Reg contains RegUnit. | /// hasRegUnit - Returns true if Reg contains RegUnit. | |||
bool hasRegUnit(unsigned Reg, unsigned RegUnit) const { | bool hasRegUnit(unsigned Reg, unsigned RegUnit) const { | |||
for (MCRegUnitIterator Units(Reg, this); Units.isValid(); ++Units) | for (MCRegUnitIterator Units(Reg, this); Units.isValid(); ++Units) | |||
if (*Units == RegUnit) | if (*Units == RegUnit) | |||
return true; | return true; | |||
return false; | return false; | |||
} | } | |||
/// isSubRegister - Returns true if regB is a sub-register of regA. | ||||
/// | ||||
bool isSubRegister(unsigned regA, unsigned regB) const { | ||||
return isSuperRegister(regB, regA); | ||||
} | ||||
/// isSuperRegister - Returns true if regB is a super-register of regA. | ||||
/// | ||||
bool isSuperRegister(unsigned RegA, unsigned RegB) const { | ||||
for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I) | ||||
if (*I == RegB) | ||||
return true; | ||||
return false; | ||||
} | ||||
/// getCalleeSavedRegs - Return a null-terminated list of all of the | /// getCalleeSavedRegs - Return a null-terminated list of all of the | |||
/// callee saved registers on this target. The register should be in the | /// callee saved registers on this target. The register should be in the | |||
/// order of desired callee-save stack frame offset. The first register i s | /// order of desired callee-save stack frame offset. The first register i s | |||
/// closest to the incoming stack pointer if stack grows down, and vice v ersa. | /// closest to the incoming stack pointer if stack grows down, and vice v ersa. | |||
/// | /// | |||
virtual const uint16_t* getCalleeSavedRegs(const MachineFunction *MF = 0) | virtual const MCPhysReg* getCalleeSavedRegs(const MachineFunction *MF = 0 ) | |||
const = 0; | const = 0; | |||
/// getCallPreservedMask - Return a mask of call-preserved registers for the | /// getCallPreservedMask - Return a mask of call-preserved registers for the | |||
/// given calling convention on the current sub-target. The mask should | /// given calling convention on the current sub-target. The mask should | |||
/// include all call-preserved aliases. This is used by the register | /// include all call-preserved aliases. This is used by the register | |||
/// allocator to determine which registers can be live across a call. | /// allocator to determine which registers can be live across a call. | |||
/// | /// | |||
/// The mask is an array containing (TRI::getNumRegs()+31)/32 entries. | /// The mask is an array containing (TRI::getNumRegs()+31)/32 entries. | |||
/// A set bit indicates that all bits of the corresponding register are | /// A set bit indicates that all bits of the corresponding register are | |||
/// preserved across the function call. The bit mask is expected to be | /// preserved across the function call. The bit mask is expected to be | |||
skipping to change at line 597 | skipping to change at line 583 | |||
/// the specific register class. The scheduler is in high register pressu re | /// the specific register class. The scheduler is in high register pressu re | |||
/// mode (for the specific register class) if it goes over the limit. | /// mode (for the specific register class) if it goes over the limit. | |||
/// | /// | |||
/// Note: this is the old register pressure model that relies on a manual ly | /// Note: this is the old register pressure model that relies on a manual ly | |||
/// specified representative register class per value type. | /// specified representative register class per value type. | |||
virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC, | virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC, | |||
MachineFunction &MF) const { | MachineFunction &MF) const { | |||
return 0; | return 0; | |||
} | } | |||
// Get the weight in units of pressure for this register class. | /// Get the weight in units of pressure for this register class. | |||
virtual const RegClassWeight &getRegClassWeight( | virtual const RegClassWeight &getRegClassWeight( | |||
const TargetRegisterClass *RC) const = 0; | const TargetRegisterClass *RC) const = 0; | |||
/// Get the weight in units of pressure for this register unit. | ||||
virtual unsigned getRegUnitWeight(unsigned RegUnit) const = 0; | ||||
/// Get the number of dimensions of register pressure. | /// Get the number of dimensions of register pressure. | |||
virtual unsigned getNumRegPressureSets() const = 0; | virtual unsigned getNumRegPressureSets() const = 0; | |||
/// Get the name of this register unit pressure set. | /// Get the name of this register unit pressure set. | |||
virtual const char *getRegPressureSetName(unsigned Idx) const = 0; | virtual const char *getRegPressureSetName(unsigned Idx) const = 0; | |||
/// Get the register unit pressure limit for this dimension. | /// Get the register unit pressure limit for this dimension. | |||
/// This limit must be adjusted dynamically for reserved registers. | /// This limit must be adjusted dynamically for reserved registers. | |||
virtual unsigned getRegPressureSetLimit(unsigned Idx) const = 0; | virtual unsigned getRegPressureSetLimit(unsigned Idx) const = 0; | |||
/// Get the dimensions of register pressure impacted by this register cla ss. | /// Get the dimensions of register pressure impacted by this register cla ss. | |||
/// Returns a -1 terminated array of pressure set IDs. | /// Returns a -1 terminated array of pressure set IDs. | |||
virtual const int *getRegClassPressureSets( | virtual const int *getRegClassPressureSets( | |||
const TargetRegisterClass *RC) const = 0; | const TargetRegisterClass *RC) const = 0; | |||
/// getRawAllocationOrder - Returns the register allocation order for a | /// Get the dimensions of register pressure impacted by this register uni | |||
/// specified register class with a target-dependent hint. The returned l | t. | |||
ist | /// Returns a -1 terminated array of pressure set IDs. | |||
/// may contain reserved registers that cannot be allocated. | virtual const int *getRegUnitPressureSets(unsigned RegUnit) const = 0; | |||
/// | ||||
/// Register allocators need only call this function to resolve | /// Get a list of 'hint' registers that the register allocator should try | |||
/// target-dependent hints, but it should work without hinting as well. | /// first when allocating a physical register for the virtual register | |||
virtual ArrayRef<uint16_t> | /// VirtReg. These registers are effectively moved to the front of the | |||
getRawAllocationOrder(const TargetRegisterClass *RC, | /// allocation order. | |||
unsigned HintType, unsigned HintReg, | /// | |||
const MachineFunction &MF) const { | /// The Order argument is the allocation order for VirtReg's register cla | |||
return RC->getRawAllocationOrder(MF); | ss | |||
} | /// as returned from RegisterClassInfo::getOrder(). The hint registers mu | |||
st | ||||
/// ResolveRegAllocHint - Resolves the specified register allocation hint | /// come from Order, and they must not be reserved. | |||
/// to a physical register. Returns the physical register if it is succes | /// | |||
sful. | /// The default implementation of this function can resolve | |||
virtual unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg, | /// target-independent hints provided to MRI::setRegAllocationHint with | |||
const MachineFunction &MF) const { | /// HintType == 0. Targets that override this function should defer to th | |||
if (Type == 0 && Reg && isPhysicalRegister(Reg)) | e | |||
return Reg; | /// default implementation if they have no reason to change the allocatio | |||
return 0; | n | |||
} | /// order for VirtReg. There may be target-independent hints. | |||
virtual void getRegAllocationHints(unsigned VirtReg, | ||||
ArrayRef<MCPhysReg> Order, | ||||
SmallVectorImpl<MCPhysReg> &Hints, | ||||
const MachineFunction &MF, | ||||
const VirtRegMap *VRM = 0) const; | ||||
/// avoidWriteAfterWrite - Return true if the register allocator should a void | /// avoidWriteAfterWrite - Return true if the register allocator should a void | |||
/// writing a register from RC in two consecutive instructions. | /// writing a register from RC in two consecutive instructions. | |||
/// This can avoid pipeline stalls on certain architectures. | /// This can avoid pipeline stalls on certain architectures. | |||
/// It does cause increased register pressure, though. | /// It does cause increased register pressure, though. | |||
virtual bool avoidWriteAfterWrite(const TargetRegisterClass *RC) const { | virtual bool avoidWriteAfterWrite(const TargetRegisterClass *RC) const { | |||
return false; | return false; | |||
} | } | |||
/// UpdateRegAllocHint - A callback to allow target a chance to update | /// UpdateRegAllocHint - A callback to allow target a chance to update | |||
skipping to change at line 745 | skipping to change at line 736 | |||
llvm_unreachable("resolveFrameIndex does not exist on this target"); | llvm_unreachable("resolveFrameIndex does not exist on this target"); | |||
} | } | |||
/// isFrameOffsetLegal - Determine whether a given offset immediate is | /// isFrameOffsetLegal - Determine whether a given offset immediate is | |||
/// encodable to resolve a frame index. | /// encodable to resolve a frame index. | |||
virtual bool isFrameOffsetLegal(const MachineInstr *MI, | virtual bool isFrameOffsetLegal(const MachineInstr *MI, | |||
int64_t Offset) const { | int64_t Offset) const { | |||
llvm_unreachable("isFrameOffsetLegal does not exist on this target"); | llvm_unreachable("isFrameOffsetLegal does not exist on this target"); | |||
} | } | |||
/// eliminateCallFramePseudoInstr - This method is called during prolog/e | ||||
pilog | ||||
/// code insertion to eliminate call frame setup and destroy pseudo | ||||
/// instructions (but only if the Target is using them). It is responsib | ||||
le | ||||
/// for eliminating these instructions, replacing them with concrete | ||||
/// instructions. This method need only be implemented if using call fra | ||||
me | ||||
/// setup/destroy pseudo instructions. | ||||
/// | ||||
virtual void | ||||
eliminateCallFramePseudoInstr(MachineFunction &MF, | ||||
MachineBasicBlock &MBB, | ||||
MachineBasicBlock::iterator MI) const { | ||||
llvm_unreachable("Call Frame Pseudo Instructions do not exist on this " | ||||
"target!"); | ||||
} | ||||
/// saveScavengerRegister - Spill the register so it can be used by the | /// saveScavengerRegister - Spill the register so it can be used by the | |||
/// register scavenger. Return true if the register was spilled, false | /// register scavenger. Return true if the register was spilled, false | |||
/// otherwise. If this function does not spill the register, the scavenge r | /// otherwise. If this function does not spill the register, the scavenge r | |||
/// will instead spill it to the emergency spill slot. | /// will instead spill it to the emergency spill slot. | |||
/// | /// | |||
virtual bool saveScavengerRegister(MachineBasicBlock &MBB, | virtual bool saveScavengerRegister(MachineBasicBlock &MBB, | |||
MachineBasicBlock::iterator I, | MachineBasicBlock::iterator I, | |||
MachineBasicBlock::iterator &UseMI, | MachineBasicBlock::iterator &UseMI, | |||
const TargetRegisterClass *RC, | const TargetRegisterClass *RC, | |||
unsigned Reg) const { | unsigned Reg) const { | |||
return false; | return false; | |||
} | } | |||
/// eliminateFrameIndex - This method must be overriden to eliminate abst ract | /// eliminateFrameIndex - This method must be overriden to eliminate abst ract | |||
/// frame indices from instructions which may use them. The instruction | /// frame indices from instructions which may use them. The instruction | |||
/// referenced by the iterator contains an MO_FrameIndex operand which mu st be | /// referenced by the iterator contains an MO_FrameIndex operand which mu st be | |||
/// eliminated by this method. This method may modify or replace the | /// eliminated by this method. This method may modify or replace the | |||
/// specified instruction, as long as it keeps the iterator pointing at t he | /// specified instruction, as long as it keeps the iterator pointing at t he | |||
/// finished product. SPAdj is the SP adjustment due to call frame setup | /// finished product. SPAdj is the SP adjustment due to call frame setup | |||
/// instruction. | /// instruction. FIOperandNum is the FI operand number. | |||
virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, | virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, | |||
int SPAdj, RegScavenger *RS=NULL) const | int SPAdj, unsigned FIOperandNum, | |||
= 0; | RegScavenger *RS = NULL) const = 0; | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
/// Debug information queries. | /// Debug information queries. | |||
/// getFrameRegister - This method should return the register used as a b ase | /// getFrameRegister - This method should return the register used as a b ase | |||
/// for values allocated in the current stack frame. | /// for values allocated in the current stack frame. | |||
virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0; | virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0; | |||
/// getCompactUnwindRegNum - This function maps the register to the numbe r for | /// getCompactUnwindRegNum - This function maps the register to the numbe r for | |||
/// compact unwind encoding. Return -1 if the register isn't valid. | /// compact unwind encoding. Return -1 if the register isn't valid. | |||
skipping to change at line 877 | skipping to change at line 854 | |||
/// %EAX - a physical register | /// %EAX - a physical register | |||
/// %physreg17 - a physical register when no TRI instance given. | /// %physreg17 - a physical register when no TRI instance given. | |||
/// | /// | |||
/// Usage: OS << PrintReg(Reg, TRI) << '\n'; | /// Usage: OS << PrintReg(Reg, TRI) << '\n'; | |||
/// | /// | |||
class PrintReg { | class PrintReg { | |||
const TargetRegisterInfo *TRI; | const TargetRegisterInfo *TRI; | |||
unsigned Reg; | unsigned Reg; | |||
unsigned SubIdx; | unsigned SubIdx; | |||
public: | public: | |||
PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, unsigned subidx | explicit PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, | |||
= 0) | unsigned subidx = 0) | |||
: TRI(tri), Reg(reg), SubIdx(subidx) {} | : TRI(tri), Reg(reg), SubIdx(subidx) {} | |||
void print(raw_ostream&) const; | void print(raw_ostream&) const; | |||
}; | }; | |||
static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) { | static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) { | |||
PR.print(OS); | PR.print(OS); | |||
return OS; | return OS; | |||
} | } | |||
/// PrintRegUnit - Helper class for printing register units on a raw_ostrea m. | /// PrintRegUnit - Helper class for printing register units on a raw_ostrea m. | |||
End of changes. 15 change blocks. | ||||
71 lines changed or deleted | 47 lines changed or added | |||
TargetRegistry.h | TargetRegistry.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// which have been registered. | // which have been registered. | |||
// | // | |||
// Target specific class implementations should register themselves using t he | // Target specific class implementations should register themselves using t he | |||
// appropriate TargetRegistry interfaces. | // appropriate TargetRegistry interfaces. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_TARGETREGISTRY_H | #ifndef LLVM_SUPPORT_TARGETREGISTRY_H | |||
#define LLVM_SUPPORT_TARGETREGISTRY_H | #define LLVM_SUPPORT_TARGETREGISTRY_H | |||
#include "llvm/Support/CodeGen.h" | ||||
#include "llvm/ADT/Triple.h" | #include "llvm/ADT/Triple.h" | |||
#include <string> | #include "llvm/Support/CodeGen.h" | |||
#include <cassert> | #include <cassert> | |||
#include <string> | ||||
namespace llvm { | namespace llvm { | |||
class AsmPrinter; | class AsmPrinter; | |||
class Module; | class Module; | |||
class MCAssembler; | class MCAssembler; | |||
class MCAsmBackend; | class MCAsmBackend; | |||
class MCAsmInfo; | class MCAsmInfo; | |||
class MCAsmParser; | class MCAsmParser; | |||
class MCCodeEmitter; | class MCCodeEmitter; | |||
class MCCodeGenInfo; | class MCCodeGenInfo; | |||
class MCContext; | class MCContext; | |||
class MCDisassembler; | class MCDisassembler; | |||
class MCInstrAnalysis; | class MCInstrAnalysis; | |||
class MCInstPrinter; | class MCInstPrinter; | |||
class MCInstrInfo; | class MCInstrInfo; | |||
class MCRegisterInfo; | class MCRegisterInfo; | |||
class MCStreamer; | class MCStreamer; | |||
class MCSubtargetInfo; | class MCSubtargetInfo; | |||
class MCTargetAsmLexer; | ||||
class MCTargetAsmParser; | class MCTargetAsmParser; | |||
class TargetMachine; | class TargetMachine; | |||
class TargetOptions; | class TargetOptions; | |||
class raw_ostream; | class raw_ostream; | |||
class formatted_raw_ostream; | class formatted_raw_ostream; | |||
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, | MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, | |||
bool isVerboseAsm, | bool isVerboseAsm, | |||
bool useLoc, bool useCFI, | bool useLoc, bool useCFI, | |||
bool useDwarfDirectory, | bool useDwarfDirectory, | |||
skipping to change at line 99 | skipping to change at line 98 | |||
StringRef Features, | StringRef Features, | |||
const TargetOptions &Opti ons, | const TargetOptions &Opti ons, | |||
Reloc::Model RM, | Reloc::Model RM, | |||
CodeModel::Model CM, | CodeModel::Model CM, | |||
CodeGenOpt::Level OL); | CodeGenOpt::Level OL); | |||
typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM, | typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM, | |||
MCStreamer &Streamer); | MCStreamer &Streamer); | |||
typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, | typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, | |||
StringRef TT, | StringRef TT, | |||
StringRef CPU); | StringRef CPU); | |||
typedef MCTargetAsmLexer *(*MCAsmLexerCtorTy)(const Target &T, | ||||
const MCRegisterInfo &MRI | ||||
, | ||||
const MCAsmInfo &MAI); | ||||
typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI, | typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI, | |||
MCAsmParser &P); | MCAsmParser &P); | |||
typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T, | typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T, | |||
const MCSubtargetInfo & STI); | const MCSubtargetInfo & STI); | |||
typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, | typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, | |||
unsigned SyntaxVariant, | unsigned SyntaxVariant, | |||
const MCAsmInfo &MAI, | const MCAsmInfo &MAI, | |||
const MCInstrInfo &MII, | const MCInstrInfo &MII, | |||
const MCRegisterInfo &MRI , | const MCRegisterInfo &MRI , | |||
const MCSubtargetInfo &ST I); | const MCSubtargetInfo &ST I); | |||
skipping to change at line 185 | skipping to change at line 181 | |||
MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn; | MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn; | |||
/// TargetMachineCtorFn - Construction function for this target's | /// TargetMachineCtorFn - Construction function for this target's | |||
/// TargetMachine, if registered. | /// TargetMachine, if registered. | |||
TargetMachineCtorTy TargetMachineCtorFn; | TargetMachineCtorTy TargetMachineCtorFn; | |||
/// MCAsmBackendCtorFn - Construction function for this target's | /// MCAsmBackendCtorFn - Construction function for this target's | |||
/// MCAsmBackend, if registered. | /// MCAsmBackend, if registered. | |||
MCAsmBackendCtorTy MCAsmBackendCtorFn; | MCAsmBackendCtorTy MCAsmBackendCtorFn; | |||
/// MCAsmLexerCtorFn - Construction function for this target's | ||||
/// MCTargetAsmLexer, if registered. | ||||
MCAsmLexerCtorTy MCAsmLexerCtorFn; | ||||
/// MCAsmParserCtorFn - Construction function for this target's | /// MCAsmParserCtorFn - Construction function for this target's | |||
/// MCTargetAsmParser, if registered. | /// MCTargetAsmParser, if registered. | |||
MCAsmParserCtorTy MCAsmParserCtorFn; | MCAsmParserCtorTy MCAsmParserCtorFn; | |||
/// AsmPrinterCtorFn - Construction function for this target's AsmPrint er, | /// AsmPrinterCtorFn - Construction function for this target's AsmPrint er, | |||
/// if registered. | /// if registered. | |||
AsmPrinterCtorTy AsmPrinterCtorFn; | AsmPrinterCtorTy AsmPrinterCtorFn; | |||
/// MCDisassemblerCtorFn - Construction function for this target's | /// MCDisassemblerCtorFn - Construction function for this target's | |||
/// MCDisassembler, if registered. | /// MCDisassembler, if registered. | |||
skipping to change at line 245 | skipping to change at line 237 | |||
/// hasJIT - Check if this targets supports the just-in-time compilatio n. | /// hasJIT - Check if this targets supports the just-in-time compilatio n. | |||
bool hasJIT() const { return HasJIT; } | bool hasJIT() const { return HasJIT; } | |||
/// hasTargetMachine - Check if this target supports code generation. | /// hasTargetMachine - Check if this target supports code generation. | |||
bool hasTargetMachine() const { return TargetMachineCtorFn != 0; } | bool hasTargetMachine() const { return TargetMachineCtorFn != 0; } | |||
/// hasMCAsmBackend - Check if this target supports .o generation. | /// hasMCAsmBackend - Check if this target supports .o generation. | |||
bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; } | bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; } | |||
/// hasMCAsmLexer - Check if this target supports .s lexing. | ||||
bool hasMCAsmLexer() const { return MCAsmLexerCtorFn != 0; } | ||||
/// hasAsmParser - Check if this target supports .s parsing. | /// hasAsmParser - Check if this target supports .s parsing. | |||
bool hasMCAsmParser() const { return MCAsmParserCtorFn != 0; } | bool hasMCAsmParser() const { return MCAsmParserCtorFn != 0; } | |||
/// hasAsmPrinter - Check if this target supports .s printing. | /// hasAsmPrinter - Check if this target supports .s printing. | |||
bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; } | bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; } | |||
/// hasMCDisassembler - Check if this target has a disassembler. | /// hasMCDisassembler - Check if this target has a disassembler. | |||
bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; } | bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; } | |||
/// hasMCInstPrinter - Check if this target has an instruction printer. | /// hasMCInstPrinter - Check if this target has an instruction printer. | |||
skipping to change at line 363 | skipping to change at line 352 | |||
/// createMCAsmBackend - Create a target specific assembly parser. | /// createMCAsmBackend - Create a target specific assembly parser. | |||
/// | /// | |||
/// \param Triple The target triple string. | /// \param Triple The target triple string. | |||
MCAsmBackend *createMCAsmBackend(StringRef Triple, StringRef CPU) const { | MCAsmBackend *createMCAsmBackend(StringRef Triple, StringRef CPU) const { | |||
if (!MCAsmBackendCtorFn) | if (!MCAsmBackendCtorFn) | |||
return 0; | return 0; | |||
return MCAsmBackendCtorFn(*this, Triple, CPU); | return MCAsmBackendCtorFn(*this, Triple, CPU); | |||
} | } | |||
/// createMCAsmLexer - Create a target specific assembly lexer. | ||||
/// | ||||
MCTargetAsmLexer *createMCAsmLexer(const MCRegisterInfo &MRI, | ||||
const MCAsmInfo &MAI) const { | ||||
if (!MCAsmLexerCtorFn) | ||||
return 0; | ||||
return MCAsmLexerCtorFn(*this, MRI, MAI); | ||||
} | ||||
/// createMCAsmParser - Create a target specific assembly parser. | /// createMCAsmParser - Create a target specific assembly parser. | |||
/// | /// | |||
/// \param Parser The target independent parser implementation to use f or | /// \param Parser The target independent parser implementation to use f or | |||
/// parsing and lexing. | /// parsing and lexing. | |||
MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI, | MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI, | |||
MCAsmParser &Parser) const { | MCAsmParser &Parser) const { | |||
if (!MCAsmParserCtorFn) | if (!MCAsmParserCtorFn) | |||
return 0; | return 0; | |||
return MCAsmParserCtorFn(STI, Parser); | return MCAsmParserCtorFn(STI, Parser); | |||
} | } | |||
skipping to change at line 678 | skipping to change at line 658 | |||
/// while another thread is attempting to access the registry. Typicall y | /// while another thread is attempting to access the registry. Typicall y | |||
/// this is done by initializing all targets at program startup. | /// this is done by initializing all targets at program startup. | |||
/// | /// | |||
/// @param T - The target being registered. | /// @param T - The target being registered. | |||
/// @param Fn - A function to construct an AsmBackend for the target. | /// @param Fn - A function to construct an AsmBackend for the target. | |||
static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) { | static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) { | |||
if (!T.MCAsmBackendCtorFn) | if (!T.MCAsmBackendCtorFn) | |||
T.MCAsmBackendCtorFn = Fn; | T.MCAsmBackendCtorFn = Fn; | |||
} | } | |||
/// RegisterMCAsmLexer - Register a MCTargetAsmLexer implementation for | ||||
the | ||||
/// given target. | ||||
/// | ||||
/// Clients are responsible for ensuring that registration doesn't occu | ||||
r | ||||
/// while another thread is attempting to access the registry. Typicall | ||||
y | ||||
/// this is done by initializing all targets at program startup. | ||||
/// | ||||
/// @param T - The target being registered. | ||||
/// @param Fn - A function to construct an MCAsmLexer for the target. | ||||
static void RegisterMCAsmLexer(Target &T, Target::MCAsmLexerCtorTy Fn) | ||||
{ | ||||
if (!T.MCAsmLexerCtorFn) | ||||
T.MCAsmLexerCtorFn = Fn; | ||||
} | ||||
/// RegisterMCAsmParser - Register a MCTargetAsmParser implementation f or | /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation f or | |||
/// the given target. | /// the given target. | |||
/// | /// | |||
/// Clients are responsible for ensuring that registration doesn't occu r | /// Clients are responsible for ensuring that registration doesn't occu r | |||
/// while another thread is attempting to access the registry. Typicall y | /// while another thread is attempting to access the registry. Typicall y | |||
/// this is done by initializing all targets at program startup. | /// this is done by initializing all targets at program startup. | |||
/// | /// | |||
/// @param T - The target being registered. | /// @param T - The target being registered. | |||
/// @param Fn - A function to construct an MCTargetAsmParser for the ta rget. | /// @param Fn - A function to construct an MCTargetAsmParser for the ta rget. | |||
static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn ) { | static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn ) { | |||
skipping to change at line 1071 | skipping to change at line 1037 | |||
TargetRegistry::RegisterMCAsmBackend(T, &Allocator); | TargetRegistry::RegisterMCAsmBackend(T, &Allocator); | |||
} | } | |||
private: | private: | |||
static MCAsmBackend *Allocator(const Target &T, StringRef Triple, | static MCAsmBackend *Allocator(const Target &T, StringRef Triple, | |||
StringRef CPU) { | StringRef CPU) { | |||
return new MCAsmBackendImpl(T, Triple, CPU); | return new MCAsmBackendImpl(T, Triple, CPU); | |||
} | } | |||
}; | }; | |||
/// RegisterMCAsmLexer - Helper template for registering a target specifi | ||||
c | ||||
/// assembly lexer, for use in the target machine initialization | ||||
/// function. Usage: | ||||
/// | ||||
/// extern "C" void LLVMInitializeFooMCAsmLexer() { | ||||
/// extern Target TheFooTarget; | ||||
/// RegisterMCAsmLexer<FooMCAsmLexer> X(TheFooTarget); | ||||
/// } | ||||
template<class MCAsmLexerImpl> | ||||
struct RegisterMCAsmLexer { | ||||
RegisterMCAsmLexer(Target &T) { | ||||
TargetRegistry::RegisterMCAsmLexer(T, &Allocator); | ||||
} | ||||
private: | ||||
static MCTargetAsmLexer *Allocator(const Target &T, | ||||
const MCRegisterInfo &MRI, | ||||
const MCAsmInfo &MAI) { | ||||
return new MCAsmLexerImpl(T, MRI, MAI); | ||||
} | ||||
}; | ||||
/// RegisterMCAsmParser - Helper template for registering a target specif ic | /// RegisterMCAsmParser - Helper template for registering a target specif ic | |||
/// assembly parser, for use in the target machine initialization | /// assembly parser, for use in the target machine initialization | |||
/// function. Usage: | /// function. Usage: | |||
/// | /// | |||
/// extern "C" void LLVMInitializeFooMCAsmParser() { | /// extern "C" void LLVMInitializeFooMCAsmParser() { | |||
/// extern Target TheFooTarget; | /// extern Target TheFooTarget; | |||
/// RegisterMCAsmParser<FooAsmParser> X(TheFooTarget); | /// RegisterMCAsmParser<FooAsmParser> X(TheFooTarget); | |||
/// } | /// } | |||
template<class MCAsmParserImpl> | template<class MCAsmParserImpl> | |||
struct RegisterMCAsmParser { | struct RegisterMCAsmParser { | |||
End of changes. 10 change blocks. | ||||
64 lines changed or deleted | 2 lines changed or added | |||
TargetSchedule.h | TargetSchedule.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines a wrapper around MCSchedModel that allows the interfac e to | // This file defines a wrapper around MCSchedModel that allows the interfac e to | |||
// benefit from information currently only available in TargetInstrInfo. | // benefit from information currently only available in TargetInstrInfo. | |||
// Ideally, the scheduling interface would be fully defined in the MC layer . | // Ideally, the scheduling interface would be fully defined in the MC layer . | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TARGET_TARGETSCHEDMODEL_H | #ifndef LLVM_CODEGEN_TARGETSCHEDULE_H | |||
#define LLVM_TARGET_TARGETSCHEDMODEL_H | #define LLVM_CODEGEN_TARGETSCHEDULE_H | |||
#include "llvm/Target/TargetSubtargetInfo.h" | ||||
#include "llvm/MC/MCSchedule.h" | ||||
#include "llvm/MC/MCInstrItineraries.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | |||
#include "llvm/MC/MCInstrItineraries.h" | ||||
#include "llvm/MC/MCSchedule.h" | ||||
#include "llvm/Target/TargetSubtargetInfo.h" | ||||
namespace llvm { | namespace llvm { | |||
class TargetRegisterInfo; | class TargetRegisterInfo; | |||
class TargetSubtargetInfo; | class TargetSubtargetInfo; | |||
class TargetInstrInfo; | class TargetInstrInfo; | |||
class MachineInstr; | class MachineInstr; | |||
/// Provide an instruction scheduling machine model to CodeGen passes. | /// Provide an instruction scheduling machine model to CodeGen passes. | |||
class TargetSchedModel { | class TargetSchedModel { | |||
skipping to change at line 87 | skipping to change at line 87 | |||
return &InstrItins; | return &InstrItins; | |||
return 0; | return 0; | |||
} | } | |||
/// \brief Identify the processor corresponding to the current subtarget. | /// \brief Identify the processor corresponding to the current subtarget. | |||
unsigned getProcessorID() const { return SchedModel.getProcessorID(); } | unsigned getProcessorID() const { return SchedModel.getProcessorID(); } | |||
/// \brief Maximum number of micro-ops that may be scheduled per cycle. | /// \brief Maximum number of micro-ops that may be scheduled per cycle. | |||
unsigned getIssueWidth() const { return SchedModel.IssueWidth; } | 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. | /// \brief Return the number of issue slots required for this MI. | |||
unsigned getNumMicroOps(const MachineInstr *MI, | unsigned getNumMicroOps(const MachineInstr *MI, | |||
const MCSchedClassDesc *SC = 0) const; | const MCSchedClassDesc *SC = 0) const; | |||
/// \brief Get the number of kinds of resources for this target. | /// \brief Get the number of kinds of resources for this target. | |||
unsigned getNumProcResourceKinds() const { | unsigned getNumProcResourceKinds() const { | |||
return SchedModel.getNumProcResourceKinds(); | return SchedModel.getNumProcResourceKinds(); | |||
} | } | |||
/// \brief Get a processor resource by ID for convenience. | /// \brief Get a processor resource by ID for convenience. | |||
End of changes. 4 change blocks. | ||||
5 lines changed or deleted | 8 lines changed or added | |||
TargetSchedule.td | TargetSchedule.td | |||
---|---|---|---|---|
skipping to change at line 79 | skipping to change at line 79 | |||
// properties are defined in MCSchedModel. A value of "-1" in the | // properties are defined in MCSchedModel. A value of "-1" in the | |||
// target description's SchedMachineModel indicates that the property | // target description's SchedMachineModel indicates that the property | |||
// is not overriden by the target. | // is not overriden by the target. | |||
// | // | |||
// Target hooks allow subtargets to associate LoadLatency and | // Target hooks allow subtargets to associate LoadLatency and | |||
// HighLatency with groups of opcodes. | // HighLatency with groups of opcodes. | |||
class SchedMachineModel { | class SchedMachineModel { | |||
int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle. | int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle. | |||
int MinLatency = -1; // Determines which instrucions are allowed in a gro up. | int MinLatency = -1; // Determines which instrucions are allowed in a gro up. | |||
// (-1) inorder (0) ooo, (1): inorder +var latencies . | // (-1) inorder (0) ooo, (1): inorder +var latencies . | |||
int ILPWindow = -1; // Cycles of latency likely hidden by hardware buffe rs. | ||||
int LoadLatency = -1; // Cycles for loads to access the cache. | int LoadLatency = -1; // Cycles for loads to access the cache. | |||
int HighLatency = -1; // Approximation of cycles for "high latency" ops. | int HighLatency = -1; // Approximation of cycles for "high latency" ops. | |||
int MispredictPenalty = -1; // Extra cycles for a mispredicted branch. | int MispredictPenalty = -1; // Extra cycles for a mispredicted branch. | |||
// Per-cycle resources tables. | // Per-cycle resources tables. | |||
ProcessorItineraries Itineraries = NoItineraries; | ProcessorItineraries Itineraries = NoItineraries; | |||
bit NoModel = 0; // Special tag to indicate missing machine model. | bit NoModel = 0; // Special tag to indicate missing machine model. | |||
} | } | |||
skipping to change at line 135 | skipping to change at line 136 | |||
// EponymousProcResourceKind helps implement ProcResourceUnits by | // EponymousProcResourceKind helps implement ProcResourceUnits by | |||
// allowing a ProcResourceUnits definition to reference itself. It | // allowing a ProcResourceUnits definition to reference itself. It | |||
// should not be referenced anywhere else. | // should not be referenced anywhere else. | |||
def EponymousProcResourceKind : ProcResourceKind; | def EponymousProcResourceKind : ProcResourceKind; | |||
// Subtargets typically define processor resource kind and number of | // Subtargets typically define processor resource kind and number of | |||
// units in one place. | // units in one place. | |||
class ProcResource<int num> : ProcResourceKind, | class ProcResource<int num> : ProcResourceKind, | |||
ProcResourceUnits<EponymousProcResourceKind, num>; | ProcResourceUnits<EponymousProcResourceKind, num>; | |||
class ProcResGroup<list<ProcResource> resources> : ProcResourceKind { | ||||
list<ProcResource> Resources = resources; | ||||
SchedMachineModel SchedModel = ?; | ||||
} | ||||
// A target architecture may define SchedReadWrite types and associate | // A target architecture may define SchedReadWrite types and associate | |||
// them with instruction operands. | // them with instruction operands. | |||
class SchedReadWrite; | class SchedReadWrite; | |||
// List the per-operand types that map to the machine model of an | // List the per-operand types that map to the machine model of an | |||
// instruction. One SchedWrite type must be listed for each explicit | // instruction. One SchedWrite type must be listed for each explicit | |||
// def operand in order. Additional SchedWrite types may optionally be | // def operand in order. Additional SchedWrite types may optionally be | |||
// listed for implicit def operands. SchedRead types may optionally | // listed for implicit def operands. SchedRead types may optionally | |||
// be listed for use operands in order. The order of defs relative to | // be listed for use operands in order. The order of defs relative to | |||
// uses is insignificant. This way, the same SchedReadWrite list may | // uses is insignificant. This way, the same SchedReadWrite list may | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 6 lines changed or added | |||
TargetSelectionDAG.td | TargetSelectionDAG.td | |||
---|---|---|---|---|
skipping to change at line 416 | skipping to change at line 416 | |||
def debugtrap : SDNode<"ISD::DEBUGTRAP" , SDTNone, | def debugtrap : SDNode<"ISD::DEBUGTRAP" , SDTNone, | |||
[SDNPHasChain, SDNPSideEffect]>; | [SDNPHasChain, SDNPSideEffect]>; | |||
def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch, | def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch, | |||
[SDNPHasChain, SDNPMayLoad, SDNPMayStore, | [SDNPHasChain, SDNPMayLoad, SDNPMayStore, | |||
SDNPMemOperand]>; | SDNPMemOperand]>; | |||
def readcyclecounter : SDNode<"ISD::READCYCLECOUNTER", SDTIntLeaf, | def readcyclecounter : SDNode<"ISD::READCYCLECOUNTER", SDTIntLeaf, | |||
[SDNPHasChain, SDNPSideEffect]>; | [SDNPHasChain, SDNPSideEffect]>; | |||
def membarrier : SDNode<"ISD::MEMBARRIER" , SDTMemBarrier, | ||||
[SDNPHasChain, SDNPSideEffect]>; | ||||
def atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence, | def atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence, | |||
[SDNPHasChain, SDNPSideEffect]>; | [SDNPHasChain, SDNPSideEffect]>; | |||
def atomic_cmp_swap : SDNode<"ISD::ATOMIC_CMP_SWAP" , SDTAtomic3, | def atomic_cmp_swap : SDNode<"ISD::ATOMIC_CMP_SWAP" , SDTAtomic3, | |||
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperan d]>; | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperan d]>; | |||
def atomic_load_add : SDNode<"ISD::ATOMIC_LOAD_ADD" , SDTAtomic2, | def atomic_load_add : SDNode<"ISD::ATOMIC_LOAD_ADD" , SDTAtomic2, | |||
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperan d]>; | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperan d]>; | |||
def atomic_swap : SDNode<"ISD::ATOMIC_SWAP", SDTAtomic2, | def atomic_swap : SDNode<"ISD::ATOMIC_SWAP", SDTAtomic2, | |||
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperan d]>; | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperan d]>; | |||
def atomic_load_sub : SDNode<"ISD::ATOMIC_LOAD_SUB" , SDTAtomic2, | def atomic_load_sub : SDNode<"ISD::ATOMIC_LOAD_SUB" , SDTAtomic2, | |||
End of changes. 1 change blocks. | ||||
3 lines changed or deleted | 0 lines changed or added | |||
TargetSubtargetInfo.h | TargetSubtargetInfo.h | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TARGET_TARGETSUBTARGETINFO_H | #ifndef LLVM_TARGET_TARGETSUBTARGETINFO_H | |||
#define LLVM_TARGET_TARGETSUBTARGETINFO_H | #define LLVM_TARGET_TARGETSUBTARGETINFO_H | |||
#include "llvm/MC/MCSubtargetInfo.h" | #include "llvm/MC/MCSubtargetInfo.h" | |||
#include "llvm/Support/CodeGen.h" | #include "llvm/Support/CodeGen.h" | |||
namespace llvm { | namespace llvm { | |||
class MachineFunction; | ||||
class MachineInstr; | class MachineInstr; | |||
class SDep; | class SDep; | |||
class SUnit; | class SUnit; | |||
class TargetRegisterClass; | class TargetRegisterClass; | |||
class TargetSchedModel; | class TargetSchedModel; | |||
template <typename T> class SmallVectorImpl; | template <typename T> class SmallVectorImpl; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// | /// | |||
/// TargetSubtargetInfo - Generic base class for all target subtargets. Al l | /// TargetSubtargetInfo - Generic base class for all target subtargets. Al l | |||
skipping to change at line 57 | skipping to change at line 58 | |||
/// Resolve a SchedClass at runtime, where SchedClass identifies an | /// Resolve a SchedClass at runtime, where SchedClass identifies an | |||
/// MCSchedClassDesc with the isVariant property. This may return the ID of | /// MCSchedClassDesc with the isVariant property. This may return the ID of | |||
/// another variant SchedClass, but repeated invocation must quickly term inate | /// another variant SchedClass, but repeated invocation must quickly term inate | |||
/// in a nonvariant SchedClass. | /// in a nonvariant SchedClass. | |||
virtual unsigned resolveSchedClass(unsigned SchedClass, const MachineInst r *MI, | virtual unsigned resolveSchedClass(unsigned SchedClass, const MachineInst r *MI, | |||
const TargetSchedModel* SchedModel) co nst { | const TargetSchedModel* SchedModel) co nst { | |||
return 0; | return 0; | |||
} | } | |||
/// \brief True if the subtarget should run MachineScheduler after aggres | ||||
sive | ||||
/// coalescing. | ||||
/// | ||||
/// This currently replaces the SelectionDAG scheduler with the "source" | ||||
order | ||||
/// scheduler. It does not yet disable the postRA scheduler. | ||||
virtual bool enableMachineScheduler() const; | ||||
// enablePostRAScheduler - If the target can benefit from post-regalloc | // enablePostRAScheduler - If the target can benefit from post-regalloc | |||
// scheduling and the specified optimization level meets the requirement | // scheduling and the specified optimization level meets the requirement | |||
// return true to enable post-register-allocation scheduling. In | // return true to enable post-register-allocation scheduling. In | |||
// CriticalPathRCs return any register classes that should only be broken | // CriticalPathRCs return any register classes that should only be broken | |||
// if on the critical path. | // if on the critical path. | |||
virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, | virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, | |||
AntiDepBreakMode& Mode, | AntiDepBreakMode& Mode, | |||
RegClassVector& CriticalPathRCs) const ; | RegClassVector& CriticalPathRCs) const ; | |||
// adjustSchedDependency - Perform target specific adjustments to | // adjustSchedDependency - Perform target specific adjustments to | |||
// the latency of a schedule dependency. | // the latency of a schedule dependency. | |||
virtual void adjustSchedDependency(SUnit *def, SUnit *use, | virtual void adjustSchedDependency(SUnit *def, SUnit *use, | |||
SDep& dep) const { } | SDep& dep) const { } | |||
/// \brief Reset the features for the subtarget. | ||||
virtual void resetSubtargetFeatures(const MachineFunction *MF) { } | ||||
}; | }; | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 13 lines changed or added | |||
TargetTransformInfo.h | TargetTransformInfo.h | |||
---|---|---|---|---|
//===- llvm/Transforms/TargetTransformInfo.h --------------------*- C++ -*- ===// | //===- llvm/Analysis/TargetTransformInfo.h ----------------------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This pass exposes codegen information to IR-level passes. Every | // This pass exposes codegen information to IR-level passes. Every | |||
// transformation that uses codegen information is broken into three parts: | // transformation that uses codegen information is broken into three parts: | |||
// 1. The IR-level analysis pass. | // 1. The IR-level analysis pass. | |||
// 2. The IR-level transformation interface which provides the needed | // 2. The IR-level transformation interface which provides the needed | |||
// information. | // information. | |||
// 3. Codegen-level implementation which uses target-specific hooks. | // 3. Codegen-level implementation which uses target-specific hooks. | |||
// | // | |||
// This file defines #2, which is the interface that IR-level transformatio ns | // This file defines #2, which is the interface that IR-level transformatio ns | |||
// use for querying the codegen. | // use for querying the codegen. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_TARGET_TRANSFORM_INTERFACE | #ifndef LLVM_ANALYSIS_TARGETTRANSFORMINFO_H | |||
#define LLVM_TRANSFORMS_TARGET_TRANSFORM_INTERFACE | #define LLVM_ANALYSIS_TARGETTRANSFORMINFO_H | |||
#include "llvm/IR/Intrinsics.h" | ||||
#include "llvm/Pass.h" | #include "llvm/Pass.h" | |||
#include "llvm/AddressingMode.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Type.h" | ||||
namespace llvm { | namespace llvm { | |||
class ScalarTargetTransformInfo; | class GlobalValue; | |||
class VectorTargetTransformInfo; | class Type; | |||
class User; | ||||
class Value; | ||||
/// TargetTransformInfo - This pass provides access to the codegen | /// TargetTransformInfo - This pass provides access to the codegen | |||
/// interfaces that are needed for IR-level transformations. | /// interfaces that are needed for IR-level transformations. | |||
class TargetTransformInfo : public ImmutablePass { | class TargetTransformInfo { | |||
private: | protected: | |||
const ScalarTargetTransformInfo *STTI; | /// \brief The TTI instance one level down the stack. | |||
const VectorTargetTransformInfo *VTTI; | ||||
public: | ||||
/// Default ctor. | ||||
/// | /// | |||
/// @note This has to exist, because this is a pass, but it should never | /// This is used to implement the default behavior all of the methods whi | |||
be | ch | |||
/// used. | /// is to delegate up through the stack of TTIs until one can answer the | |||
TargetTransformInfo(); | /// query. | |||
TargetTransformInfo *PrevTTI; | ||||
TargetTransformInfo(const ScalarTargetTransformInfo* S, | ||||
const VectorTargetTransformInfo *V) | ||||
: ImmutablePass(ID), STTI(S), VTTI(V) { | ||||
initializeTargetTransformInfoPass(*PassRegistry::getPassRegistry()); | ||||
} | ||||
TargetTransformInfo(const TargetTransformInfo &T) : | ||||
ImmutablePass(ID), STTI(T.STTI), VTTI(T.VTTI) { } | ||||
const ScalarTargetTransformInfo* getScalarTargetTransformInfo() const { | ||||
return STTI; | ||||
} | ||||
const VectorTargetTransformInfo* getVectorTargetTransformInfo() const { | ||||
return VTTI; | ||||
} | ||||
/// Pass identification, replacement for typeid. | /// \brief The top of the stack of TTI analyses available. | |||
static char ID; | /// | |||
}; | /// This is a convenience routine maintained as TTI analyses become avail | |||
able | ||||
/// that complements the PrevTTI delegation chain. When one part of an | ||||
/// analysis pass wants to query another part of the analysis pass it can | ||||
use | ||||
/// this to start back at the top of the stack. | ||||
TargetTransformInfo *TopTTI; | ||||
/// All pass subclasses must in their initializePass routine call | ||||
/// pushTTIStack with themselves to update the pointers tracking the prev | ||||
ious | ||||
/// TTI instance in the analysis group's stack, and the top of the analys | ||||
is | ||||
/// group's stack. | ||||
void pushTTIStack(Pass *P); | ||||
/// All pass subclasses must in their finalizePass routine call popTTISta | ||||
ck | ||||
/// to update the pointers tracking the previous TTI instance in the anal | ||||
ysis | ||||
/// group's stack, and the top of the analysis group's stack. | ||||
void popTTIStack(); | ||||
/// All pass subclasses must call TargetTransformInfo::getAnalysisUsage. | ||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const; | ||||
// ------------------------------------------------------------------------ | ||||
---// | ||||
// The classes below are inherited and implemented by target-specific clas | ||||
ses | ||||
// in the codegen. | ||||
// ------------------------------------------------------------------------ | ||||
---// | ||||
/// ScalarTargetTransformInfo - This interface is used by IR-level passes | ||||
/// that need target-dependent information for generic scalar transformatio | ||||
ns. | ||||
/// LSR, and LowerInvoke use this interface. | ||||
class ScalarTargetTransformInfo { | ||||
public: | public: | |||
virtual ~ScalarTargetTransformInfo() {} | /// This class is intended to be subclassed by real implementations. | |||
virtual ~TargetTransformInfo() = 0; | ||||
/// \name Generic Target Information | ||||
/// @{ | ||||
/// \brief Underlying constants for 'cost' values in this interface. | ||||
/// | ||||
/// Many APIs in this interface return a cost. This enum defines the | ||||
/// fundamental values that should be used to interpret (and produce) tho | ||||
se | ||||
/// costs. The costs are returned as an unsigned rather than a member of | ||||
this | ||||
/// enumeration because it is expected that the cost of one IR instructio | ||||
n | ||||
/// may have a multiplicative factor to it or otherwise won't fit directl | ||||
y | ||||
/// into the enum. Moreover, it is common to sum or average costs which w | ||||
orks | ||||
/// better as simple integral values. Thus this enum only provides consta | ||||
nts. | ||||
/// | ||||
/// Note that these costs should usually reflect the intersection of code | ||||
-size | ||||
/// cost and execution cost. A free instruction is typically one that fol | ||||
ds | ||||
/// into another instruction. For example, reg-to-reg moves can often be | ||||
/// skipped by renaming the registers in the CPU, but they still are enco | ||||
ded | ||||
/// and thus wouldn't be considered 'free' here. | ||||
enum TargetCostConstants { | ||||
TCC_Free = 0, ///< Expected to fold away in lowering. | ||||
TCC_Basic = 1, ///< The cost of a typical 'add' instruction. | ||||
TCC_Expensive = 4 ///< The cost of a 'div' instruction on x86. | ||||
}; | ||||
/// \brief Estimate the cost of a specific operation when lowered. | ||||
/// | ||||
/// Note that this is designed to work on an arbitrary synthetic opcode, | ||||
and | ||||
/// thus work for hypothetical queries before an instruction has even bee | ||||
n | ||||
/// formed. However, this does *not* work for GEPs, and must not be calle | ||||
d | ||||
/// for a GEP instruction. Instead, use the dedicated getGEPCost interfac | ||||
e as | ||||
/// analyzing a GEP's cost required more information. | ||||
/// | ||||
/// Typically only the result type is required, and the operand type can | ||||
be | ||||
/// omitted. However, if the opcode is one of the cast instructions, the | ||||
/// operand type is required. | ||||
/// | ||||
/// The returned cost is defined in terms of \c TargetCostConstants, see | ||||
its | ||||
/// comments for a detailed explanation of the cost values. | ||||
virtual unsigned getOperationCost(unsigned Opcode, Type *Ty, | ||||
Type *OpTy = 0) const; | ||||
/// \brief Estimate the cost of a GEP operation when lowered. | ||||
/// | ||||
/// The contract for this function is the same as \c getOperationCost exc | ||||
ept | ||||
/// that it supports an interface that provides extra information specifi | ||||
c to | ||||
/// the GEP operation. | ||||
virtual unsigned getGEPCost(const Value *Ptr, | ||||
ArrayRef<const Value *> Operands) const; | ||||
/// \brief Estimate the cost of a function call when lowered. | ||||
/// | ||||
/// The contract for this is the same as \c getOperationCost except that | ||||
it | ||||
/// supports an interface that provides extra information specific to cal | ||||
l | ||||
/// instructions. | ||||
/// | ||||
/// This is the most basic query for estimating call cost: it only knows | ||||
the | ||||
/// function type and (potentially) the number of arguments at the call s | ||||
ite. | ||||
/// The latter is only interesting for varargs function types. | ||||
virtual unsigned getCallCost(FunctionType *FTy, int NumArgs = -1) const; | ||||
/// \brief Estimate the cost of calling a specific function when lowered. | ||||
/// | ||||
/// This overload adds the ability to reason about the particular functio | ||||
n | ||||
/// being called in the event it is a library call with special lowering. | ||||
virtual unsigned getCallCost(const Function *F, int NumArgs = -1) const; | ||||
/// \brief Estimate the cost of calling a specific function when lowered. | ||||
/// | ||||
/// This overload allows specifying a set of candidate argument values. | ||||
virtual unsigned getCallCost(const Function *F, | ||||
ArrayRef<const Value *> Arguments) const; | ||||
/// \brief Estimate the cost of an intrinsic when lowered. | ||||
/// | ||||
/// Mirrors the \c getCallCost method but uses an intrinsic identifier. | ||||
virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, | ||||
ArrayRef<Type *> ParamTys) const; | ||||
/// \brief Estimate the cost of an intrinsic when lowered. | ||||
/// | ||||
/// Mirrors the \c getCallCost method but uses an intrinsic identifier. | ||||
virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, | ||||
ArrayRef<const Value *> Arguments) cons | ||||
t; | ||||
/// \brief Estimate the cost of a given IR user when lowered. | ||||
/// | ||||
/// This can estimate the cost of either a ConstantExpr or Instruction wh | ||||
en | ||||
/// lowered. It has two primary advantages over the \c getOperationCost a | ||||
nd | ||||
/// \c getGEPCost above, and one significant disadvantage: it can only be | ||||
/// used when the IR construct has already been formed. | ||||
/// | ||||
/// The advantages are that it can inspect the SSA use graph to reason mo | ||||
re | ||||
/// accurately about the cost. For example, all-constant-GEPs can often b | ||||
e | ||||
/// folded into a load or other instruction, but if they are used in some | ||||
/// other context they may not be folded. This routine can distinguish su | ||||
ch | ||||
/// cases. | ||||
/// | ||||
/// The returned cost is defined in terms of \c TargetCostConstants, see | ||||
its | ||||
/// comments for a detailed explanation of the cost values. | ||||
virtual unsigned getUserCost(const User *U) const; | ||||
/// \brief Test whether calls to a function lower to actual program funct | ||||
ion | ||||
/// calls. | ||||
/// | ||||
/// The idea is to test whether the program is likely to require a 'call' | ||||
/// instruction or equivalent in order to call the given function. | ||||
/// | ||||
/// FIXME: It's not clear that this is a good or useful query API. Client | ||||
's | ||||
/// should probably move to simpler cost metrics using the above. | ||||
/// Alternatively, we could split the cost interface into distinct code-s | ||||
ize | ||||
/// and execution-speed costs. This would allow modelling the core of thi | ||||
s | ||||
/// query more accurately as the a call is a single small instruction, bu | ||||
t | ||||
/// incurs significant execution cost. | ||||
virtual bool isLoweredToCall(const Function *F) const; | ||||
/// @} | ||||
/// \name Scalar Target Information | ||||
/// @{ | ||||
/// \brief Flags indicating the kind of support for population count. | ||||
/// | ||||
/// Compared to the SW implementation, HW support is supposed to | ||||
/// significantly boost the performance when the population is dense, and | ||||
it | ||||
/// may or may not degrade performance if the population is sparse. A HW | ||||
/// support is considered as "Fast" if it can outperform, or is on a par | ||||
/// with, SW implementation when the population is sparse; otherwise, it | ||||
is | ||||
/// considered as "Slow". | ||||
enum PopcntSupportKind { | ||||
PSK_Software, | ||||
PSK_SlowHardware, | ||||
PSK_FastHardware | ||||
}; | ||||
/// isLegalAddImmediate - Return true if the specified immediate is legal | /// isLegalAddImmediate - Return true if the specified immediate is legal | |||
/// add immediate, that is the target has add instructions which can add | /// add immediate, that is the target has add instructions which can add | |||
/// a register with the immediate without having to materialize the | /// a register with the immediate without having to materialize the | |||
/// immediate into a register. | /// immediate into a register. | |||
virtual bool isLegalAddImmediate(int64_t) const { | virtual bool isLegalAddImmediate(int64_t Imm) const; | |||
return false; | ||||
} | ||||
/// isLegalICmpImmediate - Return true if the specified immediate is lega l | /// isLegalICmpImmediate - Return true if the specified immediate is lega l | |||
/// icmp immediate, that is the target has icmp instructions which can co mpare | /// icmp immediate, that is the target has icmp instructions which can co mpare | |||
/// a register against the immediate without having to materialize the | /// a register against the immediate without having to materialize the | |||
/// immediate into a register. | /// immediate into a register. | |||
virtual bool isLegalICmpImmediate(int64_t) const { | virtual bool isLegalICmpImmediate(int64_t Imm) const; | |||
return false; | ||||
} | ||||
/// isLegalAddressingMode - Return true if the addressing mode represente d by | /// isLegalAddressingMode - Return true if the addressing mode represente d by | |||
/// AM is legal for this target, for a load/store of the specified type. | /// 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 address ing | /// The type may be VoidTy, in which case only return true if the address ing | |||
/// mode is legal for a load/store of any legal type. | /// mode is legal for a load/store of any legal type. | |||
/// TODO: Handle pre/postinc as well. | /// TODO: Handle pre/postinc as well. | |||
virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const { | virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, | |||
return false; | int64_t BaseOffset, bool HasBaseReg, | |||
} | int64_t Scale) const; | |||
/// isTruncateFree - Return true if it's free to truncate a value of | /// 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 i n | /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value i n | |||
/// register EAX to i16 by referencing its sub-register AX. | /// register EAX to i16 by referencing its sub-register AX. | |||
virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const { | virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; | |||
return false; | ||||
} | ||||
/// Is this type legal. | /// Is this type legal. | |||
virtual bool isTypeLegal(Type *Ty) const { | virtual bool isTypeLegal(Type *Ty) const; | |||
return false; | ||||
} | ||||
/// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes | /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes | |||
virtual unsigned getJumpBufAlignment() const { | virtual unsigned getJumpBufAlignment() const; | |||
return 0; | ||||
} | ||||
/// getJumpBufSize - returns the target's jmp_buf size in bytes. | /// getJumpBufSize - returns the target's jmp_buf size in bytes. | |||
virtual unsigned getJumpBufSize() const { | virtual unsigned getJumpBufSize() const; | |||
return 0; | ||||
} | ||||
/// shouldBuildLookupTables - Return true if switches should be turned in to | /// shouldBuildLookupTables - Return true if switches should be turned in to | |||
/// lookup tables for the target. | /// lookup tables for the target. | |||
virtual bool shouldBuildLookupTables() const { | virtual bool shouldBuildLookupTables() const; | |||
return true; | ||||
} | ||||
}; | ||||
/// VectorTargetTransformInfo - This interface is used by the vectorizers | /// getPopcntSupport - Return hardware support for population count. | |||
/// to estimate the profitability of vectorization for different instructio | virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) cons | |||
ns. | t; | |||
class VectorTargetTransformInfo { | ||||
public: | ||||
virtual ~VectorTargetTransformInfo() {} | ||||
/// Returns the expected cost of the instruction opcode. The opcode is on | /// getIntImmCost - Return the expected cost of materializing the given | |||
e of | /// integer immediate of the specified type. | |||
/// the enums like Instruction::Add. The type arguments are the type of t | virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const; | |||
he | ||||
/// operation. | /// @} | |||
/// Most instructions only use the first type and in that case the second | ||||
/// operand is ignored. | /// \name Vector Target Information | |||
/// | /// @{ | |||
/// Exceptions: | ||||
/// * Br instructions do not use any of the types. | /// \brief The various kinds of shuffle patterns for vector queries. | |||
/// * Select instructions pass the return type as Ty1 and the selector as | enum ShuffleKind { | |||
Ty2. | SK_Broadcast, ///< Broadcast element 0 to all other elements. | |||
/// * Cast instructions pass the destination as Ty1 and the source as Ty2 | SK_Reverse, ///< Reverse the order of the vector. | |||
. | SK_InsertSubvector, ///< InsertSubvector. Index indicates start offset. | |||
/// * Insert/Extract element pass only the vector type as Ty1. | SK_ExtractSubvector ///< ExtractSubvector Index indicates start offset. | |||
/// * ShuffleVector, Load, Store do not use this call. | }; | |||
virtual unsigned getInstrCost(unsigned Opcode, | ||||
Type *Ty1 = 0, | /// \brief Additonal information about an operand's possible values. | |||
Type *Ty2 = 0) const { | enum OperandValueKind { | |||
return 1; | OK_AnyValue, // Operand can have any value. | |||
} | OK_UniformValue, // Operand is uniform (splat of a value). | |||
OK_UniformConstantValue // Operand is uniform constant. | ||||
/// Returns the expected cost of arithmetic ops, such as mul, xor, fsub, | }; | |||
etc. | ||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const | /// \return The number of scalar or vector registers that the target has. | |||
{ | /// If 'Vectors' is true, it returns the number of vector registers. If i | |||
return 1; | t is | |||
} | /// set to false, it returns the number of scalar registers. | |||
virtual unsigned getNumberOfRegisters(bool Vector) const; | ||||
/// Returns the cost of a vector broadcast of a scalar at place zero to a | ||||
/// vector of type 'Tp'. | /// \return The width of the largest scalar or vector register type. | |||
virtual unsigned getBroadcastCost(Type *Tp) const { | virtual unsigned getRegisterBitWidth(bool Vector) const; | |||
return 1; | ||||
} | /// \return The maximum unroll factor that the vectorizer should try to | |||
/// perform for this target. This number depends on the level of parallel | ||||
ism | ||||
/// and the number of execution units in the CPU. | ||||
virtual unsigned getMaximumUnrollFactor() const; | ||||
/// \return The expected cost of arithmetic ops, such as mul, xor, fsub, | ||||
etc. | ||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty, | ||||
OperandValueKind Opd1Info = OK_AnyValue, | ||||
OperandValueKind Opd2Info = OK_AnyValue) | ||||
const; | ||||
/// \return The cost of a shuffle instruction of kind Kind and of type Tp | ||||
. | ||||
/// The index and subtype parameters are used by the subvector insertion | ||||
and | ||||
/// extraction shuffle kinds. | ||||
virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0 | ||||
, | ||||
Type *SubTp = 0) const; | ||||
/// Returns the expected cost of cast instructions, such as bitcast, trun c, | /// \return The expected cost of cast instructions, such as bitcast, trun c, | |||
/// zext, etc. | /// zext, etc. | |||
virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, | virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, | |||
Type *Src) const { | Type *Src) const; | |||
return 1; | ||||
} | ||||
/// Returns the expected cost of control-flow related instrutctions such as | /// \return The expected cost of control-flow related instructions such a s | |||
/// Phi, Ret, Br. | /// Phi, Ret, Br. | |||
virtual unsigned getCFInstrCost(unsigned Opcode) const { | virtual unsigned getCFInstrCost(unsigned Opcode) const; | |||
return 1; | ||||
} | ||||
/// Returns the expected cost of compare and select instructions. | /// \returns The expected cost of compare and select instructions. | |||
virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, | virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, | |||
Type *CondTy = 0) const { | Type *CondTy = 0) const; | |||
return 1; | ||||
} | ||||
/// Returns the expected cost of vector Insert and Extract. | /// \return The expected cost of vector Insert and Extract. | |||
/// Use -1 to indicate that there is no information on the index value. | /// Use -1 to indicate that there is no information on the index value. | |||
virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, | virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, | |||
unsigned Index = -1) const { | unsigned Index = -1) const; | |||
return 1; | ||||
} | ||||
/// Returns the cost of Load and Store instructions. | /// \return The cost of Load and Store instructions. | |||
virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, | virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, | |||
unsigned Alignment, | unsigned Alignment, | |||
unsigned AddressSpace) const { | unsigned AddressSpace) const; | |||
return 1; | ||||
} | ||||
/// Returns the number of pieces into which the provided type must be | /// \returns The cost of Intrinsic instructions. | |||
virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, | ||||
ArrayRef<Type *> Tys) const; | ||||
/// \returns The number of pieces into which the provided type must be | ||||
/// split during legalization. Zero is returned when the answer is unknow n. | /// split during legalization. Zero is returned when the answer is unknow n. | |||
virtual unsigned getNumberOfParts(Type *Tp) const { | virtual unsigned getNumberOfParts(Type *Tp) const; | |||
return 0; | ||||
} | /// \returns The cost of the address computation. For most targets this c | |||
an be | ||||
/// merged into the instruction indexing mode. Some targets might want to | ||||
/// distinguish between address computation for memory operations on vect | ||||
or | ||||
/// types and scalar types. Such targets should override this function. | ||||
virtual unsigned getAddressComputationCost(Type *Ty) const; | ||||
/// @} | ||||
/// Analysis group identification. | ||||
static char ID; | ||||
}; | }; | |||
/// \brief Create the base case instance of a pass in the TTI analysis grou | ||||
p. | ||||
/// | ||||
/// This class provides the base case for the stack of TTI analyzes. It doe | ||||
sn't | ||||
/// delegate to anything and uses the STTI and VTTI objects passed in to | ||||
/// satisfy the queries. | ||||
ImmutablePass *createNoTargetTransformInfoPass(); | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 34 change blocks. | ||||
139 lines changed or deleted | 327 lines changed or added | |||
Targets.def | Targets.def | |||
---|---|---|---|---|
skipping to change at line 26 | skipping to change at line 26 | |||
|* The set of targets supported by LLVM is generated at configuration *| | |* The set of targets supported by LLVM is generated at configuration *| | |||
|* time, at which point this header is generated. Do not modify this *| | |* time, at which point this header is generated. Do not modify this *| | |||
|* header directly. *| | |* header directly. *| | |||
|* *| | |* *| | |||
\*===---------------------------------------------------------------------- ===*/ | \*===---------------------------------------------------------------------- ===*/ | |||
#ifndef LLVM_TARGET | #ifndef LLVM_TARGET | |||
# error Please define the macro LLVM_TARGET(TargetName) | # error Please define the macro LLVM_TARGET(TargetName) | |||
#endif | #endif | |||
LLVM_TARGET(Hexagon) LLVM_TARGET(NVPTX) LLVM_TARGET(MBlaze) LLVM_TARGET(Cpp Backend) LLVM_TARGET(MSP430) LLVM_TARGET(XCore) LLVM_TARGET(CellSPU) LLVM_T ARGET(Mips) LLVM_TARGET(ARM) LLVM_TARGET(PowerPC) LLVM_TARGET(Sparc) LLVM_T ARGET(X86) | LLVM_TARGET(SystemZ) LLVM_TARGET(Hexagon) LLVM_TARGET(NVPTX) LLVM_TARGET(MB laze) LLVM_TARGET(CppBackend) LLVM_TARGET(MSP430) LLVM_TARGET(XCore) LLVM_T ARGET(Mips) LLVM_TARGET(ARM) LLVM_TARGET(AArch64) LLVM_TARGET(PowerPC) LLVM _TARGET(Sparc) LLVM_TARGET(X86) | |||
#undef LLVM_TARGET | #undef LLVM_TARGET | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
ThreadLocal.h | ThreadLocal.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the llvm::sys::ThreadLocal class. | // This file declares the llvm::sys::ThreadLocal class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_THREAD_LOCAL_H | #ifndef LLVM_SUPPORT_THREADLOCAL_H | |||
#define LLVM_SYSTEM_THREAD_LOCAL_H | #define LLVM_SUPPORT_THREADLOCAL_H | |||
#include "llvm/Support/Threading.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/Threading.h" | ||||
#include <cassert> | #include <cassert> | |||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
// ThreadLocalImpl - Common base class of all ThreadLocal instantiation s. | // ThreadLocalImpl - Common base class of all ThreadLocal instantiation s. | |||
// YOU SHOULD NEVER USE THIS DIRECTLY. | // YOU SHOULD NEVER USE THIS DIRECTLY. | |||
class ThreadLocalImpl { | class ThreadLocalImpl { | |||
typedef uint64_t ThreadLocalDataTy; | typedef uint64_t ThreadLocalDataTy; | |||
/// \brief Platform-specific thread local data. | /// \brief Platform-specific thread local data. | |||
/// | /// | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
Threading.h | Threading.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// TThis file defines llvm_start_multithreaded() and friends. | // TThis file defines llvm_start_multithreaded() and friends. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_THREADING_H | #ifndef LLVM_SUPPORT_THREADING_H | |||
#define LLVM_SYSTEM_THREADING_H | #define LLVM_SUPPORT_THREADING_H | |||
namespace llvm { | namespace llvm { | |||
/// llvm_start_multithreaded - Allocate and initialize structures needed to | /// llvm_start_multithreaded - Allocate and initialize structures needed to | |||
/// make LLVM safe for multithreading. The return value indicates whethe r | /// make LLVM safe for multithreading. The return value indicates whethe r | |||
/// multithreaded initialization succeeded. LLVM will still be operation al | /// multithreaded initialization succeeded. LLVM will still be operation al | |||
/// on "failed" return, and will still be safe for hosting threading | /// on "failed" return, and will still be safe for hosting threading | |||
/// applications in the JIT, but will not be safe for concurrent calls to the | /// applications in the JIT, but will not be safe for concurrent calls to the | |||
/// LLVM APIs. | /// LLVM APIs. | |||
/// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS. | /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS. | |||
bool llvm_start_multithreaded(); | bool llvm_start_multithreaded(); | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
TimeValue.h | TimeValue.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This header file declares the operating system TimeValue concept. | // This header file declares the operating system TimeValue concept. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_TIMEVALUE_H | ||||
#define LLVM_SUPPORT_TIMEVALUE_H | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include <string> | #include <string> | |||
#ifndef LLVM_SYSTEM_TIMEVALUE_H | ||||
#define LLVM_SYSTEM_TIMEVALUE_H | ||||
namespace llvm { | namespace llvm { | |||
namespace sys { | namespace sys { | |||
/// This class is used where a precise fixed point in time is required. T he | /// This class is used where a precise fixed point in time is required. T he | |||
/// range of TimeValue spans many hundreds of billions of years both past and | /// range of TimeValue spans many hundreds of billions of years both past and | |||
/// present. The precision of TimeValue is to the nanosecond. However, t he | /// present. The precision of TimeValue is to the nanosecond. However, t he | |||
/// actual precision of its values will be determined by the resolution o f | /// actual precision of its values will be determined by the resolution o f | |||
/// the system clock. The TimeValue class is used in conjunction with sev eral | /// the system clock. The TimeValue class is used in conjunction with sev eral | |||
/// other lib/System interfaces to specify the time at which a call shoul d | /// other lib/System interfaces to specify the time at which a call shoul d | |||
/// timeout, etc. | /// timeout, etc. | |||
/// @since 1.4 | /// @since 1.4 | |||
skipping to change at line 85 | skipping to change at line 85 | |||
NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand | NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand | |||
NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million | NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million | |||
NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms ) | NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms ) | |||
NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms ) | NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms ) | |||
}; | }; | |||
/// @} | /// @} | |||
/// @name Constructors | /// @name Constructors | |||
/// @{ | /// @{ | |||
public: | public: | |||
/// \brief Default construct a time value, initializing to ZeroTime. | ||||
TimeValue() : seconds_(0), nanos_(0) {} | ||||
/// Caller provides the exact value in seconds and nanoseconds. The | /// Caller provides the exact value in seconds and nanoseconds. The | |||
/// \p nanos argument defaults to zero for convenience. | /// \p nanos argument defaults to zero for convenience. | |||
/// @brief Explicit constructor | /// @brief Explicit constructor | |||
explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0) | explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0) | |||
: seconds_( seconds ), nanos_( nanos ) { this->normalize(); } | : seconds_( seconds ), nanos_( nanos ) { this->normalize(); } | |||
/// Caller provides the exact value as a double in seconds with the | /// Caller provides the exact value as a double in seconds with the | |||
/// fractional part representing nanoseconds. | /// fractional part representing nanoseconds. | |||
/// @brief Double Constructor. | /// @brief Double Constructor. | |||
explicit TimeValue( double new_time ) | explicit TimeValue( double new_time ) | |||
skipping to change at line 240 | skipping to change at line 243 | |||
/// @brief Convert to a number of milliseconds (can overflow) | /// @brief Convert to a number of milliseconds (can overflow) | |||
uint64_t msec() const { | uint64_t msec() const { | |||
return seconds_ * MILLISECONDS_PER_SECOND + | return seconds_ * MILLISECONDS_PER_SECOND + | |||
( nanos_ / NANOSECONDS_PER_MILLISECOND ); | ( nanos_ / NANOSECONDS_PER_MILLISECOND ); | |||
} | } | |||
/// Converts the TimeValue into the corresponding number of "ticks" for | /// Converts the TimeValue into the corresponding number of "ticks" for | |||
/// Posix, correcting for the difference in Posix zero time. | /// Posix, correcting for the difference in Posix zero time. | |||
/// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1, 1970) | /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1, 1970) | |||
uint64_t toPosixTime() const { | uint64_t toPosixTime() const { | |||
uint64_t result = seconds_ - PosixZeroTime.seconds_; | uint64_t result = seconds_ - PosixZeroTimeSeconds; | |||
result += nanos_ / NANOSECONDS_PER_POSIX_TICK; | result += nanos_ / NANOSECONDS_PER_POSIX_TICK; | |||
return result; | return result; | |||
} | } | |||
/// Converts the TimeValue into the corresponding number of seconds | /// Converts the TimeValue into the corresponding number of seconds | |||
/// since the epoch (00:00:00 Jan 1,1970). | /// since the epoch (00:00:00 Jan 1,1970). | |||
uint64_t toEpochTime() const { | uint64_t toEpochTime() const { | |||
return seconds_ - PosixZeroTime.seconds_; | return seconds_ - PosixZeroTimeSeconds; | |||
} | } | |||
/// Converts the TimeValue into the corresponding number of "ticks" for | /// Converts the TimeValue into the corresponding number of "ticks" for | |||
/// Win32 platforms, correcting for the difference in Win32 zero time. | /// 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 windows time (seconds since 12:00:00a Jan 1, 1601 ) | |||
uint64_t toWin32Time() const { | uint64_t toWin32Time() const { | |||
uint64_t result = seconds_ - Win32ZeroTime.seconds_; | uint64_t result = seconds_ - Win32ZeroTimeSeconds; | |||
result += nanos_ / NANOSECONDS_PER_WIN32_TICK; | result += nanos_ / NANOSECONDS_PER_WIN32_TICK; | |||
return result; | return result; | |||
} | } | |||
/// Provides the seconds and nanoseconds as results in its arguments af ter | /// Provides the seconds and nanoseconds as results in its arguments af ter | |||
/// correction for the Posix zero time. | /// correction for the Posix zero time. | |||
/// @brief Convert to timespec time (ala POSIX.1b) | /// @brief Convert to timespec time (ala POSIX.1b) | |||
void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const { | void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const { | |||
seconds = seconds_ - PosixZeroTime.seconds_; | seconds = seconds_ - PosixZeroTimeSeconds; | |||
nanos = nanos_; | nanos = nanos_; | |||
} | } | |||
/// Provides conversion of the TimeValue into a readable time & date. | /// Provides conversion of the TimeValue into a readable time & date. | |||
/// @returns std::string containing the readable time value | /// @returns std::string containing the readable time value | |||
/// @brief Convert time to a string. | /// @brief Convert time to a string. | |||
std::string str() const; | std::string str() const; | |||
/// @} | /// @} | |||
/// @name Mutators | /// @name Mutators | |||
skipping to change at line 331 | skipping to change at line 334 | |||
this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND; | this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND; | |||
this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND ) * | this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND ) * | |||
NANOSECONDS_PER_MILLISECOND; | NANOSECONDS_PER_MILLISECOND; | |||
this->normalize(); | this->normalize(); | |||
} | } | |||
/// Converts the \p seconds argument from PosixTime to the correspondin g | /// Converts the \p seconds argument from PosixTime to the correspondin g | |||
/// TimeValue and assigns that value to \p this. | /// TimeValue and assigns that value to \p this. | |||
/// @brief Convert seconds form PosixTime to TimeValue | /// @brief Convert seconds form PosixTime to TimeValue | |||
void fromEpochTime( SecondsType seconds ) { | void fromEpochTime( SecondsType seconds ) { | |||
seconds_ = seconds + PosixZeroTime.seconds_; | seconds_ = seconds + PosixZeroTimeSeconds; | |||
nanos_ = 0; | nanos_ = 0; | |||
this->normalize(); | this->normalize(); | |||
} | } | |||
/// Converts the \p win32Time argument from Windows FILETIME to the | /// Converts the \p win32Time argument from Windows FILETIME to the | |||
/// corresponding TimeValue and assigns that value to \p this. | /// corresponding TimeValue and assigns that value to \p this. | |||
/// @brief Convert seconds form Windows FILETIME to TimeValue | /// @brief Convert seconds form Windows FILETIME to TimeValue | |||
void fromWin32Time( uint64_t win32Time ) { | void fromWin32Time( uint64_t win32Time ) { | |||
this->seconds_ = win32Time / 10000000 + Win32ZeroTime.seconds_; | this->seconds_ = win32Time / 10000000 + Win32ZeroTimeSeconds; | |||
this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100; | this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100; | |||
} | } | |||
/// @} | /// @} | |||
/// @name Implementation | /// @name Implementation | |||
/// @{ | /// @{ | |||
private: | private: | |||
/// This causes the values to be represented so that the fractional | /// This causes the values to be represented so that the fractional | |||
/// part is minimized, possibly incrementing the seconds part. | /// part is minimized, possibly incrementing the seconds part. | |||
/// @brief Normalize to canonical form. | /// @brief Normalize to canonical form. | |||
void normalize(); | void normalize(); | |||
/// @} | /// @} | |||
/// @name Data | /// @name Data | |||
/// @{ | /// @{ | |||
private: | private: | |||
/// Store the values as a <timeval>. | /// Store the values as a <timeval>. | |||
SecondsType seconds_;///< Stores the seconds part of the TimeVal | SecondsType seconds_;///< Stores the seconds part of the TimeVal | |||
NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeV al | NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeV al | |||
static const SecondsType PosixZeroTimeSeconds; | ||||
static const SecondsType Win32ZeroTimeSeconds; | ||||
/// @} | /// @} | |||
}; | }; | |||
inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) { | inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) { | |||
TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_); | TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_); | |||
sum.normalize (); | sum.normalize (); | |||
return sum; | return sum; | |||
} | } | |||
End of changes. 10 change blocks. | ||||
9 lines changed or deleted | 15 lines changed or added | |||
Timer.h | Timer.h | |||
---|---|---|---|---|
//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*- ===// | //===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | ||||
// This file defines three classes: Timer, TimeRegion, and TimerGroup, | ||||
// documented below. | ||||
// | ||||
//===---------------------------------------------------------------------- | ||||
===// | ||||
#ifndef LLVM_SUPPORT_TIMER_H | #ifndef LLVM_SUPPORT_TIMER_H | |||
#define LLVM_SUPPORT_TIMER_H | #define LLVM_SUPPORT_TIMER_H | |||
#include "llvm/ADT/StringRef.h" | ||||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/ADT/StringRef.h" | ||||
#include <cassert> | #include <cassert> | |||
#include <string> | #include <string> | |||
#include <vector> | ||||
#include <utility> | #include <utility> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
class Timer; | class Timer; | |||
class TimerGroup; | class TimerGroup; | |||
class raw_ostream; | class raw_ostream; | |||
class TimeRecord { | class TimeRecord { | |||
double WallTime; // Wall clock time elapsed in seconds | double WallTime; // Wall clock time elapsed in seconds | |||
double UserTime; // User time elapsed | double UserTime; // User time elapsed | |||
skipping to change at line 80 | skipping to change at line 75 | |||
/// print - Print the current timer to standard error, and reset the "Sta rted" | /// print - Print the current timer to standard error, and reset the "Sta rted" | |||
/// flag. | /// flag. | |||
void print(const TimeRecord &Total, raw_ostream &OS) const; | void print(const TimeRecord &Total, raw_ostream &OS) const; | |||
}; | }; | |||
/// Timer - This class is used to track the amount of time spent between | /// Timer - This class is used to track the amount of time spent between | |||
/// invocations of its startTimer()/stopTimer() methods. Given appropriate OS | /// invocations of its startTimer()/stopTimer() methods. Given appropriate OS | |||
/// support it can also keep track of the RSS of the program at various poi nts. | /// support it can also keep track of the RSS of the program at various poi nts. | |||
/// By default, the Timer will print the amount of time it has captured to | /// By default, the Timer will print the amount of time it has captured to | |||
/// standard error when the laster timer is destroyed, otherwise it is prin ted | /// standard error when the last timer is destroyed, otherwise it is printe d | |||
/// when its TimerGroup is destroyed. Timers do not print their informatio n | /// when its TimerGroup is destroyed. Timers do not print their informatio n | |||
/// if they are never started. | /// if they are never started. | |||
/// | /// | |||
class Timer { | class Timer { | |||
TimeRecord Time; | TimeRecord Time; | |||
std::string Name; // The name of this time variable. | std::string Name; // The name of this time variable. | |||
bool Started; // Has this time variable ever been started? | bool Started; // Has this time variable ever been started? | |||
TimerGroup *TG; // The TimerGroup this Timer is in. | TimerGroup *TG; // The TimerGroup this Timer is in. | |||
Timer **Prev, *Next; // Doubly linked list of timers in the group. | Timer **Prev, *Next; // Doubly linked list of timers in the group. | |||
skipping to change at line 127 | skipping to change at line 122 | |||
/// stopTimer - Stop the timer. | /// stopTimer - Stop the timer. | |||
/// | /// | |||
void stopTimer(); | void stopTimer(); | |||
private: | private: | |||
friend class TimerGroup; | friend class TimerGroup; | |||
}; | }; | |||
/// The TimeRegion class is used as a helper class to call the startTimer() and | /// The TimeRegion class is used as a helper class to call the startTimer() and | |||
/// stopTimer() methods of the Timer class. When the object is constructed , it | /// stopTimer() methods of the Timer class. When the object is constructed , it | |||
/// starts the timer specified as it's argument. When it is destroyed, it stops | /// starts the timer specified as its argument. When it is destroyed, it s tops | |||
/// the relevant timer. This makes it easy to time a region of code. | /// the relevant timer. This makes it easy to time a region of code. | |||
/// | /// | |||
class TimeRegion { | class TimeRegion { | |||
Timer *T; | Timer *T; | |||
TimeRegion(const TimeRegion &) LLVM_DELETED_FUNCTION; | TimeRegion(const TimeRegion &) LLVM_DELETED_FUNCTION; | |||
public: | public: | |||
explicit TimeRegion(Timer &t) : T(&t) { | explicit TimeRegion(Timer &t) : T(&t) { | |||
T->startTimer(); | T->startTimer(); | |||
} | } | |||
explicit TimeRegion(Timer *t) : T(t) { | explicit TimeRegion(Timer *t) : T(t) { | |||
End of changes. 7 change blocks. | ||||
10 lines changed or deleted | 4 lines changed or added | |||
TinyPtrVector.h | TinyPtrVector.h | |||
---|---|---|---|---|
skipping to change at line 73 | skipping to change at line 73 | |||
// If we have a full vector allocated, try to re-use it. | // If we have a full vector allocated, try to re-use it. | |||
if (RHS.Val.template is<EltTy>()) { | if (RHS.Val.template is<EltTy>()) { | |||
Val.template get<VecTy*>()->clear(); | Val.template get<VecTy*>()->clear(); | |||
Val.template get<VecTy*>()->push_back(RHS.front()); | Val.template get<VecTy*>()->push_back(RHS.front()); | |||
} else { | } else { | |||
*Val.template get<VecTy*>() = *RHS.Val.template get<VecTy*>(); | *Val.template get<VecTy*>() = *RHS.Val.template get<VecTy*>(); | |||
} | } | |||
return *this; | return *this; | |||
} | } | |||
#if LLVM_USE_RVALUE_REFERENCES | #if LLVM_HAS_RVALUE_REFERENCES | |||
TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) { | TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) { | |||
RHS.Val = (EltTy)0; | RHS.Val = (EltTy)0; | |||
} | } | |||
TinyPtrVector &operator=(TinyPtrVector &&RHS) { | TinyPtrVector &operator=(TinyPtrVector &&RHS) { | |||
if (this == &RHS) | if (this == &RHS) | |||
return *this; | return *this; | |||
if (RHS.empty()) { | if (RHS.empty()) { | |||
this->clear(); | this->clear(); | |||
return *this; | return *this; | |||
} | } | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
ToolOutputFile.h | ToolOutputFile.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the tool_output_file class. | // This file defines the tool_output_file class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_TOOL_OUTPUT_FILE_H | #ifndef LLVM_SUPPORT_TOOLOUTPUTFILE_H | |||
#define LLVM_SUPPORT_TOOL_OUTPUT_FILE_H | #define LLVM_SUPPORT_TOOLOUTPUTFILE_H | |||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | |||
namespace llvm { | namespace llvm { | |||
/// tool_output_file - This class contains a raw_fd_ostream and adds a | /// tool_output_file - This class contains a raw_fd_ostream and adds a | |||
/// few extra features commonly needed for compiler-like tool output files: | /// few extra features commonly needed for compiler-like tool output files: | |||
/// - The file is automatically deleted if the process is killed. | /// - The file is automatically deleted if the process is killed. | |||
/// - The file is automatically deleted when the tool_output_file | /// - The file is automatically deleted when the tool_output_file | |||
/// object is destroyed unless the client calls keep(). | /// object is destroyed unless the client calls keep(). | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Trace.h | Trace.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// single entry, multiple exit, region of code that is often hot. Trace-ba sed | // single entry, multiple exit, region of code that is often hot. Trace-ba sed | |||
// optimizations treat traces almost like they are a large, strange, basic | // optimizations treat traces almost like they are a large, strange, basic | |||
// block: because the trace path is assumed to be hot, optimizations for th e | // block: because the trace path is assumed to be hot, optimizations for th e | |||
// fall-through path are made at the expense of the non-fall-through paths. | // fall-through path are made at the expense of the non-fall-through paths. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ANALYSIS_TRACE_H | #ifndef LLVM_ANALYSIS_TRACE_H | |||
#define LLVM_ANALYSIS_TRACE_H | #define LLVM_ANALYSIS_TRACE_H | |||
#include <vector> | ||||
#include <cassert> | #include <cassert> | |||
#include <vector> | ||||
namespace llvm { | namespace llvm { | |||
class BasicBlock; | class BasicBlock; | |||
class Function; | class Function; | |||
class Module; | class Module; | |||
class raw_ostream; | class raw_ostream; | |||
class Trace { | class Trace { | |||
typedef std::vector<BasicBlock *> BasicBlockListType; | typedef std::vector<BasicBlock *> BasicBlockListType; | |||
BasicBlockListType BasicBlocks; | BasicBlockListType BasicBlocks; | |||
skipping to change at line 119 | skipping to change at line 119 | |||
void print(raw_ostream &O) const; | void print(raw_ostream &O) const; | |||
/// dump - Debugger convenience method; writes trace to standard error | /// dump - Debugger convenience method; writes trace to standard error | |||
/// output stream. | /// output stream. | |||
/// | /// | |||
void dump() const; | void dump() const; | |||
}; | }; | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif // TRACE_H | #endif // LLVM_ANALYSIS_TRACE_H | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Triple.h | Triple.h | |||
---|---|---|---|---|
skipping to change at line 46 | skipping to change at line 46 | |||
/// Clients that need to handle the non-canonical triples that users often | /// Clients that need to handle the non-canonical triples that users often | |||
/// specify should use the normalize method. | /// specify should use the normalize method. | |||
/// | /// | |||
/// See autoconf/config.guess for a glimpse into what triples look like in | /// See autoconf/config.guess for a glimpse into what triples look like in | |||
/// practice. | /// practice. | |||
class Triple { | class Triple { | |||
public: | public: | |||
enum ArchType { | enum ArchType { | |||
UnknownArch, | UnknownArch, | |||
arm, // ARM; arm, armv.*, xscale | arm, // ARM: arm, armv.*, xscale | |||
cellspu, // CellSPU: spu, cellspu | aarch64, // AArch64: aarch64 | |||
hexagon, // Hexagon: hexagon | hexagon, // Hexagon: hexagon | |||
mips, // MIPS: mips, mipsallegrex | mips, // MIPS: mips, mipsallegrex | |||
mipsel, // MIPSEL: mipsel, mipsallegrexel | mipsel, // MIPSEL: mipsel, mipsallegrexel | |||
mips64, // MIPS64: mips64 | mips64, // MIPS64: mips64 | |||
mips64el,// MIPS64EL: mips64el | mips64el,// MIPS64EL: mips64el | |||
msp430, // MSP430: msp430 | msp430, // MSP430: msp430 | |||
ppc, // PPC: powerpc | ppc, // PPC: powerpc | |||
ppc64, // PPC64: powerpc64, ppu | ppc64, // PPC64: powerpc64, ppu | |||
r600, // R600: AMD GPUs HD2XXX - HD6XXX | r600, // R600: AMD GPUs HD2XXX - HD6XXX | |||
sparc, // Sparc: sparc | sparc, // Sparc: sparc | |||
sparcv9, // Sparcv9: Sparcv9 | sparcv9, // Sparcv9: Sparcv9 | |||
systemz, // SystemZ: s390x | ||||
tce, // TCE (http://tce.cs.tut.fi/): tce | tce, // TCE (http://tce.cs.tut.fi/): tce | |||
thumb, // Thumb: thumb, thumbv.* | thumb, // Thumb: thumb, thumbv.* | |||
x86, // X86: i[3-9]86 | x86, // X86: i[3-9]86 | |||
x86_64, // X86-64: amd64, x86_64 | x86_64, // X86-64: amd64, x86_64 | |||
xcore, // XCore: xcore | xcore, // XCore: xcore | |||
mblaze, // MBlaze: mblaze | mblaze, // MBlaze: mblaze | |||
nvptx, // NVPTX: 32-bit | nvptx, // NVPTX: 32-bit | |||
nvptx64, // NVPTX: 64-bit | nvptx64, // NVPTX: 64-bit | |||
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten) | le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten) | |||
amdil, // amdil: amd IL | amdil, // amdil: amd IL | |||
skipping to change at line 104 | skipping to change at line 105 | |||
Lv2, // PS3 | Lv2, // PS3 | |||
MacOSX, | MacOSX, | |||
MinGW32, // i*86-pc-mingw32, *-w64-mingw32 | MinGW32, // i*86-pc-mingw32, *-w64-mingw32 | |||
NetBSD, | NetBSD, | |||
OpenBSD, | OpenBSD, | |||
Solaris, | Solaris, | |||
Win32, | Win32, | |||
Haiku, | Haiku, | |||
Minix, | Minix, | |||
RTEMS, | RTEMS, | |||
NativeClient, | NaCl, // Native Client | |||
CNK, // BG/P Compute-Node Kernel | CNK, // BG/P Compute-Node Kernel | |||
Bitrig, | Bitrig, | |||
AIX | AIX | |||
}; | }; | |||
enum EnvironmentType { | enum EnvironmentType { | |||
UnknownEnvironment, | UnknownEnvironment, | |||
GNU, | GNU, | |||
GNUEABI, | GNUEABI, | |||
GNUEABIHF, | GNUEABIHF, | |||
GNUX32, | ||||
EABI, | EABI, | |||
MachO, | MachO, | |||
Android, | Android, | |||
ELF | ELF | |||
}; | }; | |||
private: | private: | |||
std::string Data; | std::string Data; | |||
/// The parsed arch type. | /// The parsed arch type. | |||
skipping to change at line 299 | skipping to change at line 301 | |||
assert(Major == 10 && "Unexpected major version"); | assert(Major == 10 && "Unexpected major version"); | |||
return isOSVersionLT(Minor + 4, Micro, 0); | return isOSVersionLT(Minor + 4, Micro, 0); | |||
} | } | |||
/// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both | /// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both | |||
/// "darwin" and "osx" as OS X triples. | /// "darwin" and "osx" as OS X triples. | |||
bool isMacOSX() const { | bool isMacOSX() const { | |||
return getOS() == Triple::Darwin || getOS() == Triple::MacOSX; | return getOS() == Triple::Darwin || getOS() == Triple::MacOSX; | |||
} | } | |||
/// Is this an iOS triple. | ||||
bool isiOS() const { | ||||
return getOS() == Triple::IOS; | ||||
} | ||||
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS). | /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS). | |||
bool isOSDarwin() const { | bool isOSDarwin() const { | |||
return isMacOSX() || getOS() == Triple::IOS; | return isMacOSX() || isiOS(); | |||
} | } | |||
/// \brief Tests for either Cygwin or MinGW OS | /// \brief Tests for either Cygwin or MinGW OS | |||
bool isOSCygMing() const { | bool isOSCygMing() const { | |||
return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32; | return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32; | |||
} | } | |||
/// isOSWindows - Is this a "Windows" OS. | /// isOSWindows - Is this a "Windows" OS. | |||
bool isOSWindows() const { | bool isOSWindows() const { | |||
return getOS() == Triple::Win32 || isOSCygMing(); | return getOS() == Triple::Win32 || isOSCygMing(); | |||
} | } | |||
/// \brief Tests whether the OS is NaCl (Native Client) | ||||
bool isOSNaCl() const { | ||||
return getOS() == Triple::NaCl; | ||||
} | ||||
/// \brief Tests whether the OS uses the ELF binary format. | /// \brief Tests whether the OS uses the ELF binary format. | |||
bool isOSBinFormatELF() const { | bool isOSBinFormatELF() const { | |||
return !isOSDarwin() && !isOSWindows(); | return !isOSDarwin() && !isOSWindows(); | |||
} | } | |||
/// \brief Tests whether the OS uses the COFF binary format. | /// \brief Tests whether the OS uses the COFF binary format. | |||
bool isOSBinFormatCOFF() const { | bool isOSBinFormatCOFF() const { | |||
return isOSWindows(); | return isOSWindows(); | |||
} | } | |||
End of changes. 7 change blocks. | ||||
5 lines changed or deleted | 17 lines changed or added | |||
Twine.h | Twine.h | |||
---|---|---|---|---|
skipping to change at line 239 | skipping to change at line 239 | |||
if (getRHSKind() == TwineKind && | if (getRHSKind() == TwineKind && | |||
!RHS.twine->isBinary()) | !RHS.twine->isBinary()) | |||
return false; | return false; | |||
return true; | return true; | |||
} | } | |||
/// getLHSKind - Get the NodeKind of the left-hand side. | /// getLHSKind - Get the NodeKind of the left-hand side. | |||
NodeKind getLHSKind() const { return (NodeKind) LHSKind; } | NodeKind getLHSKind() const { return (NodeKind) LHSKind; } | |||
/// getRHSKind - Get the NodeKind of the left-hand side. | /// getRHSKind - Get the NodeKind of the right-hand side. | |||
NodeKind getRHSKind() const { return (NodeKind) RHSKind; } | NodeKind getRHSKind() const { return (NodeKind) RHSKind; } | |||
/// printOneChild - Print one child from a twine. | /// printOneChild - Print one child from a twine. | |||
void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const; | void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const; | |||
/// printOneChildRepr - Print the representation of one child from a tw ine. | /// printOneChildRepr - Print the representation of one child from a tw ine. | |||
void printOneChildRepr(raw_ostream &OS, Child Ptr, | void printOneChildRepr(raw_ostream &OS, Child Ptr, | |||
NodeKind Kind) const; | NodeKind Kind) const; | |||
public: | public: | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Type.h | Type.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the declaration of the Type class. For more "Type" | // This file contains the declaration of the Type class. For more "Type" | |||
// stuff, look in DerivedTypes.h. | // stuff, look in DerivedTypes.h. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TYPE_H | #ifndef LLVM_IR_TYPE_H | |||
#define LLVM_TYPE_H | #define LLVM_IR_TYPE_H | |||
#include "llvm/ADT/APFloat.h" | ||||
#include "llvm/Support/Casting.h" | #include "llvm/Support/Casting.h" | |||
#include "llvm/Support/CBindingWrapping.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/ErrorHandling.h" | ||||
#include "llvm-c/Core.h" | ||||
namespace llvm { | namespace llvm { | |||
class PointerType; | class PointerType; | |||
class IntegerType; | class IntegerType; | |||
class raw_ostream; | class raw_ostream; | |||
class Module; | class Module; | |||
class LLVMContext; | class LLVMContext; | |||
class LLVMContextImpl; | class LLVMContextImpl; | |||
class StringRef; | class StringRef; | |||
skipping to change at line 165 | skipping to change at line 169 | |||
/// isFloatingPointTy - Return true if this is one of the six floating po int | /// isFloatingPointTy - Return true if this is one of the six floating po int | |||
/// types | /// types | |||
bool isFloatingPointTy() const { | bool isFloatingPointTy() const { | |||
return getTypeID() == HalfTyID || getTypeID() == FloatTyID || | return getTypeID() == HalfTyID || getTypeID() == FloatTyID || | |||
getTypeID() == DoubleTyID || | getTypeID() == DoubleTyID || | |||
getTypeID() == X86_FP80TyID || getTypeID() == FP128TyID || | getTypeID() == X86_FP80TyID || getTypeID() == FP128TyID || | |||
getTypeID() == PPC_FP128TyID; | getTypeID() == PPC_FP128TyID; | |||
} | } | |||
const fltSemantics &getFltSemantics() const { | ||||
switch (getTypeID()) { | ||||
case HalfTyID: return APFloat::IEEEhalf; | ||||
case FloatTyID: return APFloat::IEEEsingle; | ||||
case DoubleTyID: return APFloat::IEEEdouble; | ||||
case X86_FP80TyID: return APFloat::x87DoubleExtended; | ||||
case FP128TyID: return APFloat::IEEEquad; | ||||
case PPC_FP128TyID: return APFloat::PPCDoubleDouble; | ||||
default: llvm_unreachable("Invalid floating type"); | ||||
} | ||||
} | ||||
/// isX86_MMXTy - Return true if this is X86 MMX. | /// isX86_MMXTy - Return true if this is X86 MMX. | |||
bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; } | bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; } | |||
/// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP . | /// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP . | |||
/// | /// | |||
bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy (); } | bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy (); } | |||
/// isLabelTy - Return true if this is 'label'. | /// isLabelTy - Return true if this is 'label'. | |||
bool isLabelTy() const { return getTypeID() == LabelTyID; } | bool isLabelTy() const { return getTypeID() == LabelTyID; } | |||
skipping to change at line 454 | skipping to change at line 470 | |||
static inline NodeType *getEntryNode(NodeType *T) { return T; } | static inline NodeType *getEntryNode(NodeType *T) { return T; } | |||
static inline ChildIteratorType child_begin(NodeType *N) { | static inline ChildIteratorType child_begin(NodeType *N) { | |||
return N->subtype_begin(); | return N->subtype_begin(); | |||
} | } | |||
static inline ChildIteratorType child_end(NodeType *N) { | static inline ChildIteratorType child_end(NodeType *N) { | |||
return N->subtype_end(); | return N->subtype_end(); | |||
} | } | |||
}; | }; | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
DEFINE_ISA_CONVERSION_FUNCTIONS(Type, LLVMTypeRef) | ||||
/* Specialized opaque type conversions. | ||||
*/ | ||||
inline Type **unwrap(LLVMTypeRef* Tys) { | ||||
return reinterpret_cast<Type**>(Tys); | ||||
} | ||||
inline LLVMTypeRef *wrap(Type **Tys) { | ||||
return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys)); | ||||
} | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 6 change blocks. | ||||
2 lines changed or deleted | 31 lines changed or added | |||
TypeBuilder.h | TypeBuilder.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the TypeBuilder class, which is used as a convenient w ay to | // This file defines the TypeBuilder class, which is used as a convenient w ay to | |||
// create LLVM types with a consistent and simplified interface. | // create LLVM types with a consistent and simplified interface. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TYPEBUILDER_H | #ifndef LLVM_IR_TYPEBUILDER_H | |||
#define LLVM_TYPEBUILDER_H | #define LLVM_IR_TYPEBUILDER_H | |||
#include "llvm/DerivedTypes.h" | #include "llvm/IR/DerivedTypes.h" | |||
#include "llvm/LLVMContext.h" | #include "llvm/IR/LLVMContext.h" | |||
#include <limits.h> | #include <limits.h> | |||
namespace llvm { | namespace llvm { | |||
/// TypeBuilder - This provides a uniform API for looking up types | /// TypeBuilder - This provides a uniform API for looking up types | |||
/// known at compile time. To support cross-compilation, we define a | /// known at compile time. To support cross-compilation, we define a | |||
/// series of tag types in the llvm::types namespace, like i<N>, | /// series of tag types in the llvm::types namespace, like i<N>, | |||
/// ieee_float, ppc_fp128, etc. TypeBuilder<T, false> allows T to be | /// ieee_float, ppc_fp128, etc. TypeBuilder<T, false> allows T to be | |||
/// any of these, a native C type (whose size may depend on the host | /// any of these, a native C type (whose size may depend on the host | |||
/// compiler), or a pointer, function, or struct type built out of | /// compiler), or a pointer, function, or struct type built out of | |||
End of changes. 2 change blocks. | ||||
4 lines changed or deleted | 4 lines changed or added | |||
TypeFinder.h | TypeFinder.h | |||
---|---|---|---|---|
//===-- llvm/TypeFinder.h - Class for finding used struct types -*- C++ -*- ===// | //===-- llvm/IR/TypeFinder.h - Class to find used struct types --*- C++ -*- ===// | |||
// | // | |||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file contains the declaration of the TypeFinder class. | // This file contains the declaration of the TypeFinder class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TYPEFINDER_H | #ifndef LLVM_IR_TYPEFINDER_H | |||
#define LLVM_TYPEFINDER_H | #define LLVM_IR_TYPEFINDER_H | |||
#include "llvm/ADT/DenseSet.h" | #include "llvm/ADT/DenseSet.h" | |||
#include <vector> | #include <vector> | |||
namespace llvm { | namespace llvm { | |||
class MDNode; | class MDNode; | |||
class Module; | class Module; | |||
class StructType; | class StructType; | |||
class Type; | class Type; | |||
End of changes. 2 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
Use.h | Use.h | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
// to a Use without having to store a User pointer in every Use. A | // to a Use without having to store a User pointer in every Use. A | |||
// User is preceded in memory by all the Uses corresponding to its | // User is preceded in memory by all the Uses corresponding to its | |||
// operands, and the low bits of one of the fields (Prev) of the Use | // operands, and the low bits of one of the fields (Prev) of the Use | |||
// class are used to encode offsets to be able to find that User given | // class are used to encode offsets to be able to find that User given | |||
// a pointer to any Use. For details, see: | // a pointer to any Use. For details, see: | |||
// | // | |||
// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout | // http://www.llvm.org/docs/ProgrammersManual.html#UserLayout | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_USE_H | #ifndef LLVM_IR_USE_H | |||
#define LLVM_USE_H | #define LLVM_IR_USE_H | |||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/Support/CBindingWrapping.h" | ||||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm-c/Core.h" | ||||
#include <cstddef> | #include <cstddef> | |||
#include <iterator> | #include <iterator> | |||
namespace llvm { | namespace llvm { | |||
class Value; | class Value; | |||
class User; | class User; | |||
class Use; | class Use; | |||
template<typename> | template<typename> | |||
struct simplify_type; | struct simplify_type; | |||
skipping to change at line 69 | skipping to change at line 71 | |||
public: | public: | |||
/// swap - provide a fast substitute to std::swap<Use> | /// swap - provide a fast substitute to std::swap<Use> | |||
/// that also works with less standard-compliant compilers | /// that also works with less standard-compliant compilers | |||
void swap(Use &RHS); | void swap(Use &RHS); | |||
// A type for the word following an array of hung-off Uses in memory, whi ch is | // A type for the word following an array of hung-off Uses in memory, whi ch is | |||
// a pointer back to their User with the bottom bit set. | // a pointer back to their User with the bottom bit set. | |||
typedef PointerIntPair<User*, 1, unsigned> UserRef; | typedef PointerIntPair<User*, 1, unsigned> UserRef; | |||
private: | private: | |||
/// Copy ctor - do not implement | ||||
Use(const Use &U) LLVM_DELETED_FUNCTION; | Use(const Use &U) LLVM_DELETED_FUNCTION; | |||
/// Destructor - Only for zap() | /// Destructor - Only for zap() | |||
~Use() { | ~Use() { | |||
if (Val) removeFromList(); | if (Val) removeFromList(); | |||
} | } | |||
enum PrevPtrTag { zeroDigitTag | enum PrevPtrTag { zeroDigitTag | |||
, oneDigitTag | , oneDigitTag | |||
, stopTag | , stopTag | |||
skipping to change at line 152 | skipping to change at line 153 | |||
if (Next) Next->setPrev(StrippedPrev); | if (Next) Next->setPrev(StrippedPrev); | |||
} | } | |||
friend class Value; | friend class Value; | |||
}; | }; | |||
// simplify_type - Allow clients to treat uses just like values when using | // simplify_type - Allow clients to treat uses just like values when using | |||
// casting operators. | // casting operators. | |||
template<> struct simplify_type<Use> { | template<> struct simplify_type<Use> { | |||
typedef Value* SimpleType; | typedef Value* SimpleType; | |||
static SimpleType getSimplifiedValue(const Use &Val) { | static SimpleType getSimplifiedValue(Use &Val) { | |||
return static_cast<SimpleType>(Val.get()); | return Val.get(); | |||
} | } | |||
}; | }; | |||
template<> struct simplify_type<const Use> { | template<> struct simplify_type<const Use> { | |||
typedef Value* SimpleType; | typedef /*const*/ Value* SimpleType; | |||
static SimpleType getSimplifiedValue(const Use &Val) { | static SimpleType getSimplifiedValue(const Use &Val) { | |||
return static_cast<SimpleType>(Val.get()); | return Val.get(); | |||
} | } | |||
}; | }; | |||
template<typename UserTy> // UserTy == 'User' or 'const User' | template<typename UserTy> // UserTy == 'User' or 'const User' | |||
class value_use_iterator : public std::iterator<std::forward_iterator_tag, | class value_use_iterator : public std::iterator<std::forward_iterator_tag, | |||
UserTy*, ptrdiff_t> { | UserTy*, ptrdiff_t> { | |||
typedef std::iterator<std::forward_iterator_tag, UserTy*, ptrdiff_t> supe r; | typedef std::iterator<std::forward_iterator_tag, UserTy*, ptrdiff_t> supe r; | |||
typedef value_use_iterator<UserTy> _Self; | typedef value_use_iterator<UserTy> _Self; | |||
Use *U; | Use *U; | |||
skipping to change at line 215 | skipping to change at line 216 | |||
UserTy *operator->() const { return operator*(); } | UserTy *operator->() const { return operator*(); } | |||
Use &getUse() const { return *U; } | Use &getUse() const { return *U; } | |||
/// getOperandNo - Return the operand # of this use in its User. Defined in | /// getOperandNo - Return the operand # of this use in its User. Defined in | |||
/// User.h | /// User.h | |||
/// | /// | |||
unsigned getOperandNo() const; | unsigned getOperandNo() const; | |||
}; | }; | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef) | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 8 change blocks. | ||||
7 lines changed or deleted | 11 lines changed or added | |||
User.h | User.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This class defines the interface that one who uses a Value must implemen t. | // This class defines the interface that one who uses a Value must implemen t. | |||
// Each instance of the Value class keeps track of what User's have handles | // Each instance of the Value class keeps track of what User's have handles | |||
// to it. | // to it. | |||
// | // | |||
// * Instructions are the largest class of Users. | // * Instructions are the largest class of Users. | |||
// * Constants may be users of other constants (think arrays and stuff) | // * Constants may be users of other constants (think arrays and stuff) | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_USER_H | #ifndef LLVM_IR_USER_H | |||
#define LLVM_USER_H | #define LLVM_IR_USER_H | |||
#include "llvm/IR/Value.h" | ||||
#include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | |||
#include "llvm/Value.h" | ||||
namespace llvm { | namespace llvm { | |||
/// OperandTraits - Compile-time customization of | /// OperandTraits - Compile-time customization of | |||
/// operand-related allocators and accessors | /// operand-related allocators and accessors | |||
/// for use of the User class | /// for use of the User class | |||
template <class> | template <class> | |||
struct OperandTraits; | struct OperandTraits; | |||
class User : public Value { | class User : public Value { | |||
skipping to change at line 186 | skipping to change at line 186 | |||
void replaceUsesOfWith(Value *From, Value *To); | void replaceUsesOfWith(Value *From, Value *To); | |||
// Methods for support type inquiry through isa, cast, and dyn_cast: | // Methods for support type inquiry through isa, cast, and dyn_cast: | |||
static inline bool classof(const Value *V) { | static inline bool classof(const Value *V) { | |||
return isa<Instruction>(V) || isa<Constant>(V); | return isa<Instruction>(V) || isa<Constant>(V); | |||
} | } | |||
}; | }; | |||
template<> struct simplify_type<User::op_iterator> { | template<> struct simplify_type<User::op_iterator> { | |||
typedef Value* SimpleType; | typedef Value* SimpleType; | |||
static SimpleType getSimplifiedValue(User::op_iterator &Val) { | ||||
static SimpleType getSimplifiedValue(const User::op_iterator &Val) { | return Val->get(); | |||
return static_cast<SimpleType>(Val->get()); | ||||
} | } | |||
}; | }; | |||
template<> struct simplify_type<const User::op_iterator> | ||||
: public simplify_type<User::op_iterator> {}; | ||||
template<> struct simplify_type<User::const_op_iterator> { | template<> struct simplify_type<User::const_op_iterator> { | |||
typedef Value* SimpleType; | typedef /*const*/ Value* SimpleType; | |||
static SimpleType getSimplifiedValue(User::const_op_iterator &Val) { | ||||
static SimpleType getSimplifiedValue(const User::const_op_iterator &Val) | return Val->get(); | |||
{ | ||||
return static_cast<SimpleType>(Val->get()); | ||||
} | } | |||
}; | }; | |||
template<> struct simplify_type<const User::const_op_iterator> | ||||
: public simplify_type<User::const_op_iterator> {}; | ||||
// value_use_iterator::getOperandNo - Requires the definition of the User c lass. | // value_use_iterator::getOperandNo - Requires the definition of the User c lass. | |||
template<typename UserTy> | template<typename UserTy> | |||
unsigned value_use_iterator<UserTy>::getOperandNo() const { | unsigned value_use_iterator<UserTy>::getOperandNo() const { | |||
return U - U->getUser()->op_begin(); | return U - U->getUser()->op_begin(); | |||
} | } | |||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 7 change blocks. | ||||
18 lines changed or deleted | 8 lines changed or added | |||
Valgrind.h | Valgrind.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// Methods for communicating with a valgrind instance this program is runni ng | // Methods for communicating with a valgrind instance this program is runni ng | |||
// under. These are all no-ops unless LLVM was configured on a system with the | // under. These are all no-ops unless LLVM was configured on a system with the | |||
// valgrind headers installed and valgrind is controlling this process. | // valgrind headers installed and valgrind is controlling this process. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_VALGRIND_H | #ifndef LLVM_SYSTEM_VALGRIND_H | |||
#define LLVM_SYSTEM_VALGRIND_H | #define LLVM_SYSTEM_VALGRIND_H | |||
#include "llvm/Support/Compiler.h" | ||||
#include "llvm/Config/llvm-config.h" | #include "llvm/Config/llvm-config.h" | |||
#include "llvm/Support/Compiler.h" | ||||
#include <stddef.h> | #include <stddef.h> | |||
#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG) | #if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG) | |||
// tsan (Thread Sanitizer) is a valgrind-based tool that detects these exac t | // tsan (Thread Sanitizer) is a valgrind-based tool that detects these exac t | |||
// functions by name. | // functions by name. | |||
extern "C" { | extern "C" { | |||
LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line, | LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line, | |||
const volatile void *cv); | const volatile void *cv); | |||
LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line, | LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line, | |||
const volatile void *cv); | const volatile void *cv); | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Value.h | Value.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file declares the Value class. | // This file declares the Value class. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_VALUE_H | #ifndef LLVM_IR_VALUE_H | |||
#define LLVM_VALUE_H | #define LLVM_IR_VALUE_H | |||
#include "llvm/Use.h" | #include "llvm/IR/Use.h" | |||
#include "llvm/Support/Casting.h" | #include "llvm/Support/Casting.h" | |||
#include "llvm/Support/CBindingWrapping.h" | ||||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
#include "llvm-c/Core.h" | ||||
namespace llvm { | namespace llvm { | |||
class Constant; | class Constant; | |||
class Argument; | class Argument; | |||
class Instruction; | class Instruction; | |||
class BasicBlock; | class BasicBlock; | |||
class GlobalValue; | class GlobalValue; | |||
class Function; | class Function; | |||
class GlobalVariable; | class GlobalVariable; | |||
skipping to change at line 260 | skipping to change at line 262 | |||
/// intersectOptionalDataWith - Clear any optional flags in this value | /// intersectOptionalDataWith - Clear any optional flags in this value | |||
/// that are not also set in the given value. | /// that are not also set in the given value. | |||
void intersectOptionalDataWith(const Value *V) { | void intersectOptionalDataWith(const Value *V) { | |||
SubclassOptionalData &= V->SubclassOptionalData; | SubclassOptionalData &= V->SubclassOptionalData; | |||
} | } | |||
/// hasValueHandle - Return true if there is a value handle associated wi th | /// hasValueHandle - Return true if there is a value handle associated wi th | |||
/// this value. | /// this value. | |||
bool hasValueHandle() const { return HasValueHandle; } | bool hasValueHandle() const { return HasValueHandle; } | |||
/// stripPointerCasts - This method strips off any unneeded pointer casts | /// \brief This method strips off any unneeded pointer casts, | |||
and | /// all-zero GEPs and aliases from the specified value, returning the ori | |||
/// all-zero GEPs from the specified value, returning the original uncast | ginal | |||
ed | /// uncasted value. If this is called on a non-pointer value, it returns | |||
/// value. If this is called on a non-pointer value, it returns 'this'. | /// 'this'. | |||
Value *stripPointerCasts(); | Value *stripPointerCasts(); | |||
const Value *stripPointerCasts() const { | const Value *stripPointerCasts() const { | |||
return const_cast<Value*>(this)->stripPointerCasts(); | return const_cast<Value*>(this)->stripPointerCasts(); | |||
} | } | |||
/// \brief This method strips off any unneeded pointer casts and | ||||
/// all-zero GEPs from the specified value, returning the original | ||||
/// uncasted value. If this is called on a non-pointer value, it returns | ||||
/// 'this'. | ||||
Value *stripPointerCastsNoFollowAliases(); | ||||
const Value *stripPointerCastsNoFollowAliases() const { | ||||
return const_cast<Value*>(this)->stripPointerCastsNoFollowAliases(); | ||||
} | ||||
/// stripInBoundsConstantOffsets - This method strips off unneeded pointe r casts and | /// stripInBoundsConstantOffsets - This method strips off unneeded pointe r casts and | |||
/// all-constant GEPs from the specified value, returning the original | /// all-constant GEPs from the specified value, returning the original | |||
/// pointer value. If this is called on a non-pointer value, it returns | /// pointer value. If this is called on a non-pointer value, it returns | |||
/// 'this'. | /// 'this'. | |||
Value *stripInBoundsConstantOffsets(); | Value *stripInBoundsConstantOffsets(); | |||
const Value *stripInBoundsConstantOffsets() const { | const Value *stripInBoundsConstantOffsets() const { | |||
return const_cast<Value*>(this)->stripInBoundsConstantOffsets(); | return const_cast<Value*>(this)->stripInBoundsConstantOffsets(); | |||
} | } | |||
/// stripInBoundsOffsets - This method strips off unneeded pointer casts and | /// stripInBoundsOffsets - This method strips off unneeded pointer casts and | |||
skipping to change at line 407 | skipping to change at line 419 | |||
class PointerLikeTypeTraits<Value*> { | class PointerLikeTypeTraits<Value*> { | |||
typedef Value* PT; | typedef Value* PT; | |||
public: | public: | |||
static inline void *getAsVoidPointer(PT P) { return P; } | static inline void *getAsVoidPointer(PT P) { return P; } | |||
static inline PT getFromVoidPointer(void *P) { | static inline PT getFromVoidPointer(void *P) { | |||
return static_cast<PT>(P); | return static_cast<PT>(P); | |||
} | } | |||
enum { NumLowBitsAvailable = 2 }; | enum { NumLowBitsAvailable = 2 }; | |||
}; | }; | |||
// Create wrappers for C Binding types (see CBindingWrapping.h). | ||||
DEFINE_ISA_CONVERSION_FUNCTIONS(Value, LLVMValueRef) | ||||
/* Specialized opaque value conversions. | ||||
*/ | ||||
inline Value **unwrap(LLVMValueRef *Vals) { | ||||
return reinterpret_cast<Value**>(Vals); | ||||
} | ||||
template<typename T> | ||||
inline T **unwrap(LLVMValueRef *Vals, unsigned Length) { | ||||
#ifdef DEBUG | ||||
for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I) | ||||
cast<T>(*I); | ||||
#endif | ||||
(void)Length; | ||||
return reinterpret_cast<T**>(Vals); | ||||
} | ||||
inline LLVMValueRef *wrap(const Value **Vals) { | ||||
return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals)); | ||||
} | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 7 change blocks. | ||||
8 lines changed or deleted | 42 lines changed or added | |||
ValueHandle.h | ValueHandle.h | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// | // | |||
// This file declares the ValueHandle class and its sub-classes. | // This file declares the ValueHandle class and its sub-classes. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_VALUEHANDLE_H | #ifndef LLVM_SUPPORT_VALUEHANDLE_H | |||
#define LLVM_SUPPORT_VALUEHANDLE_H | #define LLVM_SUPPORT_VALUEHANDLE_H | |||
#include "llvm/ADT/DenseMapInfo.h" | #include "llvm/ADT/DenseMapInfo.h" | |||
#include "llvm/ADT/PointerIntPair.h" | #include "llvm/ADT/PointerIntPair.h" | |||
#include "llvm/Value.h" | #include "llvm/IR/Value.h" | |||
namespace llvm { | namespace llvm { | |||
class ValueHandleBase; | class ValueHandleBase; | |||
template<typename From> struct simplify_type; | ||||
// ValueHandleBase** is only 4-byte aligned. | // ValueHandleBase** is only 4-byte aligned. | |||
template<> | template<> | |||
class PointerLikeTypeTraits<ValueHandleBase**> { | class PointerLikeTypeTraits<ValueHandleBase**> { | |||
public: | public: | |||
static inline void *getAsVoidPointer(ValueHandleBase** P) { return P; } | static inline void *getAsVoidPointer(ValueHandleBase** P) { return P; } | |||
static inline ValueHandleBase **getFromVoidPointer(void *P) { | static inline ValueHandleBase **getFromVoidPointer(void *P) { | |||
return static_cast<ValueHandleBase**>(P); | return static_cast<ValueHandleBase**>(P); | |||
} | } | |||
enum { NumLowBitsAvailable = 2 }; | enum { NumLowBitsAvailable = 2 }; | |||
skipping to change at line 165 | skipping to change at line 166 | |||
return ValueHandleBase::operator=(RHS); | return ValueHandleBase::operator=(RHS); | |||
} | } | |||
operator Value*() const { | operator Value*() const { | |||
return getValPtr(); | return getValPtr(); | |||
} | } | |||
}; | }; | |||
// Specialize simplify_type to allow WeakVH to participate in | // Specialize simplify_type to allow WeakVH to participate in | |||
// dyn_cast, isa, etc. | // dyn_cast, isa, etc. | |||
template<typename From> struct simplify_type; | template<> struct simplify_type<WeakVH> { | |||
template<> struct simplify_type<const WeakVH> { | ||||
typedef Value* SimpleType; | typedef Value* SimpleType; | |||
static SimpleType getSimplifiedValue(const WeakVH &WVH) { | static SimpleType getSimplifiedValue(WeakVH &WVH) { | |||
return static_cast<Value *>(WVH); | return WVH; | |||
} | } | |||
}; | }; | |||
template<> struct simplify_type<WeakVH> : public simplify_type<const WeakVH > {}; | ||||
/// AssertingVH - This is a Value Handle that points to a value and asserts out | /// AssertingVH - This is a Value Handle that points to a value and asserts out | |||
/// if the value is destroyed while the handle is still live. This is very | /// if the value is destroyed while the handle is still live. This is very | |||
/// useful for catching dangling pointer bugs and other things which can be | /// useful for catching dangling pointer bugs and other things which can be | |||
/// non-obvious. One particularly useful place to use this is as the Key o f a | /// non-obvious. One particularly useful place to use this is as the Key o f a | |||
/// map. Dangling pointer bugs often lead to really subtle bugs that only occur | /// map. Dangling pointer bugs often lead to really subtle bugs that only occur | |||
/// if another object happens to get allocated to the same address as the o ld | /// if another object happens to get allocated to the same address as the o ld | |||
/// one. Using an AssertingVH ensures that an assert is triggered as soon as | /// one. Using an AssertingVH ensures that an assert is triggered as soon as | |||
/// the bad delete occurs. | /// the bad delete occurs. | |||
/// | /// | |||
skipping to change at line 239 | skipping to change at line 238 | |||
} | } | |||
ValueTy *operator=(const AssertingVH<ValueTy> &RHS) { | ValueTy *operator=(const AssertingVH<ValueTy> &RHS) { | |||
setValPtr(RHS.getValPtr()); | setValPtr(RHS.getValPtr()); | |||
return getValPtr(); | return getValPtr(); | |||
} | } | |||
ValueTy *operator->() const { return getValPtr(); } | ValueTy *operator->() const { return getValPtr(); } | |||
ValueTy &operator*() const { return *getValPtr(); } | ValueTy &operator*() const { return *getValPtr(); } | |||
}; | }; | |||
// Specialize simplify_type to allow AssertingVH to participate in | ||||
// dyn_cast, isa, etc. | ||||
template<typename From> struct simplify_type; | ||||
template<> struct simplify_type<const AssertingVH<Value> > { | ||||
typedef Value* SimpleType; | ||||
static SimpleType getSimplifiedValue(const AssertingVH<Value> &AVH) { | ||||
return static_cast<Value *>(AVH); | ||||
} | ||||
}; | ||||
template<> struct simplify_type<AssertingVH<Value> > | ||||
: public simplify_type<const AssertingVH<Value> > {}; | ||||
// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap. | // Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap. | |||
template<typename T> | template<typename T> | |||
struct DenseMapInfo<AssertingVH<T> > { | struct DenseMapInfo<AssertingVH<T> > { | |||
typedef DenseMapInfo<T*> PointerInfo; | typedef DenseMapInfo<T*> PointerInfo; | |||
static inline AssertingVH<T> getEmptyKey() { | static inline AssertingVH<T> getEmptyKey() { | |||
return AssertingVH<T>(PointerInfo::getEmptyKey()); | return AssertingVH<T>(PointerInfo::getEmptyKey()); | |||
} | } | |||
static inline T* getTombstoneKey() { | static inline T* getTombstoneKey() { | |||
return AssertingVH<T>(PointerInfo::getTombstoneKey()); | return AssertingVH<T>(PointerInfo::getTombstoneKey()); | |||
} | } | |||
skipping to change at line 347 | skipping to change at line 334 | |||
} | } | |||
ValueTy *operator=(const TrackingVH<ValueTy> &RHS) { | ValueTy *operator=(const TrackingVH<ValueTy> &RHS) { | |||
setValPtr(RHS.getValPtr()); | setValPtr(RHS.getValPtr()); | |||
return getValPtr(); | return getValPtr(); | |||
} | } | |||
ValueTy *operator->() const { return getValPtr(); } | ValueTy *operator->() const { return getValPtr(); } | |||
ValueTy &operator*() const { return *getValPtr(); } | ValueTy &operator*() const { return *getValPtr(); } | |||
}; | }; | |||
// Specialize simplify_type to allow TrackingVH to participate in | ||||
// dyn_cast, isa, etc. | ||||
template<typename From> struct simplify_type; | ||||
template<> struct simplify_type<const TrackingVH<Value> > { | ||||
typedef Value* SimpleType; | ||||
static SimpleType getSimplifiedValue(const TrackingVH<Value> &AVH) { | ||||
return static_cast<Value *>(AVH); | ||||
} | ||||
}; | ||||
template<> struct simplify_type<TrackingVH<Value> > | ||||
: public simplify_type<const TrackingVH<Value> > {}; | ||||
/// CallbackVH - This is a value handle that allows subclasses to define | /// CallbackVH - This is a value handle that allows subclasses to define | |||
/// callbacks that run when the underlying Value has RAUW called on it or i s | /// callbacks that run when the underlying Value has RAUW called on it or i s | |||
/// destroyed. This class can be used as the key of a map, as long as the user | /// destroyed. This class can be used as the key of a map, as long as the user | |||
/// takes it out of the map before calling setValPtr() (since the map has t o | /// takes it out of the map before calling setValPtr() (since the map has t o | |||
/// rearrange itself when the pointer changes). Unlike ValueHandleBase, th is | /// rearrange itself when the pointer changes). Unlike ValueHandleBase, th is | |||
/// class has a vtable and a virtual destructor. | /// class has a vtable and a virtual destructor. | |||
class CallbackVH : public ValueHandleBase { | class CallbackVH : public ValueHandleBase { | |||
protected: | protected: | |||
CallbackVH(const CallbackVH &RHS) | CallbackVH(const CallbackVH &RHS) | |||
: ValueHandleBase(Callback, RHS) {} | : ValueHandleBase(Callback, RHS) {} | |||
skipping to change at line 401 | skipping to change at line 376 | |||
/// Value that's being destroyed. | /// Value that's being destroyed. | |||
virtual void deleted(); | virtual void deleted(); | |||
/// Called when this->getValPtr()->replaceAllUsesWith(new_value) is calle d, | /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is calle d, | |||
/// _before_ any of the uses have actually been replaced. If WeakVH were | /// _before_ any of the uses have actually been replaced. If WeakVH were | |||
/// implemented as a CallbackVH, it would use this method to call | /// implemented as a CallbackVH, it would use this method to call | |||
/// setValPtr(new_value). AssertingVH would do nothing in this method. | /// setValPtr(new_value). AssertingVH would do nothing in this method. | |||
virtual void allUsesReplacedWith(Value *); | virtual void allUsesReplacedWith(Value *); | |||
}; | }; | |||
// Specialize simplify_type to allow CallbackVH to participate in | ||||
// dyn_cast, isa, etc. | ||||
template<typename From> struct simplify_type; | ||||
template<> struct simplify_type<const CallbackVH> { | ||||
typedef Value* SimpleType; | ||||
static SimpleType getSimplifiedValue(const CallbackVH &CVH) { | ||||
return static_cast<Value *>(CVH); | ||||
} | ||||
}; | ||||
template<> struct simplify_type<CallbackVH> | ||||
: public simplify_type<const CallbackVH> {}; | ||||
} // End llvm namespace | } // End llvm namespace | |||
#endif | #endif | |||
End of changes. 8 change blocks. | ||||
42 lines changed or deleted | 5 lines changed or added | |||
ValueMap.h | ValueMap.h | |||
---|---|---|---|---|
skipping to change at line 30 | skipping to change at line 30 | |||
// parameters should inherit from ValueMapConfig<KeyT> to get default | // parameters should inherit from ValueMapConfig<KeyT> to get default | |||
// implementations of all the methods ValueMap uses. See ValueMapConfig fo r | // implementations of all the methods ValueMap uses. See ValueMapConfig fo r | |||
// documentation of the functions you can override. | // documentation of the functions you can override. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_VALUEMAP_H | #ifndef LLVM_ADT_VALUEMAP_H | |||
#define LLVM_ADT_VALUEMAP_H | #define LLVM_ADT_VALUEMAP_H | |||
#include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | |||
#include "llvm/Support/Mutex.h" | ||||
#include "llvm/Support/ValueHandle.h" | #include "llvm/Support/ValueHandle.h" | |||
#include "llvm/Support/type_traits.h" | #include "llvm/Support/type_traits.h" | |||
#include "llvm/Support/Mutex.h" | ||||
#include <iterator> | #include <iterator> | |||
namespace llvm { | namespace llvm { | |||
template<typename KeyT, typename ValueT, typename Config> | template<typename KeyT, typename ValueT, typename Config> | |||
class ValueMapCallbackVH; | class ValueMapCallbackVH; | |||
template<typename DenseMapT, typename KeyT> | template<typename DenseMapT, typename KeyT> | |||
class ValueMapIterator; | class ValueMapIterator; | |||
template<typename DenseMapT, typename KeyT> | template<typename DenseMapT, typename KeyT> | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 1 lines changed or added | |||
ValueSymbolTable.h | ValueSymbolTable.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements the name/Value symbol table for LLVM. | // This file implements the name/Value symbol table for LLVM. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_VALUE_SYMBOL_TABLE_H | #ifndef LLVM_IR_VALUESYMBOLTABLE_H | |||
#define LLVM_VALUE_SYMBOL_TABLE_H | #define LLVM_IR_VALUESYMBOLTABLE_H | |||
#include "llvm/Value.h" | ||||
#include "llvm/ADT/StringMap.h" | #include "llvm/ADT/StringMap.h" | |||
#include "llvm/IR/Value.h" | ||||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
namespace llvm { | namespace llvm { | |||
template<typename ValueSubClass, typename ItemParentClass> | template<typename ValueSubClass, typename ItemParentClass> | |||
class SymbolTableListTraits; | class SymbolTableListTraits; | |||
class BasicBlock; | class BasicBlock; | |||
class Function; | class Function; | |||
class NamedMDNode; | class NamedMDNode; | |||
class Module; | class Module; | |||
class StringRef; | class StringRef; | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
ValueTracking.h | ValueTracking.h | |||
---|---|---|---|---|
skipping to change at line 48 | skipping to change at line 48 | |||
/// for all of the elements in the vector. | /// for all of the elements in the vector. | |||
void ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne, | void ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne, | |||
const DataLayout *TD = 0, unsigned Depth = 0); | const DataLayout *TD = 0, unsigned Depth = 0); | |||
void computeMaskedBitsLoad(const MDNode &Ranges, APInt &KnownZero); | void computeMaskedBitsLoad(const MDNode &Ranges, APInt &KnownZero); | |||
/// ComputeSignBit - Determine whether the sign bit is known to be zero o r | /// ComputeSignBit - Determine whether the sign bit is known to be zero o r | |||
/// one. Convenience wrapper around ComputeMaskedBits. | /// one. Convenience wrapper around ComputeMaskedBits. | |||
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne, | void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne, | |||
const DataLayout *TD = 0, unsigned Depth = 0); | const DataLayout *TD = 0, unsigned Depth = 0); | |||
/// isPowerOfTwo - Return true if the given value is known to have exactl | /// isKnownToBeAPowerOfTwo - Return true if the given value is known to h | |||
y one | ave | |||
/// bit set when defined. For vectors return true if every element is kno | /// exactly one bit set when defined. For vectors return true if every | |||
wn to | /// element is known to be a power of two when defined. Supports values | |||
/// be a power of two when defined. Supports values with integer or poin | with | |||
ter | /// integer or pointer type and vectors of integers. If 'OrZero' is set | |||
/// type and vectors of integers. If 'OrZero' is set then returns true i | then | |||
f the | /// returns true if the given value is either a power of two or zero. | |||
/// given value is either a power of two or zero. | bool isKnownToBeAPowerOfTwo(Value *V, bool OrZero = false, unsigned Depth | |||
bool isPowerOfTwo(Value *V, const DataLayout *TD = 0, bool OrZero = false | = 0); | |||
, | ||||
unsigned Depth = 0); | ||||
/// isKnownNonZero - Return true if the given value is known to be non-ze ro | /// isKnownNonZero - Return true if the given value is known to be non-ze ro | |||
/// when defined. For vectors return true if every element is known to b e | /// when defined. For vectors return true if every element is known to b e | |||
/// non-zero when defined. Supports values with integer or pointer type and | /// non-zero when defined. Supports values with integer or pointer type and | |||
/// vectors of integers. | /// vectors of integers. | |||
bool isKnownNonZero(Value *V, const DataLayout *TD = 0, unsigned Depth = 0); | bool isKnownNonZero(Value *V, const DataLayout *TD = 0, unsigned Depth = 0); | |||
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. W e use | /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. W e use | |||
/// this predicate to simplify operations downstream. Mask is known to b e | /// this predicate to simplify operations downstream. Mask is known to b e | |||
/// zero for bits that V cannot have. | /// zero for bits that V cannot have. | |||
skipping to change at line 120 | skipping to change at line 119 | |||
/// If InsertBefore is not null, this function will duplicate (modified) | /// If InsertBefore is not null, this function will duplicate (modified) | |||
/// insertvalues when a part of a nested struct is extracted. | /// insertvalues when a part of a nested struct is extracted. | |||
Value *FindInsertedValue(Value *V, | Value *FindInsertedValue(Value *V, | |||
ArrayRef<unsigned> idx_range, | ArrayRef<unsigned> idx_range, | |||
Instruction *InsertBefore = 0); | Instruction *InsertBefore = 0); | |||
/// GetPointerBaseWithConstantOffset - Analyze the specified pointer to s ee if | /// GetPointerBaseWithConstantOffset - Analyze the specified pointer to s ee if | |||
/// it can be expressed as a base pointer plus a constant offset. Return the | /// it can be expressed as a base pointer plus a constant offset. Return the | |||
/// base and offset to the caller. | /// base and offset to the caller. | |||
Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, | Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, | |||
const DataLayout &TD); | const DataLayout *TD); | |||
static inline const Value * | static inline const Value * | |||
GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset, | GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset, | |||
const DataLayout &TD) { | const DataLayout *TD) { | |||
return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset ,TD); | return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset ,TD); | |||
} | } | |||
/// getConstantStringInfo - This function computes the length of a | /// getConstantStringInfo - This function computes the length of a | |||
/// null-terminated C string pointed to by V. If successful, it returns true | /// null-terminated C string pointed to by V. If successful, it returns true | |||
/// and returns the string in Str. If unsuccessful, it returns false. T his | /// and returns the string in Str. If unsuccessful, it returns false. T his | |||
/// does not include the trailing nul character by default. If TrimAtNul is | /// does not include the trailing nul character by default. If TrimAtNul is | |||
/// set to false, then this returns any trailing nul characters as well a s any | /// set to false, then this returns any trailing nul characters as well a s any | |||
/// other characters that come after it. | /// other characters that come after it. | |||
bool getConstantStringInfo(const Value *V, StringRef &Str, | bool getConstantStringInfo(const Value *V, StringRef &Str, | |||
skipping to change at line 186 | skipping to change at line 185 | |||
/// flow, specifically terminators and PHI nodes. | /// flow, specifically terminators and PHI nodes. | |||
/// | /// | |||
/// This method only looks at the instruction itself and its operands, so if | /// This method only looks at the instruction itself and its operands, so if | |||
/// this method returns true, it is safe to move the instruction as long as | /// this method returns true, it is safe to move the instruction as long as | |||
/// the correct dominance relationships for the operands and users hold. | /// the correct dominance relationships for the operands and users hold. | |||
/// However, this method can return true for instructions that read memor y; | /// However, this method can return true for instructions that read memor y; | |||
/// for such instructions, moving them may change the resulting value. | /// for such instructions, moving them may change the resulting value. | |||
bool isSafeToSpeculativelyExecute(const Value *V, | bool isSafeToSpeculativelyExecute(const Value *V, | |||
const DataLayout *TD = 0); | const DataLayout *TD = 0); | |||
/// isKnownNonNull - Return true if this pointer couldn't possibly be nul | ||||
l by | ||||
/// its definition. This returns true for allocas, non-extern-weak globa | ||||
ls | ||||
/// and byval arguments. | ||||
bool isKnownNonNull(const Value *V); | ||||
} // end namespace llvm | } // end namespace llvm | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
14 lines changed or deleted | 19 lines changed or added | |||
ValueTypes.h | ValueTypes.h | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
class Type; | class Type; | |||
class LLVMContext; | class LLVMContext; | |||
struct EVT; | struct EVT; | |||
/// MVT - Machine Value Type. Every type that is supported natively by s ome | /// MVT - Machine Value Type. Every type that is supported natively by s ome | |||
/// processor targeted by LLVM occurs here. This means that any legal va lue | /// processor targeted by LLVM occurs here. This means that any legal va lue | |||
/// type can be represented by a MVT. | /// type can be represented by a MVT. | |||
class MVT { | class MVT { | |||
public: | public: | |||
enum SimpleValueType { | enum SimpleValueType { | |||
// INVALID_SIMPLE_VALUE_TYPE - Simple value types less than zero are | ||||
// considered extended value types. | ||||
INVALID_SIMPLE_VALUE_TYPE = -1, | ||||
// If you change this numbering, you must change the values in | // If you change this numbering, you must change the values in | |||
// ValueTypes.td as well! | // ValueTypes.td as well! | |||
Other = 0, // This is a non-standard value | Other = 0, // This is a non-standard value | |||
i1 = 1, // This is a 1 bit integer value | i1 = 1, // This is a 1 bit integer value | |||
i8 = 2, // This is an 8 bit integer value | i8 = 2, // This is an 8 bit integer value | |||
i16 = 3, // This is a 16 bit integer value | i16 = 3, // This is a 16 bit integer value | |||
i32 = 4, // This is a 32 bit integer value | i32 = 4, // This is a 32 bit integer value | |||
i64 = 5, // This is a 64 bit integer value | i64 = 5, // This is a 64 bit integer value | |||
i128 = 6, // This is a 128 bit integer value | i128 = 6, // This is a 128 bit integer value | |||
skipping to change at line 63 | skipping to change at line 67 | |||
f128 = 11, // This is a 128 bit floating point value | f128 = 11, // This is a 128 bit floating point value | |||
ppcf128 = 12, // This is a PPC 128-bit floating point value | ppcf128 = 12, // This is a PPC 128-bit floating point value | |||
FIRST_FP_VALUETYPE = f16, | FIRST_FP_VALUETYPE = f16, | |||
LAST_FP_VALUETYPE = ppcf128, | LAST_FP_VALUETYPE = ppcf128, | |||
v2i1 = 13, // 2 x i1 | v2i1 = 13, // 2 x i1 | |||
v4i1 = 14, // 4 x i1 | v4i1 = 14, // 4 x i1 | |||
v8i1 = 15, // 8 x i1 | v8i1 = 15, // 8 x i1 | |||
v16i1 = 16, // 16 x i1 | v16i1 = 16, // 16 x i1 | |||
v2i8 = 17, // 2 x i8 | v32i1 = 17, // 32 x i1 | |||
v4i8 = 18, // 4 x i8 | v64i1 = 18, // 64 x i1 | |||
v8i8 = 19, // 8 x i8 | ||||
v16i8 = 20, // 16 x i8 | v2i8 = 19, // 2 x i8 | |||
v32i8 = 21, // 32 x i8 | v4i8 = 20, // 4 x i8 | |||
v1i16 = 22, // 1 x i16 | v8i8 = 21, // 8 x i8 | |||
v2i16 = 23, // 2 x i16 | v16i8 = 22, // 16 x i8 | |||
v4i16 = 24, // 4 x i16 | v32i8 = 23, // 32 x i8 | |||
v8i16 = 25, // 8 x i16 | v64i8 = 24, // 64 x i8 | |||
v16i16 = 26, // 16 x i16 | v1i16 = 25, // 1 x i16 | |||
v1i32 = 27, // 1 x i32 | v2i16 = 26, // 2 x i16 | |||
v2i32 = 28, // 2 x i32 | v4i16 = 27, // 4 x i16 | |||
v4i32 = 29, // 4 x i32 | v8i16 = 28, // 8 x i16 | |||
v8i32 = 30, // 8 x i32 | v16i16 = 29, // 16 x i16 | |||
v16i32 = 31, // 16 x i32 | v32i16 = 30, // 32 x i16 | |||
v1i64 = 32, // 1 x i64 | v1i32 = 31, // 1 x i32 | |||
v2i64 = 33, // 2 x i64 | v2i32 = 32, // 2 x i32 | |||
v4i64 = 34, // 4 x i64 | v4i32 = 33, // 4 x i32 | |||
v8i64 = 35, // 8 x i64 | v8i32 = 34, // 8 x i32 | |||
v16i64 = 36, // 16 x i64 | v16i32 = 35, // 16 x i32 | |||
v1i64 = 36, // 1 x i64 | ||||
v2f16 = 37, // 2 x f16 | v2i64 = 37, // 2 x i64 | |||
v2f32 = 38, // 2 x f32 | v4i64 = 38, // 4 x i64 | |||
v4f32 = 39, // 4 x f32 | v8i64 = 39, // 8 x i64 | |||
v8f32 = 40, // 8 x f32 | v16i64 = 40, // 16 x i64 | |||
v2f64 = 41, // 2 x f64 | ||||
v4f64 = 42, // 4 x f64 | ||||
FIRST_VECTOR_VALUETYPE = v2i1, | ||||
LAST_VECTOR_VALUETYPE = v4f64, | ||||
FIRST_INTEGER_VECTOR_VALUETYPE = v2i1, | FIRST_INTEGER_VECTOR_VALUETYPE = v2i1, | |||
LAST_INTEGER_VECTOR_VALUETYPE = v16i64, | LAST_INTEGER_VECTOR_VALUETYPE = v16i64, | |||
v2f16 = 41, // 2 x f16 | ||||
v2f32 = 42, // 2 x f32 | ||||
v4f32 = 43, // 4 x f32 | ||||
v8f32 = 44, // 8 x f32 | ||||
v16f32 = 45, // 16 x f32 | ||||
v2f64 = 46, // 2 x f64 | ||||
v4f64 = 47, // 4 x f64 | ||||
v8f64 = 48, // 8 x f64 | ||||
FIRST_FP_VECTOR_VALUETYPE = v2f16, | FIRST_FP_VECTOR_VALUETYPE = v2f16, | |||
LAST_FP_VECTOR_VALUETYPE = v4f64, | LAST_FP_VECTOR_VALUETYPE = v8f64, | |||
FIRST_VECTOR_VALUETYPE = v2i1, | ||||
LAST_VECTOR_VALUETYPE = v8f64, | ||||
x86mmx = 43, // This is an X86 MMX value | x86mmx = 49, // This is an X86 MMX value | |||
Glue = 44, // This glues nodes together during pre-RA sc hed | Glue = 50, // This glues nodes together during pre-RA sc hed | |||
isVoid = 45, // This has no value | isVoid = 51, // This has no value | |||
Untyped = 46, // This value takes a register, but has | Untyped = 52, // This value takes a register, but has | |||
// unspecified type. The register class | // unspecified type. The register class | |||
// will be determined by the opcode. | // will be determined by the opcode. | |||
LAST_VALUETYPE = 47, // This always remains at the end of the list . | LAST_VALUETYPE = 53, // This always remains at the end of the list . | |||
// This is the current maximum for LAST_VALUETYPE. | // This is the current maximum for LAST_VALUETYPE. | |||
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vec tors | // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vec tors | |||
// This value must be a multiple of 32. | // This value must be a multiple of 32. | |||
MAX_ALLOWED_VALUETYPE = 64, | MAX_ALLOWED_VALUETYPE = 64, | |||
// Metadata - This is MDNode or MDString. | // Metadata - This is MDNode or MDString. | |||
Metadata = 250, | Metadata = 250, | |||
// iPTRAny - An int value the size of the pointer of the current | // iPTRAny - An int value the size of the pointer of the current | |||
skipping to change at line 140 | skipping to change at line 153 | |||
// This is only for tblgen's consumption! | // This is only for tblgen's consumption! | |||
fAny = 253, | fAny = 253, | |||
// iAny - An integer or vector integer value of any bit width. This i s | // iAny - An integer or vector integer value of any bit width. This i s | |||
// used for intrinsics that have overloadings based on integer bit wi dths. | // used for intrinsics that have overloadings based on integer bit wi dths. | |||
// This is only for tblgen's consumption! | // This is only for tblgen's consumption! | |||
iAny = 254, | iAny = 254, | |||
// iPTR - An int value the size of the pointer of the current | // iPTR - An int value the size of the pointer of the current | |||
// target. This should only be used internal to tblgen! | // target. This should only be used internal to tblgen! | |||
iPTR = 255, | iPTR = 255 | |||
// LastSimpleValueType - The greatest valid SimpleValueType value. | ||||
LastSimpleValueType = 255, | ||||
// INVALID_SIMPLE_VALUE_TYPE - Simple value types greater than or equ | ||||
al | ||||
// to this are considered extended value types. | ||||
INVALID_SIMPLE_VALUE_TYPE = LastSimpleValueType + 1 | ||||
}; | }; | |||
SimpleValueType SimpleTy; | SimpleValueType SimpleTy; | |||
MVT() : SimpleTy((SimpleValueType)(INVALID_SIMPLE_VALUE_TYPE)) {} | MVT() : SimpleTy((SimpleValueType)(INVALID_SIMPLE_VALUE_TYPE)) {} | |||
MVT(SimpleValueType SVT) : SimpleTy(SVT) { } | MVT(SimpleValueType SVT) : SimpleTy(SVT) { } | |||
bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; } | bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; } | |||
bool operator<(const MVT& S) const { return SimpleTy < S.SimpleTy; } | bool operator<(const MVT& S) const { return SimpleTy < S.SimpleTy; } | |||
bool operator==(const MVT& S) const { return SimpleTy == S.SimpleTy; } | bool operator==(const MVT& S) const { return SimpleTy == S.SimpleTy; } | |||
skipping to change at line 219 | skipping to change at line 225 | |||
/// is256BitVector - Return true if this is a 256-bit vector type. | /// is256BitVector - Return true if this is a 256-bit vector type. | |||
bool is256BitVector() const { | bool is256BitVector() const { | |||
return (SimpleTy == MVT::v8f32 || SimpleTy == MVT::v4f64 || | return (SimpleTy == MVT::v8f32 || SimpleTy == MVT::v4f64 || | |||
SimpleTy == MVT::v32i8 || SimpleTy == MVT::v16i16 || | SimpleTy == MVT::v32i8 || SimpleTy == MVT::v16i16 || | |||
SimpleTy == MVT::v8i32 || SimpleTy == MVT::v4i64); | SimpleTy == MVT::v8i32 || SimpleTy == MVT::v4i64); | |||
} | } | |||
/// is512BitVector - Return true if this is a 512-bit vector type. | /// is512BitVector - Return true if this is a 512-bit vector type. | |||
bool is512BitVector() const { | bool is512BitVector() const { | |||
return (SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32); | return (SimpleTy == MVT::v8f64 || SimpleTy == MVT::v16f32 || | |||
SimpleTy == MVT::v64i8 || SimpleTy == MVT::v32i16 || | ||||
SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32); | ||||
} | } | |||
/// is1024BitVector - Return true if this is a 1024-bit vector type. | /// is1024BitVector - Return true if this is a 1024-bit vector type. | |||
bool is1024BitVector() const { | bool is1024BitVector() const { | |||
return (SimpleTy == MVT::v16i64); | return (SimpleTy == MVT::v16i64); | |||
} | } | |||
/// isPow2VectorType - Returns true if the given vector is a power of 2 . | /// isPow2VectorType - Returns true if the given vector is a power of 2 . | |||
bool isPow2VectorType() const { | bool isPow2VectorType() const { | |||
unsigned NElts = getVectorNumElements(); | unsigned NElts = getVectorNumElements(); | |||
skipping to change at line 257 | skipping to change at line 265 | |||
return isVector() ? getVectorElementType() : *this; | return isVector() ? getVectorElementType() : *this; | |||
} | } | |||
MVT getVectorElementType() const { | MVT getVectorElementType() const { | |||
switch (SimpleTy) { | switch (SimpleTy) { | |||
default: | default: | |||
llvm_unreachable("Not a vector MVT!"); | llvm_unreachable("Not a vector MVT!"); | |||
case v2i1 : | case v2i1 : | |||
case v4i1 : | case v4i1 : | |||
case v8i1 : | case v8i1 : | |||
case v16i1: return i1; | case v16i1 : | |||
case v32i1 : | ||||
case v64i1: return i1; | ||||
case v2i8 : | case v2i8 : | |||
case v4i8 : | case v4i8 : | |||
case v8i8 : | case v8i8 : | |||
case v16i8: | case v16i8: | |||
case v32i8: return i8; | case v32i8: | |||
case v64i8: return i8; | ||||
case v1i16: | case v1i16: | |||
case v2i16: | case v2i16: | |||
case v4i16: | case v4i16: | |||
case v8i16: | case v8i16: | |||
case v16i16: return i16; | case v16i16: | |||
case v32i16: return i16; | ||||
case v1i32: | case v1i32: | |||
case v2i32: | case v2i32: | |||
case v4i32: | case v4i32: | |||
case v8i32: | case v8i32: | |||
case v16i32: return i32; | case v16i32: return i32; | |||
case v1i64: | case v1i64: | |||
case v2i64: | case v2i64: | |||
case v4i64: | case v4i64: | |||
case v8i64: | case v8i64: | |||
case v16i64: return i64; | case v16i64: return i64; | |||
case v2f16: return f16; | case v2f16: return f16; | |||
case v2f32: | case v2f32: | |||
case v4f32: | case v4f32: | |||
case v8f32: return f32; | case v8f32: | |||
case v16f32: return f32; | ||||
case v2f64: | case v2f64: | |||
case v4f64: return f64; | case v4f64: | |||
case v8f64: return f64; | ||||
} | } | |||
} | } | |||
unsigned getVectorNumElements() const { | unsigned getVectorNumElements() const { | |||
switch (SimpleTy) { | switch (SimpleTy) { | |||
default: | default: | |||
llvm_unreachable("Not a vector MVT!"); | llvm_unreachable("Not a vector MVT!"); | |||
case v32i8: return 32; | case v32i1: | |||
case v32i8: | ||||
case v32i16: return 32; | ||||
case v64i1: | ||||
case v64i8: return 64; | ||||
case v16i1: | case v16i1: | |||
case v16i8: | case v16i8: | |||
case v16i16: | case v16i16: | |||
case v16i32: | case v16i32: | |||
case v16i64:return 16; | case v16i64: | |||
case v8i1: | case v16f32: return 16; | |||
case v8i1 : | ||||
case v8i8 : | case v8i8 : | |||
case v8i16: | case v8i16: | |||
case v8i32: | case v8i32: | |||
case v8i64: | case v8i64: | |||
case v8f32: return 8; | case v8f32: | |||
case v8f64: return 8; | ||||
case v4i1: | case v4i1: | |||
case v4i8: | case v4i8: | |||
case v4i16: | case v4i16: | |||
case v4i32: | case v4i32: | |||
case v4i64: | case v4i64: | |||
case v4f32: | case v4f32: | |||
case v4f64: return 4; | case v4f64: return 4; | |||
case v2i1: | case v2i1: | |||
case v2i8: | case v2i8: | |||
case v2i16: | case v2i16: | |||
skipping to change at line 331 | skipping to change at line 351 | |||
} | } | |||
} | } | |||
unsigned getSizeInBits() const { | unsigned getSizeInBits() const { | |||
switch (SimpleTy) { | switch (SimpleTy) { | |||
case iPTR: | case iPTR: | |||
llvm_unreachable("Value type size is target-dependent. Ask TLI."); | llvm_unreachable("Value type size is target-dependent. Ask TLI."); | |||
case iPTRAny: | case iPTRAny: | |||
case iAny: | case iAny: | |||
case fAny: | case fAny: | |||
case vAny: | ||||
llvm_unreachable("Value type is overloaded."); | llvm_unreachable("Value type is overloaded."); | |||
case Metadata: | ||||
llvm_unreachable("Value type is metadata."); | ||||
default: | default: | |||
llvm_unreachable("getSizeInBits called on extended MVT."); | llvm_unreachable("getSizeInBits called on extended MVT."); | |||
case i1 : return 1; | case i1 : return 1; | |||
case v2i1: return 2; | case v2i1: return 2; | |||
case v4i1: return 4; | case v4i1: return 4; | |||
case i8 : | case i8 : | |||
case v8i1: return 8; | case v8i1: return 8; | |||
case i16 : | case i16 : | |||
case f16: | case f16: | |||
case v16i1: | case v16i1: | |||
case v2i8: | case v2i8: | |||
case v1i16: return 16; | case v1i16: return 16; | |||
case f32 : | case f32 : | |||
case i32 : | case i32 : | |||
case v32i1: | ||||
case v4i8: | case v4i8: | |||
case v2i16: | case v2i16: | |||
case v2f16: | case v2f16: | |||
case v1i32: return 32; | case v1i32: return 32; | |||
case x86mmx: | case x86mmx: | |||
case f64 : | case f64 : | |||
case i64 : | case i64 : | |||
case v64i1: | ||||
case v8i8: | case v8i8: | |||
case v4i16: | case v4i16: | |||
case v2i32: | case v2i32: | |||
case v1i64: | case v1i64: | |||
case v2f32: return 64; | case v2f32: return 64; | |||
case f80 : return 80; | case f80 : return 80; | |||
case f128: | case f128: | |||
case ppcf128: | case ppcf128: | |||
case i128: | case i128: | |||
case v16i8: | case v16i8: | |||
skipping to change at line 374 | skipping to change at line 399 | |||
case v4i32: | case v4i32: | |||
case v2i64: | case v2i64: | |||
case v4f32: | case v4f32: | |||
case v2f64: return 128; | case v2f64: return 128; | |||
case v32i8: | case v32i8: | |||
case v16i16: | case v16i16: | |||
case v8i32: | case v8i32: | |||
case v4i64: | case v4i64: | |||
case v8f32: | case v8f32: | |||
case v4f64: return 256; | case v4f64: return 256; | |||
case v64i8: | ||||
case v32i16: | ||||
case v16i32: | case v16i32: | |||
case v8i64: return 512; | case v8i64: | |||
case v16f32: | ||||
case v8f64: return 512; | ||||
case v16i64:return 1024; | case v16i64:return 1024; | |||
} | } | |||
} | } | |||
/// getStoreSize - Return the number of bytes overwritten by a store | /// getStoreSize - Return the number of bytes overwritten by a store | |||
/// of the specified value type. | /// of the specified value type. | |||
unsigned getStoreSize() const { | unsigned getStoreSize() const { | |||
return (getSizeInBits() + 7) / 8; | return (getSizeInBits() + 7) / 8; | |||
} | } | |||
/// getStoreSizeInBits - Return the number of bits overwritten by a sto re | /// getStoreSizeInBits - Return the number of bits overwritten by a sto re | |||
/// of the specified value type. | /// of the specified value type. | |||
unsigned getStoreSizeInBits() const { | unsigned getStoreSizeInBits() const { | |||
return getStoreSize() * 8; | return getStoreSize() * 8; | |||
} | } | |||
/// Return true if this has more bits than VT. | ||||
bool bitsGT(MVT VT) const { | ||||
return getSizeInBits() > VT.getSizeInBits(); | ||||
} | ||||
/// Return true if this has no less bits than VT. | ||||
bool bitsGE(MVT VT) const { | ||||
return getSizeInBits() >= VT.getSizeInBits(); | ||||
} | ||||
/// Return true if this has less bits than VT. | ||||
bool bitsLT(MVT VT) const { | ||||
return getSizeInBits() < VT.getSizeInBits(); | ||||
} | ||||
/// Return true if this has no more bits than VT. | ||||
bool bitsLE(MVT VT) const { | ||||
return getSizeInBits() <= VT.getSizeInBits(); | ||||
} | ||||
static MVT getFloatingPointVT(unsigned BitWidth) { | static MVT getFloatingPointVT(unsigned BitWidth) { | |||
switch (BitWidth) { | switch (BitWidth) { | |||
default: | default: | |||
llvm_unreachable("Bad bit width!"); | llvm_unreachable("Bad bit width!"); | |||
case 16: | case 16: | |||
return MVT::f16; | return MVT::f16; | |||
case 32: | case 32: | |||
return MVT::f32; | return MVT::f32; | |||
case 64: | case 64: | |||
return MVT::f64; | return MVT::f64; | |||
skipping to change at line 437 | skipping to change at line 486 | |||
static MVT getVectorVT(MVT VT, unsigned NumElements) { | static MVT getVectorVT(MVT VT, unsigned NumElements) { | |||
switch (VT.SimpleTy) { | switch (VT.SimpleTy) { | |||
default: | default: | |||
break; | break; | |||
case MVT::i1: | case MVT::i1: | |||
if (NumElements == 2) return MVT::v2i1; | if (NumElements == 2) return MVT::v2i1; | |||
if (NumElements == 4) return MVT::v4i1; | if (NumElements == 4) return MVT::v4i1; | |||
if (NumElements == 8) return MVT::v8i1; | if (NumElements == 8) return MVT::v8i1; | |||
if (NumElements == 16) return MVT::v16i1; | if (NumElements == 16) return MVT::v16i1; | |||
if (NumElements == 32) return MVT::v32i1; | ||||
if (NumElements == 64) return MVT::v64i1; | ||||
break; | break; | |||
case MVT::i8: | case MVT::i8: | |||
if (NumElements == 2) return MVT::v2i8; | if (NumElements == 2) return MVT::v2i8; | |||
if (NumElements == 4) return MVT::v4i8; | if (NumElements == 4) return MVT::v4i8; | |||
if (NumElements == 8) return MVT::v8i8; | if (NumElements == 8) return MVT::v8i8; | |||
if (NumElements == 16) return MVT::v16i8; | if (NumElements == 16) return MVT::v16i8; | |||
if (NumElements == 32) return MVT::v32i8; | if (NumElements == 32) return MVT::v32i8; | |||
if (NumElements == 64) return MVT::v64i8; | ||||
break; | break; | |||
case MVT::i16: | case MVT::i16: | |||
if (NumElements == 1) return MVT::v1i16; | if (NumElements == 1) return MVT::v1i16; | |||
if (NumElements == 2) return MVT::v2i16; | if (NumElements == 2) return MVT::v2i16; | |||
if (NumElements == 4) return MVT::v4i16; | if (NumElements == 4) return MVT::v4i16; | |||
if (NumElements == 8) return MVT::v8i16; | if (NumElements == 8) return MVT::v8i16; | |||
if (NumElements == 16) return MVT::v16i16; | if (NumElements == 16) return MVT::v16i16; | |||
if (NumElements == 32) return MVT::v32i16; | ||||
break; | break; | |||
case MVT::i32: | case MVT::i32: | |||
if (NumElements == 1) return MVT::v1i32; | if (NumElements == 1) return MVT::v1i32; | |||
if (NumElements == 2) return MVT::v2i32; | if (NumElements == 2) return MVT::v2i32; | |||
if (NumElements == 4) return MVT::v4i32; | if (NumElements == 4) return MVT::v4i32; | |||
if (NumElements == 8) return MVT::v8i32; | if (NumElements == 8) return MVT::v8i32; | |||
if (NumElements == 16) return MVT::v16i32; | if (NumElements == 16) return MVT::v16i32; | |||
break; | break; | |||
case MVT::i64: | case MVT::i64: | |||
if (NumElements == 1) return MVT::v1i64; | if (NumElements == 1) return MVT::v1i64; | |||
skipping to change at line 473 | skipping to change at line 526 | |||
if (NumElements == 8) return MVT::v8i64; | if (NumElements == 8) return MVT::v8i64; | |||
if (NumElements == 16) return MVT::v16i64; | if (NumElements == 16) return MVT::v16i64; | |||
break; | break; | |||
case MVT::f16: | case MVT::f16: | |||
if (NumElements == 2) return MVT::v2f16; | if (NumElements == 2) return MVT::v2f16; | |||
break; | break; | |||
case MVT::f32: | case MVT::f32: | |||
if (NumElements == 2) return MVT::v2f32; | if (NumElements == 2) return MVT::v2f32; | |||
if (NumElements == 4) return MVT::v4f32; | if (NumElements == 4) return MVT::v4f32; | |||
if (NumElements == 8) return MVT::v8f32; | if (NumElements == 8) return MVT::v8f32; | |||
if (NumElements == 16) return MVT::v16f32; | ||||
break; | break; | |||
case MVT::f64: | case MVT::f64: | |||
if (NumElements == 2) return MVT::v2f64; | if (NumElements == 2) return MVT::v2f64; | |||
if (NumElements == 4) return MVT::v4f64; | if (NumElements == 4) return MVT::v4f64; | |||
if (NumElements == 8) return MVT::v8f64; | ||||
break; | break; | |||
} | } | |||
return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE); | return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE); | |||
} | } | |||
/// Return the value type corresponding to the specified type. This re | ||||
turns | ||||
/// all pointers as iPTR. If HandleUnknown is true, unknown types are | ||||
/// returned as Other, otherwise they are invalid. | ||||
static MVT getVT(Type *Ty, bool HandleUnknown = false); | ||||
}; | }; | |||
/// EVT - Extended Value Type. Capable of holding value types which are not | /// EVT - Extended Value Type. Capable of holding value types which are not | |||
/// native for any processor (such as the i12345 type), as well as the ty pes | /// native for any processor (such as the i12345 type), as well as the ty pes | |||
/// a MVT can represent. | /// a MVT can represent. | |||
struct EVT { | struct EVT { | |||
private: | private: | |||
MVT V; | MVT V; | |||
Type *LLVMTy; | Type *LLVMTy; | |||
skipping to change at line 503 | skipping to change at line 564 | |||
LLVMTy(0) {} | LLVMTy(0) {} | |||
EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(0) { } | EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(0) { } | |||
EVT(MVT S) : V(S), LLVMTy(0) {} | EVT(MVT S) : V(S), LLVMTy(0) {} | |||
bool operator==(EVT VT) const { | bool operator==(EVT VT) const { | |||
return !(*this != VT); | return !(*this != VT); | |||
} | } | |||
bool operator!=(EVT VT) const { | bool operator!=(EVT VT) const { | |||
if (V.SimpleTy != VT.V.SimpleTy) | if (V.SimpleTy != VT.V.SimpleTy) | |||
return true; | return true; | |||
if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) | if (V.SimpleTy < 0) | |||
return LLVMTy != VT.LLVMTy; | return LLVMTy != VT.LLVMTy; | |||
return false; | return false; | |||
} | } | |||
/// getFloatingPointVT - Returns the EVT that represents a floating poi nt | /// getFloatingPointVT - Returns the EVT that represents a floating poi nt | |||
/// type with the given number of bits. There are two floating point t ypes | /// type with the given number of bits. There are two floating point t ypes | |||
/// with 128 bits - this returns f128 rather than ppcf128. | /// with 128 bits - this returns f128 rather than ppcf128. | |||
static EVT getFloatingPointVT(unsigned BitWidth) { | static EVT getFloatingPointVT(unsigned BitWidth) { | |||
return MVT::getFloatingPointVT(BitWidth); | return MVT::getFloatingPointVT(BitWidth); | |||
} | } | |||
/// getIntegerVT - Returns the EVT that represents an integer with the given | /// getIntegerVT - Returns the EVT that represents an integer with the given | |||
/// number of bits. | /// number of bits. | |||
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) { | static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) { | |||
MVT M = MVT::getIntegerVT(BitWidth); | MVT M = MVT::getIntegerVT(BitWidth); | |||
if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) | if (M.SimpleTy >= 0) | |||
return M; | return M; | |||
return getExtendedIntegerVT(Context, BitWidth); | return getExtendedIntegerVT(Context, BitWidth); | |||
} | } | |||
/// getVectorVT - Returns the EVT that represents a vector NumElements in | /// getVectorVT - Returns the EVT that represents a vector NumElements in | |||
/// length, where each element is of type VT. | /// length, where each element is of type VT. | |||
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElemen ts) { | static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElemen ts) { | |||
MVT M = MVT::getVectorVT(VT.V, NumElements); | MVT M = MVT::getVectorVT(VT.V, NumElements); | |||
if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) | if (M.SimpleTy >= 0) | |||
return M; | return M; | |||
return getExtendedVectorVT(Context, VT, NumElements); | return getExtendedVectorVT(Context, VT, NumElements); | |||
} | } | |||
/// changeVectorElementTypeToInteger - Return a vector with the same nu mber | /// changeVectorElementTypeToInteger - Return a vector with the same nu mber | |||
/// of elements as this vector, but with the element type converted to an | /// of elements as this vector, but with the element type converted to an | |||
/// integer type with the same bitwidth. | /// integer type with the same bitwidth. | |||
EVT changeVectorElementTypeToInteger() const { | EVT changeVectorElementTypeToInteger() const { | |||
if (!isSimple()) | if (!isSimple()) | |||
return changeExtendedVectorElementTypeToInteger(); | return changeExtendedVectorElementTypeToInteger(); | |||
MVT EltTy = getSimpleVT().getVectorElementType(); | MVT EltTy = getSimpleVT().getVectorElementType(); | |||
unsigned BitWidth = EltTy.getSizeInBits(); | unsigned BitWidth = EltTy.getSizeInBits(); | |||
MVT IntTy = MVT::getIntegerVT(BitWidth); | MVT IntTy = MVT::getIntegerVT(BitWidth); | |||
MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements()); | MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements()); | |||
assert(VecTy != MVT::INVALID_SIMPLE_VALUE_TYPE && | assert(VecTy.SimpleTy >= 0 && | |||
"Simple vector VT not representable by simple integer vector V T!"); | "Simple vector VT not representable by simple integer vector V T!"); | |||
return VecTy; | return VecTy; | |||
} | } | |||
/// isSimple - Test if the given EVT is simple (as opposed to being | /// isSimple - Test if the given EVT is simple (as opposed to being | |||
/// extended). | /// extended). | |||
bool isSimple() const { | bool isSimple() const { | |||
return V.SimpleTy <= MVT::LastSimpleValueType; | return V.SimpleTy >= 0; | |||
} | } | |||
/// isExtended - Test if the given EVT is extended (as opposed to | /// isExtended - Test if the given EVT is extended (as opposed to | |||
/// being simple). | /// being simple). | |||
bool isExtended() const { | bool isExtended() const { | |||
return !isSimple(); | return !isSimple(); | |||
} | } | |||
/// isFloatingPoint - Return true if this is a FP, or a vector FP type. | /// isFloatingPoint - Return true if this is a FP, or a vector FP type. | |||
bool isFloatingPoint() const { | bool isFloatingPoint() const { | |||
skipping to change at line 766 | skipping to change at line 827 | |||
/// getTypeForEVT - This method returns an LLVM type corresponding to t he | /// getTypeForEVT - This method returns an LLVM type corresponding to t he | |||
/// specified EVT. For integer types, this returns an unsigned type. Note | /// specified EVT. For integer types, this returns an unsigned type. Note | |||
/// that this will abort for types that cannot be represented. | /// that this will abort for types that cannot be represented. | |||
Type *getTypeForEVT(LLVMContext &Context) const; | Type *getTypeForEVT(LLVMContext &Context) const; | |||
/// getEVT - Return the value type corresponding to the specified type. | /// getEVT - Return the value type corresponding to the specified type. | |||
/// This returns all pointers as iPTR. If HandleUnknown is true, unkno wn | /// This returns all pointers as iPTR. If HandleUnknown is true, unkno wn | |||
/// types are returned as Other, otherwise they are invalid. | /// types are returned as Other, otherwise they are invalid. | |||
static EVT getEVT(Type *Ty, bool HandleUnknown = false); | static EVT getEVT(Type *Ty, bool HandleUnknown = false); | |||
intptr_t getRawBits() { | intptr_t getRawBits() const { | |||
if (isSimple()) | if (isSimple()) | |||
return V.SimpleTy; | return V.SimpleTy; | |||
else | else | |||
return (intptr_t)(LLVMTy); | return (intptr_t)(LLVMTy); | |||
} | } | |||
/// compareRawBits - A meaningless but well-behaved order, useful for | /// compareRawBits - A meaningless but well-behaved order, useful for | |||
/// constructing containers. | /// constructing containers. | |||
struct compareRawBits { | struct compareRawBits { | |||
bool operator()(EVT L, EVT R) const { | bool operator()(EVT L, EVT R) const { | |||
End of changes. 39 change blocks. | ||||
61 lines changed or deleted | 122 lines changed or added | |||
ValueTypes.td | ValueTypes.td | |||
---|---|---|---|---|
skipping to change at line 40 | skipping to change at line 40 | |||
def f32 : ValueType<32 , 8>; // 32-bit floating point value | def f32 : ValueType<32 , 8>; // 32-bit floating point value | |||
def f64 : ValueType<64 , 9>; // 64-bit floating point value | def f64 : ValueType<64 , 9>; // 64-bit floating point value | |||
def f80 : ValueType<80 , 10>; // 80-bit floating point value | def f80 : ValueType<80 , 10>; // 80-bit floating point value | |||
def f128 : ValueType<128, 11>; // 128-bit floating point value | def f128 : ValueType<128, 11>; // 128-bit floating point value | |||
def ppcf128: ValueType<128, 12>; // PPC 128-bit floating point value | def ppcf128: ValueType<128, 12>; // PPC 128-bit floating point value | |||
def v2i1 : ValueType<2 , 13>; // 2 x i1 vector value | def v2i1 : ValueType<2 , 13>; // 2 x i1 vector value | |||
def v4i1 : ValueType<4 , 14>; // 4 x i1 vector value | def v4i1 : ValueType<4 , 14>; // 4 x i1 vector value | |||
def v8i1 : ValueType<8 , 15>; // 8 x i1 vector value | def v8i1 : ValueType<8 , 15>; // 8 x i1 vector value | |||
def v16i1 : ValueType<16, 16>; // 16 x i1 vector value | def v16i1 : ValueType<16, 16>; // 16 x i1 vector value | |||
def v2i8 : ValueType<16 , 17>; // 2 x i8 vector value | def v32i1 : ValueType<32 , 17>; // 32 x i1 vector value | |||
def v4i8 : ValueType<32 , 18>; // 4 x i8 vector value | def v64i1 : ValueType<64 , 18>; // 64 x i1 vector value | |||
def v8i8 : ValueType<64 , 19>; // 8 x i8 vector value | def v2i8 : ValueType<16 , 19>; // 2 x i8 vector value | |||
def v16i8 : ValueType<128, 20>; // 16 x i8 vector value | def v4i8 : ValueType<32 , 20>; // 4 x i8 vector value | |||
def v32i8 : ValueType<256, 21>; // 32 x i8 vector value | def v8i8 : ValueType<64 , 21>; // 8 x i8 vector value | |||
def v1i16 : ValueType<16 , 22>; // 1 x i16 vector value | def v16i8 : ValueType<128, 22>; // 16 x i8 vector value | |||
def v2i16 : ValueType<32 , 23>; // 2 x i16 vector value | def v32i8 : ValueType<256, 23>; // 32 x i8 vector value | |||
def v4i16 : ValueType<64 , 24>; // 4 x i16 vector value | def v64i8 : ValueType<512, 24>; // 64 x i8 vector value | |||
def v8i16 : ValueType<128, 25>; // 8 x i16 vector value | def v1i16 : ValueType<16 , 25>; // 1 x i16 vector value | |||
def v16i16 : ValueType<256, 26>; // 16 x i16 vector value | def v2i16 : ValueType<32 , 26>; // 2 x i16 vector value | |||
def v1i32 : ValueType<32 , 27>; // 1 x i32 vector value | def v4i16 : ValueType<64 , 27>; // 4 x i16 vector value | |||
def v2i32 : ValueType<64 , 28>; // 2 x i32 vector value | def v8i16 : ValueType<128, 28>; // 8 x i16 vector value | |||
def v4i32 : ValueType<128, 29>; // 4 x i32 vector value | def v16i16 : ValueType<256, 29>; // 16 x i16 vector value | |||
def v8i32 : ValueType<256, 30>; // 8 x i32 vector value | def v32i16 : ValueType<512, 30>; // 32 x i16 vector value | |||
def v16i32 : ValueType<512, 31>; // 16 x i32 vector value | def v1i32 : ValueType<32 , 31>; // 1 x i32 vector value | |||
def v1i64 : ValueType<64 , 32>; // 1 x i64 vector value | def v2i32 : ValueType<64 , 32>; // 2 x i32 vector value | |||
def v2i64 : ValueType<128, 33>; // 2 x i64 vector value | def v4i32 : ValueType<128, 33>; // 4 x i32 vector value | |||
def v4i64 : ValueType<256, 34>; // 4 x i64 vector value | def v8i32 : ValueType<256, 34>; // 8 x i32 vector value | |||
def v8i64 : ValueType<512, 35>; // 8 x i64 vector value | def v16i32 : ValueType<512, 35>; // 16 x i32 vector value | |||
def v16i64 : ValueType<1024,36>; // 16 x i64 vector value | def v1i64 : ValueType<64 , 36>; // 1 x i64 vector value | |||
def v2i64 : ValueType<128, 37>; // 2 x i64 vector value | ||||
def v2f16 : ValueType<32 , 37>; // 2 x f16 vector value | def v4i64 : ValueType<256, 38>; // 4 x i64 vector value | |||
def v2f32 : ValueType<64 , 38>; // 2 x f32 vector value | def v8i64 : ValueType<512, 39>; // 8 x i64 vector value | |||
def v4f32 : ValueType<128, 39>; // 4 x f32 vector value | def v16i64 : ValueType<1024,40>; // 16 x i64 vector value | |||
def v8f32 : ValueType<256, 40>; // 8 x f32 vector value | ||||
def v2f64 : ValueType<128, 41>; // 2 x f64 vector value | def v2f16 : ValueType<32 , 41>; // 2 x f16 vector value | |||
def v4f64 : ValueType<256, 42>; // 4 x f64 vector value | def v2f32 : ValueType<64 , 42>; // 2 x f32 vector value | |||
def v4f32 : ValueType<128, 43>; // 4 x f32 vector value | ||||
def x86mmx : ValueType<64 , 43>; // X86 MMX value | def v8f32 : ValueType<256, 44>; // 8 x f32 vector value | |||
def FlagVT : ValueType<0 , 44>; // Pre-RA sched glue | def v16f32 : ValueType<512, 45>; // 16 x f32 vector value | |||
def isVoid : ValueType<0 , 45>; // Produces no value | def v2f64 : ValueType<128, 46>; // 2 x f64 vector value | |||
def untyped: ValueType<8 , 46>; // Produces an untyped value | def v4f64 : ValueType<256, 47>; // 4 x f64 vector value | |||
def v8f64 : ValueType<512, 48>; // 8 x f64 vector value | ||||
def x86mmx : ValueType<64 , 49>; // X86 MMX value | ||||
def FlagVT : ValueType<0 , 50>; // Pre-RA sched glue | ||||
def isVoid : ValueType<0 , 51>; // Produces no value | ||||
def untyped: ValueType<8 , 52>; // Produces an untyped value | ||||
def MetadataVT: ValueType<0, 250>; // Metadata | def MetadataVT: ValueType<0, 250>; // Metadata | |||
// Pseudo valuetype mapped to the current pointer size to any address space . | // Pseudo valuetype mapped to the current pointer size to any address space . | |||
// Should only be used in TableGen. | // Should only be used in TableGen. | |||
def iPTRAny : ValueType<0, 251>; | def iPTRAny : ValueType<0, 251>; | |||
// Pseudo valuetype to represent "vector of any size" | // Pseudo valuetype to represent "vector of any size" | |||
def vAny : ValueType<0 , 252>; | def vAny : ValueType<0 , 252>; | |||
// Pseudo valuetype to represent "float of any format" | // Pseudo valuetype to represent "float of any format" | |||
End of changes. 1 change blocks. | ||||
33 lines changed or deleted | 38 lines changed or added | |||
VariadicFunction.h | VariadicFunction.h | |||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
// | // | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file implements compile-time type-safe variadic functions. | // This file implements compile-time type-safe variadic functions. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_VARIADIC_FUNCTION_H | #ifndef LLVM_ADT_VARIADICFUNCTION_H | |||
#define LLVM_ADT_VARIADIC_FUNCTION_H | #define LLVM_ADT_VARIADICFUNCTION_H | |||
#include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | |||
namespace llvm { | namespace llvm { | |||
// Define macros to aid in expanding a comma separated series with the inde x of | // Define macros to aid in expanding a comma separated series with the inde x of | |||
// the series pasted onto the last token. | // the series pasted onto the last token. | |||
#define LLVM_COMMA_JOIN1(x) x ## 0 | #define LLVM_COMMA_JOIN1(x) x ## 0 | |||
#define LLVM_COMMA_JOIN2(x) LLVM_COMMA_JOIN1(x), x ## 1 | #define LLVM_COMMA_JOIN2(x) LLVM_COMMA_JOIN1(x), x ## 1 | |||
#define LLVM_COMMA_JOIN3(x) LLVM_COMMA_JOIN2(x), x ## 2 | #define LLVM_COMMA_JOIN3(x) LLVM_COMMA_JOIN2(x), x ## 2 | |||
skipping to change at line 331 | skipping to change at line 331 | |||
#undef LLVM_COMMA_JOIN26 | #undef LLVM_COMMA_JOIN26 | |||
#undef LLVM_COMMA_JOIN27 | #undef LLVM_COMMA_JOIN27 | |||
#undef LLVM_COMMA_JOIN28 | #undef LLVM_COMMA_JOIN28 | |||
#undef LLVM_COMMA_JOIN29 | #undef LLVM_COMMA_JOIN29 | |||
#undef LLVM_COMMA_JOIN30 | #undef LLVM_COMMA_JOIN30 | |||
#undef LLVM_COMMA_JOIN31 | #undef LLVM_COMMA_JOIN31 | |||
#undef LLVM_COMMA_JOIN32 | #undef LLVM_COMMA_JOIN32 | |||
} // end namespace llvm | } // end namespace llvm | |||
#endif // LLVM_ADT_VARIADIC_FUNCTION_H | #endif // LLVM_ADT_VARIADICFUNCTION_H | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
Vectorize.h | Vectorize.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
// in the Vectorize transformations library. | // in the Vectorize transformations library. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_TRANSFORMS_VECTORIZE_H | #ifndef LLVM_TRANSFORMS_VECTORIZE_H | |||
#define LLVM_TRANSFORMS_VECTORIZE_H | #define LLVM_TRANSFORMS_VECTORIZE_H | |||
namespace llvm { | namespace llvm { | |||
class BasicBlock; | class BasicBlock; | |||
class BasicBlockPass; | class BasicBlockPass; | |||
class Pass; | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// @brief Vectorize configuration. | /// @brief Vectorize configuration. | |||
struct VectorizeConfig { | struct VectorizeConfig { | |||
//===-------------------------------------------------------------------- ===// | //===-------------------------------------------------------------------- ===// | |||
// Target architecture related parameters | // Target architecture related parameters | |||
/// @brief The size of the native vector registers. | /// @brief The size of the native vector registers. | |||
unsigned VectorBits; | unsigned VectorBits; | |||
skipping to change at line 86 | skipping to change at line 87 | |||
/// @brief The maximum number of candidate pairs with which to use a full | /// @brief The maximum number of candidate pairs with which to use a full | |||
/// cycle check. | /// cycle check. | |||
unsigned MaxCandPairsForCycleCheck; | unsigned MaxCandPairsForCycleCheck; | |||
/// @brief Replicating one element to a pair breaks the chain. | /// @brief Replicating one element to a pair breaks the chain. | |||
bool SplatBreaksChain; | bool SplatBreaksChain; | |||
/// @brief The maximum number of pairable instructions per group. | /// @brief The maximum number of pairable instructions per group. | |||
unsigned MaxInsts; | unsigned MaxInsts; | |||
/// @brief The maximum number of candidate instruction pairs per group. | ||||
unsigned MaxPairs; | ||||
/// @brief The maximum number of pairing iterations. | /// @brief The maximum number of pairing iterations. | |||
unsigned MaxIter; | unsigned MaxIter; | |||
/// @brief Don't try to form odd-length vectors. | /// @brief Don't try to form odd-length vectors. | |||
bool Pow2LenOnly; | bool Pow2LenOnly; | |||
/// @brief Don't boost the chain-depth contribution of loads and stores. | /// @brief Don't boost the chain-depth contribution of loads and stores. | |||
bool NoMemOpBoost; | bool NoMemOpBoost; | |||
/// @brief Use a fast instruction dependency analysis. | /// @brief Use a fast instruction dependency analysis. | |||
skipping to change at line 113 | skipping to change at line 117 | |||
// | // | |||
// BBVectorize - A basic-block vectorization pass. | // BBVectorize - A basic-block vectorization pass. | |||
// | // | |||
BasicBlockPass * | BasicBlockPass * | |||
createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig()); | createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig()); | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// LoopVectorize - Create a loop vectorization pass. | // LoopVectorize - Create a loop vectorization pass. | |||
// | // | |||
Pass * createLoopVectorizePass(); | Pass *createLoopVectorizePass(); | |||
//===---------------------------------------------------------------------- | ||||
===// | ||||
// | ||||
// SLPVectorizer - Create a bottom-up SLP vectorizer pass. | ||||
// | ||||
Pass *createSLPVectorizerPass(); | ||||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
/// @brief Vectorize the BasicBlock. | /// @brief Vectorize the BasicBlock. | |||
/// | /// | |||
/// @param BB The BasicBlock to be vectorized | /// @param BB The BasicBlock to be vectorized | |||
/// @param P The current running pass, should require AliasAnalysis and | /// @param P The current running pass, should require AliasAnalysis and | |||
/// ScalarEvolution. After the vectorization, AliasAnalysis, | /// ScalarEvolution. After the vectorization, AliasAnalysis, | |||
/// ScalarEvolution and CFG are preserved. | /// ScalarEvolution and CFG are preserved. | |||
/// | /// | |||
/// @return True if the BB is changed, false otherwise. | /// @return True if the BB is changed, false otherwise. | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 12 lines changed or added | |||
Win64EH.h | Win64EH.h | |||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
// This file contains constants and structures used for implementing | // This file contains constants and structures used for implementing | |||
// exception handling on Win64 platforms. For more information, see | // exception handling on Win64 platforms. For more information, see | |||
// http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx | // http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_WIN64EH_H | #ifndef LLVM_SUPPORT_WIN64EH_H | |||
#define LLVM_SUPPORT_WIN64EH_H | #define LLVM_SUPPORT_WIN64EH_H | |||
#include "llvm/Support/DataTypes.h" | #include "llvm/Support/DataTypes.h" | |||
#include "llvm/Support/Endian.h" | ||||
namespace llvm { | namespace llvm { | |||
namespace Win64EH { | namespace Win64EH { | |||
/// UnwindOpcodes - Enumeration whose values specify a single operation in | /// UnwindOpcodes - Enumeration whose values specify a single operation in | |||
/// the prolog of a function. | /// the prolog of a function. | |||
enum UnwindOpcodes { | enum UnwindOpcodes { | |||
UOP_PushNonVol = 0, | UOP_PushNonVol = 0, | |||
UOP_AllocLarge, | UOP_AllocLarge, | |||
UOP_AllocSmall, | UOP_AllocSmall, | |||
skipping to change at line 42 | skipping to change at line 43 | |||
UOP_SaveNonVolBig, | UOP_SaveNonVolBig, | |||
UOP_SaveXMM128 = 8, | UOP_SaveXMM128 = 8, | |||
UOP_SaveXMM128Big, | UOP_SaveXMM128Big, | |||
UOP_PushMachFrame | UOP_PushMachFrame | |||
}; | }; | |||
/// UnwindCode - This union describes a single operation in a function prol og, | /// UnwindCode - This union describes a single operation in a function prol og, | |||
/// or part thereof. | /// or part thereof. | |||
union UnwindCode { | union UnwindCode { | |||
struct { | struct { | |||
uint8_t codeOffset; | support::ulittle8_t CodeOffset; | |||
uint8_t unwindOp:4, | support::ulittle8_t UnwindOpAndOpInfo; | |||
opInfo:4; | ||||
} u; | } u; | |||
uint16_t frameOffset; | support::ulittle16_t FrameOffset; | |||
uint8_t getUnwindOp() const { | ||||
return u.UnwindOpAndOpInfo & 0x0F; | ||||
} | ||||
uint8_t getOpInfo() const { | ||||
return (u.UnwindOpAndOpInfo >> 4) & 0x0F; | ||||
} | ||||
}; | }; | |||
enum { | enum { | |||
/// UNW_ExceptionHandler - Specifies that this function has an exception | /// UNW_ExceptionHandler - Specifies that this function has an exception | |||
/// handler. | /// handler. | |||
UNW_ExceptionHandler = 0x01, | UNW_ExceptionHandler = 0x01, | |||
/// UNW_TerminateHandler - Specifies that this function has a termination | /// UNW_TerminateHandler - Specifies that this function has a termination | |||
/// handler. | /// handler. | |||
UNW_TerminateHandler = 0x02, | UNW_TerminateHandler = 0x02, | |||
/// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained t o | /// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained t o | |||
/// another one. | /// another one. | |||
UNW_ChainInfo = 0x04 | UNW_ChainInfo = 0x04 | |||
}; | }; | |||
/// RuntimeFunction - An entry in the table of functions with unwind info. | /// RuntimeFunction - An entry in the table of functions with unwind info. | |||
struct RuntimeFunction { | struct RuntimeFunction { | |||
uint64_t startAddress; | support::ulittle32_t StartAddress; | |||
uint64_t endAddress; | support::ulittle32_t EndAddress; | |||
uint64_t unwindInfoOffset; | support::ulittle32_t UnwindInfoOffset; | |||
}; | }; | |||
/// UnwindInfo - An entry in the exception table. | /// UnwindInfo - An entry in the exception table. | |||
struct UnwindInfo { | struct UnwindInfo { | |||
uint8_t version:3, | support::ulittle8_t VersionAndFlags; | |||
flags:5; | support::ulittle8_t PrologSize; | |||
uint8_t prologSize; | support::ulittle8_t NumCodes; | |||
uint8_t numCodes; | support::ulittle8_t FrameRegisterAndOffset; | |||
uint8_t frameRegister:4, | UnwindCode UnwindCodes[1]; | |||
frameOffset:4; | ||||
UnwindCode unwindCodes[1]; | ||||
uint8_t getVersion() const { | ||||
return VersionAndFlags & 0x07; | ||||
} | ||||
uint8_t getFlags() const { | ||||
return (VersionAndFlags >> 3) & 0x1f; | ||||
} | ||||
uint8_t getFrameRegister() const { | ||||
return FrameRegisterAndOffset & 0x0f; | ||||
} | ||||
uint8_t getFrameOffset() const { | ||||
return (FrameRegisterAndOffset >> 4) & 0x0f; | ||||
} | ||||
// The data after unwindCodes depends on flags. | ||||
// If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows | ||||
// the address of the language-specific exception handler. | ||||
// If UNW_ChainInfo is set then follows a RuntimeFunction which defines | ||||
// the chained unwind info. | ||||
// For more information please see MSDN at: | ||||
// http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx | ||||
/// \brief Return pointer to language specific data part of UnwindInfo. | ||||
void *getLanguageSpecificData() { | void *getLanguageSpecificData() { | |||
return reinterpret_cast<void *>(&unwindCodes[(numCodes+1) & ~1]); | return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]); | |||
} | } | |||
uint64_t getLanguageSpecificHandlerOffset() { | ||||
return *reinterpret_cast<uint64_t *>(getLanguageSpecificData()); | /// \brief Return pointer to language specific data part of UnwindInfo. | |||
const void *getLanguageSpecificData() const { | ||||
return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes+1) & ~1]); | ||||
} | } | |||
void setLanguageSpecificHandlerOffset(uint64_t offset) { | ||||
*reinterpret_cast<uint64_t *>(getLanguageSpecificData()) = offset; | /// \brief Return image-relative offset of language-specific exception ha | |||
ndler. | ||||
uint32_t getLanguageSpecificHandlerOffset() const { | ||||
return *reinterpret_cast<const uint32_t *>(getLanguageSpecificData()); | ||||
} | } | |||
RuntimeFunction *getChainedFunctionEntry() { | ||||
return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData()); | /// \brief Set image-relative offset of language-specific exception handl | |||
er. | ||||
void setLanguageSpecificHandlerOffset(uint32_t offset) { | ||||
*reinterpret_cast<uint32_t *>(getLanguageSpecificData()) = offset; | ||||
} | } | |||
/// \brief Return pointer to exception-specific data. | ||||
void *getExceptionData() { | void *getExceptionData() { | |||
return reinterpret_cast<void *>(reinterpret_cast<uint64_t *>( | return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>( | |||
getLanguageSpecificData() )+1); | getLanguageSpecificData() )+1); | |||
} | } | |||
/// \brief Return pointer to chained unwind info. | ||||
RuntimeFunction *getChainedFunctionEntry() { | ||||
return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData()); | ||||
} | ||||
/// \brief Return pointer to chained unwind info. | ||||
const RuntimeFunction *getChainedFunctionEntry() const { | ||||
return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificDat | ||||
a()); | ||||
} | ||||
}; | }; | |||
} // End of namespace Win64EH | } // End of namespace Win64EH | |||
} // End of namespace llvm | } // End of namespace llvm | |||
#endif | #endif | |||
End of changes. 13 change blocks. | ||||
22 lines changed or deleted | 70 lines changed or added | |||
YAMLParser.h | YAMLParser.h | |||
---|---|---|---|---|
skipping to change at line 38 | skipping to change at line 38 | |||
// di != de; ++di) { | // di != de; ++di) { | |||
// yaml::Node *n = di->getRoot(); | // yaml::Node *n = di->getRoot(); | |||
// if (n) { | // if (n) { | |||
// // Do something with n... | // // Do something with n... | |||
// } else | // } else | |||
// break; | // break; | |||
// } | // } | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SUPPORT_YAML_PARSER_H | #ifndef LLVM_SUPPORT_YAMLPARSER_H | |||
#define LLVM_SUPPORT_YAML_PARSER_H | #define LLVM_SUPPORT_YAMLPARSER_H | |||
#include "llvm/ADT/OwningPtr.h" | #include "llvm/ADT/OwningPtr.h" | |||
#include "llvm/ADT/SmallString.h" | #include "llvm/ADT/SmallString.h" | |||
#include "llvm/ADT/StringRef.h" | #include "llvm/ADT/StringRef.h" | |||
#include "llvm/Support/Allocator.h" | #include "llvm/Support/Allocator.h" | |||
#include "llvm/Support/SMLoc.h" | #include "llvm/Support/SMLoc.h" | |||
#include <limits> | #include <limits> | |||
#include <utility> | #include <utility> | |||
namespace llvm { | namespace llvm { | |||
class MemoryBuffer; | class MemoryBuffer; | |||
class SourceMgr; | class SourceMgr; | |||
class raw_ostream; | class raw_ostream; | |||
class Twine; | class Twine; | |||
namespace yaml { | namespace yaml { | |||
skipping to change at line 80 | skipping to change at line 79 | |||
/// @returns true if there was an error, false otherwise. | /// @returns true if there was an error, false otherwise. | |||
bool scanTokens(StringRef Input); | bool scanTokens(StringRef Input); | |||
/// @brief Escape \a Input for a double quoted scalar. | /// @brief Escape \a Input for a double quoted scalar. | |||
std::string escape(StringRef Input); | std::string escape(StringRef Input); | |||
/// @brief This class represents a YAML stream potentially containing multi ple | /// @brief This class represents a YAML stream potentially containing multi ple | |||
/// documents. | /// documents. | |||
class Stream { | class Stream { | |||
public: | public: | |||
/// @brief This keeps a reference to the string referenced by \p Input. | ||||
Stream(StringRef Input, SourceMgr &); | Stream(StringRef Input, SourceMgr &); | |||
/// @brief This takes ownership of \p InputBuffer. | ||||
Stream(MemoryBuffer *InputBuffer, SourceMgr &); | ||||
~Stream(); | ~Stream(); | |||
document_iterator begin(); | document_iterator begin(); | |||
document_iterator end(); | document_iterator end(); | |||
void skip(); | void skip(); | |||
bool failed(); | bool failed(); | |||
bool validate() { | bool validate() { | |||
skip(); | skip(); | |||
return !failed(); | return !failed(); | |||
} | } | |||
skipping to change at line 184 | skipping to change at line 187 | |||
/// series of zero or more Unicode scalar values. | /// series of zero or more Unicode scalar values. | |||
/// | /// | |||
/// Example: | /// Example: | |||
/// Adena | /// Adena | |||
class ScalarNode : public Node { | class ScalarNode : public Node { | |||
public: | public: | |||
ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Val) | ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Val) | |||
: Node(NK_Scalar, D, Anchor) | : Node(NK_Scalar, D, Anchor) | |||
, Value(Val) { | , Value(Val) { | |||
SMLoc Start = SMLoc::getFromPointer(Val.begin()); | SMLoc Start = SMLoc::getFromPointer(Val.begin()); | |||
SMLoc End = SMLoc::getFromPointer(Val.end() - 1); | SMLoc End = SMLoc::getFromPointer(Val.end()); | |||
SourceRange = SMRange(Start, End); | SourceRange = SMRange(Start, End); | |||
} | } | |||
// Return Value without any escaping or folding or other fun YAML stuff. This | // Return Value without any escaping or folding or other fun YAML stuff. This | |||
// is the exact bytes that are contained in the file (after conversion to | // is the exact bytes that are contained in the file (after conversion to | |||
// utf8). | // utf8). | |||
StringRef getRawValue() const { return Value; } | StringRef getRawValue() const { return Value; } | |||
/// @brief Gets the value of this node as a StringRef. | /// @brief Gets the value of this node as a StringRef. | |||
/// | /// | |||
End of changes. 5 change blocks. | ||||
4 lines changed or deleted | 7 lines changed or added | |||
circular_raw_ostream.h | circular_raw_ostream.h | |||
---|---|---|---|---|
skipping to change at line 74 | skipping to change at line 74 | |||
/// | /// | |||
bool Filled; | bool Filled; | |||
/// Banner - A pointer to a banner to print before dumping the | /// Banner - A pointer to a banner to print before dumping the | |||
/// log. | /// log. | |||
/// | /// | |||
const char *Banner; | const char *Banner; | |||
/// flushBuffer - Dump the contents of the buffer to Stream. | /// flushBuffer - Dump the contents of the buffer to Stream. | |||
/// | /// | |||
void flushBuffer(void) { | void flushBuffer() { | |||
if (Filled) | if (Filled) | |||
// Write the older portion of the buffer. | // Write the older portion of the buffer. | |||
TheStream->write(Cur, BufferArray + BufferSize - Cur); | TheStream->write(Cur, BufferArray + BufferSize - Cur); | |||
// Write the newer portion of the buffer. | // Write the newer portion of the buffer. | |||
TheStream->write(BufferArray, Cur - BufferArray); | TheStream->write(BufferArray, Cur - BufferArray); | |||
Cur = BufferArray; | Cur = BufferArray; | |||
Filled = false; | Filled = false; | |||
} | } | |||
virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; | virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; | |||
skipping to change at line 154 | skipping to change at line 154 | |||
/// | /// | |||
void setStream(raw_ostream &Stream, bool Owns = REFERENCE_ONLY) { | void setStream(raw_ostream &Stream, bool Owns = REFERENCE_ONLY) { | |||
releaseStream(); | releaseStream(); | |||
TheStream = &Stream; | TheStream = &Stream; | |||
OwnsStream = Owns; | OwnsStream = Owns; | |||
} | } | |||
/// flushBufferWithBanner - Force output of the buffer along with | /// flushBufferWithBanner - Force output of the buffer along with | |||
/// a small header. | /// a small header. | |||
/// | /// | |||
void flushBufferWithBanner(void); | void flushBufferWithBanner(); | |||
private: | private: | |||
/// releaseStream - Delete the held stream if needed. Otherwise, | /// releaseStream - Delete the held stream if needed. Otherwise, | |||
/// transfer the buffer settings from this circular_raw_ostream | /// transfer the buffer settings from this circular_raw_ostream | |||
/// back to the underlying stream. | /// back to the underlying stream. | |||
/// | /// | |||
void releaseStream() { | void releaseStream() { | |||
if (!TheStream) | if (!TheStream) | |||
return; | return; | |||
if (OwnsStream) | if (OwnsStream) | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
config.h | config.h | |||
---|---|---|---|---|
skipping to change at line 76 | skipping to change at line 76 | |||
/* Define if the neat program is available */ | /* Define if the neat program is available */ | |||
#define HAVE_CIRCO 1 | #define HAVE_CIRCO 1 | |||
/* Define to 1 if you have the `closedir' function. */ | /* Define to 1 if you have the `closedir' function. */ | |||
#define HAVE_CLOSEDIR 1 | #define HAVE_CLOSEDIR 1 | |||
/* Define to 1 if you have the <CrashReporterClient.h> header file. */ | /* Define to 1 if you have the <CrashReporterClient.h> header file. */ | |||
/* #undef HAVE_CRASHREPORTERCLIENT_H */ | /* #undef HAVE_CRASHREPORTERCLIENT_H */ | |||
/* Define if __crashreporter_info__ exists. */ | /* can use __crashreporter_info__ */ | |||
#define HAVE_CRASHREPORTER_INFO 0 | #define HAVE_CRASHREPORTER_INFO 0 | |||
/* Define to 1 if you have the <ctype.h> header file. */ | /* Define to 1 if you have the <ctype.h> header file. */ | |||
#define HAVE_CTYPE_H 1 | #define HAVE_CTYPE_H 1 | |||
/* Define to 1 if you have the <cxxabi.h> header file. */ | ||||
#define HAVE_CXXABI_H 1 | ||||
/* Define to 1 if you have the declaration of `FE_ALL_EXCEPT', and to 0 if | ||||
you | ||||
don't. */ | ||||
#define HAVE_DECL_FE_ALL_EXCEPT 1 | ||||
/* Define to 1 if you have the declaration of `FE_INEXACT', and to 0 if you | ||||
don't. */ | ||||
#define HAVE_DECL_FE_INEXACT 1 | ||||
/* Define to 1 if you have the declaration of `strerror_s', and to 0 if you | /* Define to 1 if you have the declaration of `strerror_s', and to 0 if you | |||
don't. */ | don't. */ | |||
#define HAVE_DECL_STRERROR_S 0 | #define HAVE_DECL_STRERROR_S 0 | |||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR' . | /* Define to 1 if you have the <dirent.h> header file, and it defines `DIR' . | |||
*/ | */ | |||
#define HAVE_DIRENT_H 1 | #define HAVE_DIRENT_H 1 | |||
/* Define if you have the GNU dld library. */ | /* Define if you have the GNU dld library. */ | |||
/* #undef HAVE_DLD */ | /* #undef HAVE_DLD */ | |||
skipping to change at line 126 | skipping to change at line 137 | |||
/* Define to 1 if you have the <errno.h> header file. */ | /* Define to 1 if you have the <errno.h> header file. */ | |||
#define HAVE_ERRNO_H 1 | #define HAVE_ERRNO_H 1 | |||
/* Define to 1 if the system has the type `error_t'. */ | /* Define to 1 if the system has the type `error_t'. */ | |||
#define HAVE_ERROR_T 1 | #define HAVE_ERROR_T 1 | |||
/* Define to 1 if you have the <execinfo.h> header file. */ | /* Define to 1 if you have the <execinfo.h> header file. */ | |||
#define HAVE_EXECINFO_H 1 | #define HAVE_EXECINFO_H 1 | |||
/* Define to 1 if you have the `exp' function. */ | ||||
#define HAVE_EXP 1 | ||||
/* Define to 1 if you have the `exp2' function. */ | ||||
#define HAVE_EXP2 1 | ||||
/* Define to 1 if you have the <fcntl.h> header file. */ | /* Define to 1 if you have the <fcntl.h> header file. */ | |||
#define HAVE_FCNTL_H 1 | #define HAVE_FCNTL_H 1 | |||
/* Define if the neat program is available */ | /* Define if the neat program is available */ | |||
#define HAVE_FDP 1 | #define HAVE_FDP 1 | |||
/* Define to 1 if you have the <fenv.h> header file. */ | /* Define to 1 if you have the <fenv.h> header file. */ | |||
#define HAVE_FENV_H 1 | #define HAVE_FENV_H 1 | |||
/* Define if libffi is available on this platform. */ | /* Define if libffi is available on this platform. */ | |||
skipping to change at line 216 | skipping to change at line 233 | |||
/* Define to 1 if you have the `psapi' library (-lpsapi). */ | /* Define to 1 if you have the `psapi' library (-lpsapi). */ | |||
/* #undef HAVE_LIBPSAPI */ | /* #undef HAVE_LIBPSAPI */ | |||
/* Define to 1 if you have the `pthread' library (-lpthread). */ | /* Define to 1 if you have the `pthread' library (-lpthread). */ | |||
#define HAVE_LIBPTHREAD 1 | #define HAVE_LIBPTHREAD 1 | |||
/* Define to 1 if you have the `udis86' library (-ludis86). */ | /* Define to 1 if you have the `udis86' library (-ludis86). */ | |||
/* #undef HAVE_LIBUDIS86 */ | /* #undef HAVE_LIBUDIS86 */ | |||
/* Define to 1 if you have the `z' library (-lz). */ | ||||
#define HAVE_LIBZ 1 | ||||
/* Define to 1 if you have the <limits.h> header file. */ | /* Define to 1 if you have the <limits.h> header file. */ | |||
#define HAVE_LIMITS_H 1 | #define HAVE_LIMITS_H 1 | |||
/* Define if you can use -Wl,-export-dynamic. */ | /* Define if you can use -Wl,-export-dynamic. */ | |||
#define HAVE_LINK_EXPORT_DYNAMIC 1 | #define HAVE_LINK_EXPORT_DYNAMIC 1 | |||
/* Define to 1 if you have the <link.h> header file. */ | /* Define to 1 if you have the <link.h> header file. */ | |||
#define HAVE_LINK_H 1 | #define HAVE_LINK_H 1 | |||
/* Define if you can use -Wl,-R. to pass -R. to the linker, in order to add | /* 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. */ | the current directory to the dynamic linker search path. */ | |||
#define HAVE_LINK_R 1 | #define HAVE_LINK_R 1 | |||
/* Define to 1 if you have the `log' function. */ | ||||
#define HAVE_LOG 1 | ||||
/* Define to 1 if you have the `log10' function. */ | ||||
#define HAVE_LOG10 1 | ||||
/* Define to 1 if you have the `log2' function. */ | ||||
#define HAVE_LOG2 1 | ||||
/* Define to 1 if you have the `longjmp' function. */ | /* Define to 1 if you have the `longjmp' function. */ | |||
#define HAVE_LONGJMP 1 | #define HAVE_LONGJMP 1 | |||
/* Define to 1 if you have the <mach/mach.h> header file. */ | /* Define to 1 if you have the <mach/mach.h> header file. */ | |||
/* #undef HAVE_MACH_MACH_H */ | /* #undef HAVE_MACH_MACH_H */ | |||
/* Define to 1 if you have the <mach-o/dyld.h> header file. */ | /* Define to 1 if you have the <mach-o/dyld.h> header file. */ | |||
/* #undef HAVE_MACH_O_DYLD_H */ | /* #undef HAVE_MACH_O_DYLD_H */ | |||
/* Define if mallinfo() is available on this platform. */ | /* Define if mallinfo() is available on this platform. */ | |||
skipping to change at line 484 | skipping to change at line 513 | |||
/* Define to 1 if you have the <windows.h> header file. */ | /* Define to 1 if you have the <windows.h> header file. */ | |||
/* #undef HAVE_WINDOWS_H */ | /* #undef HAVE_WINDOWS_H */ | |||
/* Define to 1 if you have the `writev' function. */ | /* Define to 1 if you have the `writev' function. */ | |||
#define HAVE_WRITEV 1 | #define HAVE_WRITEV 1 | |||
/* Define if the xdot.py program is available */ | /* Define if the xdot.py program is available */ | |||
/* #undef HAVE_XDOT_PY */ | /* #undef HAVE_XDOT_PY */ | |||
/* Define to 1 if you have the <zlib.h> header file. */ | ||||
#define HAVE_ZLIB_H 1 | ||||
/* Have host's _alloca */ | /* Have host's _alloca */ | |||
/* #undef HAVE__ALLOCA */ | /* #undef HAVE__ALLOCA */ | |||
/* Have host's __alloca */ | /* Have host's __alloca */ | |||
/* #undef HAVE___ALLOCA */ | /* #undef HAVE___ALLOCA */ | |||
/* Have host's __ashldi3 */ | /* Have host's __ashldi3 */ | |||
/* #undef HAVE___ASHLDI3 */ | /* #undef HAVE___ASHLDI3 */ | |||
/* Have host's __ashrdi3 */ | /* Have host's __ashrdi3 */ | |||
skipping to change at line 539 | skipping to change at line 571 | |||
/* Have host's __umoddi3 */ | /* Have host's __umoddi3 */ | |||
/* #undef HAVE___UMODDI3 */ | /* #undef HAVE___UMODDI3 */ | |||
/* Have host's ___chkstk */ | /* Have host's ___chkstk */ | |||
/* #undef HAVE____CHKSTK */ | /* #undef HAVE____CHKSTK */ | |||
/* Linker version detected at compile time. */ | /* Linker version detected at compile time. */ | |||
#define HOST_LINK_VERSION "2.21.52.0.2.20110610" | #define HOST_LINK_VERSION "2.21.52.0.2.20110610" | |||
/* Installation directory for binary executables */ | /* Installation directory for binary executables */ | |||
#define LLVM_BINDIR "/home/ut/testing/llvm/3.2/bin" | #define LLVM_BINDIR "/home/ut/testing/llvm/3.3/bin" | |||
/* Time at which LLVM was configured */ | /* Time at which LLVM was configured */ | |||
#define LLVM_CONFIGTIME "Wed Jan 9 12:07:05 MSK 2013" | #define LLVM_CONFIGTIME "Tue Jun 18 03:16:37 MSK 2013" | |||
/* Installation directory for data files */ | /* Installation directory for data files */ | |||
#define LLVM_DATADIR "/home/ut/testing/llvm/3.2/share/llvm" | #define LLVM_DATADIR "/home/ut/testing/llvm/3.3/share/llvm" | |||
/* Target triple LLVM will generate code for by default */ | /* Target triple LLVM will generate code for by default */ | |||
#define LLVM_DEFAULT_TARGET_TRIPLE "i686-pc-linux-gnu" | #define LLVM_DEFAULT_TARGET_TRIPLE "i686-pc-linux-gnu" | |||
/* Installation directory for documentation */ | /* Installation directory for documentation */ | |||
#define LLVM_DOCSDIR "/home/ut/testing/llvm/3.2/share/doc/llvm" | #define LLVM_DOCSDIR "/home/ut/testing/llvm/3.3/share/doc/llvm" | |||
/* Define if threads enabled */ | /* Define if threads enabled */ | |||
#define LLVM_ENABLE_THREADS 1 | #define LLVM_ENABLE_THREADS 1 | |||
/* Define if zlib is enabled */ | ||||
#define LLVM_ENABLE_ZLIB 1 | ||||
/* Installation directory for config files */ | /* Installation directory for config files */ | |||
#define LLVM_ETCDIR "/home/ut/testing/llvm/3.2/etc/llvm" | #define LLVM_ETCDIR "/home/ut/testing/llvm/3.3/etc/llvm" | |||
/* Has gcc/MSVC atomic intrinsics */ | /* Has gcc/MSVC atomic intrinsics */ | |||
#define LLVM_HAS_ATOMICS 1 | #define LLVM_HAS_ATOMICS 1 | |||
/* Host triple LLVM will be executed on */ | /* Host triple LLVM will be executed on */ | |||
#define LLVM_HOSTTRIPLE "i686-pc-linux-gnu" | #define LLVM_HOST_TRIPLE "i686-pc-linux-gnu" | |||
/* Installation directory for include files */ | /* Installation directory for include files */ | |||
#define LLVM_INCLUDEDIR "/home/ut/testing/llvm/3.2/include" | #define LLVM_INCLUDEDIR "/home/ut/testing/llvm/3.3/include" | |||
/* Installation directory for .info files */ | /* Installation directory for .info files */ | |||
#define LLVM_INFODIR "/home/ut/testing/llvm/3.2/info" | #define LLVM_INFODIR "/home/ut/testing/llvm/3.3/info" | |||
/* Installation directory for libraries */ | /* Installation directory for libraries */ | |||
#define LLVM_LIBDIR "/home/ut/testing/llvm/3.2/lib" | #define LLVM_LIBDIR "/home/ut/testing/llvm/3.3/lib" | |||
/* Installation directory for man pages */ | /* Installation directory for man pages */ | |||
#define LLVM_MANDIR "/home/ut/testing/llvm/3.2/man" | #define LLVM_MANDIR "/home/ut/testing/llvm/3.3/man" | |||
/* LLVM architecture name for the native architecture, if available */ | /* LLVM architecture name for the native architecture, if available */ | |||
#define LLVM_NATIVE_ARCH X86 | #define LLVM_NATIVE_ARCH X86 | |||
/* LLVM name for the native AsmParser init function, if available */ | /* LLVM name for the native AsmParser init function, if available */ | |||
#define LLVM_NATIVE_ASMPARSER LLVMInitializeX86AsmParser | #define LLVM_NATIVE_ASMPARSER LLVMInitializeX86AsmParser | |||
/* LLVM name for the native AsmPrinter init function, if available */ | /* LLVM name for the native AsmPrinter init function, if available */ | |||
#define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter | #define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter | |||
skipping to change at line 632 | skipping to change at line 667 | |||
/* Define to path to neato program if found or 'echo neato' otherwise */ | /* Define to path to neato program if found or 'echo neato' otherwise */ | |||
#define LLVM_PATH_NEATO "/usr/bin/neato" | #define LLVM_PATH_NEATO "/usr/bin/neato" | |||
/* Define to path to twopi program if found or 'echo twopi' otherwise */ | /* Define to path to twopi program if found or 'echo twopi' otherwise */ | |||
#define LLVM_PATH_TWOPI "/usr/bin/twopi" | #define LLVM_PATH_TWOPI "/usr/bin/twopi" | |||
/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise * / | /* Define to path to xdot.py program if found or 'echo xdot.py' otherwise * / | |||
/* #undef LLVM_PATH_XDOT_PY */ | /* #undef LLVM_PATH_XDOT_PY */ | |||
/* Installation prefix directory */ | /* Installation prefix directory */ | |||
#define LLVM_PREFIX "/home/ut/testing/llvm/3.2" | #define LLVM_PREFIX "/home/ut/testing/llvm/3.3" | |||
/* Define if we have the Intel JIT API runtime support library */ | /* Define if we have the Intel JIT API runtime support library */ | |||
#define LLVM_USE_INTEL_JITEVENTS 0 | #define LLVM_USE_INTEL_JITEVENTS 0 | |||
/* Define if we have the oprofile JIT-support library */ | /* Define if we have the oprofile JIT-support library */ | |||
#define LLVM_USE_OPROFILE 0 | #define LLVM_USE_OPROFILE 0 | |||
/* Major version of the LLVM API */ | /* Major version of the LLVM API */ | |||
#define LLVM_VERSION_MAJOR 3 | #define LLVM_VERSION_MAJOR 3 | |||
/* Minor version of the LLVM API */ | /* Minor version of the LLVM API */ | |||
#define LLVM_VERSION_MINOR 2 | #define LLVM_VERSION_MINOR 3 | |||
/* Define if the OS needs help to load dependent libraries for dlopen(). */ | /* Define if the OS needs help to load dependent libraries for dlopen(). */ | |||
/* #undef LTDL_DLOPEN_DEPLIBS */ | /* #undef LTDL_DLOPEN_DEPLIBS */ | |||
/* Define to the sub-directory in which libtool stores uninstalled librarie s. | /* Define to the sub-directory in which libtool stores uninstalled librarie s. | |||
*/ | */ | |||
#define LTDL_OBJDIR ".libs/" | #define LTDL_OBJDIR ".libs/" | |||
/* Define to the name of the environment variable that determines the dynam ic | /* Define to the name of the environment variable that determines the dynam ic | |||
library search path. */ | library search path. */ | |||
skipping to change at line 677 | skipping to change at line 712 | |||
/* Define if dlsym() requires a leading underscore in symbol names. */ | /* Define if dlsym() requires a leading underscore in symbol names. */ | |||
/* #undef NEED_USCORE */ | /* #undef NEED_USCORE */ | |||
/* Define to the address where bug reports for this package should be sent. */ | /* Define to the address where bug reports for this package should be sent. */ | |||
#define PACKAGE_BUGREPORT "http://llvm.org/bugs/" | #define PACKAGE_BUGREPORT "http://llvm.org/bugs/" | |||
/* Define to the full name of this package. */ | /* Define to the full name of this package. */ | |||
#define PACKAGE_NAME "LLVM" | #define PACKAGE_NAME "LLVM" | |||
/* Define to the full name and version of this package. */ | /* Define to the full name and version of this package. */ | |||
#define PACKAGE_STRING "LLVM 3.2svn" | #define PACKAGE_STRING "LLVM 3.3" | |||
/* Define to the one symbol short name of this package. */ | /* Define to the one symbol short name of this package. */ | |||
#define PACKAGE_TARNAME "llvm" | #define PACKAGE_TARNAME "llvm" | |||
/* Define to the version of this package. */ | /* Define to the version of this package. */ | |||
#define PACKAGE_VERSION "3.2svn" | #define PACKAGE_VERSION "3.3" | |||
/* Define as the return type of signal handlers (`int' or `void'). */ | /* Define as the return type of signal handlers (`int' or `void'). */ | |||
#define RETSIGTYPE void | #define RETSIGTYPE void | |||
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */ | /* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */ | |||
/* #undef STAT_MACROS_BROKEN */ | /* #undef STAT_MACROS_BROKEN */ | |||
/* Define to 1 if you have the ANSI C header files. */ | /* Define to 1 if you have the ANSI C header files. */ | |||
#define STDC_HEADERS 1 | #define STDC_HEADERS 1 | |||
End of changes. 21 change blocks. | ||||
15 lines changed or deleted | 51 lines changed or added | |||
ilist.h | ilist.h | |||
---|---|---|---|---|
skipping to change at line 237 | skipping to change at line 237 | |||
ilist_iterator operator++(int) { // postincrement operators... | ilist_iterator operator++(int) { // postincrement operators... | |||
ilist_iterator tmp = *this; | ilist_iterator tmp = *this; | |||
++*this; | ++*this; | |||
return tmp; | return tmp; | |||
} | } | |||
// Internal interface, do not use... | // Internal interface, do not use... | |||
pointer getNodePtrUnchecked() const { return NodePtr; } | pointer getNodePtrUnchecked() const { return NodePtr; } | |||
}; | }; | |||
// do not implement. this is to catch errors when people try to use | // These are to catch errors when people try to use them as random access | |||
// them as random access iterators | // iterators. | |||
template<typename T> | template<typename T> | |||
void operator-(int, ilist_iterator<T>); | void operator-(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION; | |||
template<typename T> | template<typename T> | |||
void operator-(ilist_iterator<T>,int); | void operator-(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION; | |||
template<typename T> | template<typename T> | |||
void operator+(int, ilist_iterator<T>); | void operator+(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION; | |||
template<typename T> | template<typename T> | |||
void operator+(ilist_iterator<T>,int); | void operator+(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION; | |||
// operator!=/operator== - Allow mixed comparisons without dereferencing | // operator!=/operator== - Allow mixed comparisons without dereferencing | |||
// the iterator, which could very likely be pointing to end(). | // the iterator, which could very likely be pointing to end(). | |||
template<typename T> | template<typename T> | |||
bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) { | bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) { | |||
return LHS != RHS.getNodePtrUnchecked(); | return LHS != RHS.getNodePtrUnchecked(); | |||
} | } | |||
template<typename T> | template<typename T> | |||
bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) { | bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) { | |||
return LHS == RHS.getNodePtrUnchecked(); | return LHS == RHS.getNodePtrUnchecked(); | |||
skipping to change at line 276 | skipping to change at line 276 | |||
} | } | |||
// Allow ilist_iterators to convert into pointers to a node automatically w hen | // Allow ilist_iterators to convert into pointers to a node automatically w hen | |||
// used by the dyn_cast, cast, isa mechanisms... | // used by the dyn_cast, cast, isa mechanisms... | |||
template<typename From> struct simplify_type; | template<typename From> struct simplify_type; | |||
template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > { | template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > { | |||
typedef NodeTy* SimpleType; | typedef NodeTy* SimpleType; | |||
static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) { | static SimpleType getSimplifiedValue(ilist_iterator<NodeTy> &Node) { | |||
return &*Node; | return &*Node; | |||
} | } | |||
}; | }; | |||
template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > { | template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > { | |||
typedef NodeTy* SimpleType; | typedef /*const*/ NodeTy* SimpleType; | |||
static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) { | static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) { | |||
return &*Node; | return &*Node; | |||
} | } | |||
}; | }; | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
/// iplist - The subset of list functionality that can safely be used on no des | /// iplist - The subset of list functionality that can safely be used on no des | |||
/// of polymorphic types, i.e. a heterogeneous list with a common base clas s that | /// of polymorphic types, i.e. a heterogeneous list with a common base clas s that | |||
skipping to change at line 465 | skipping to change at line 465 | |||
iterator MutIt = IT; | iterator MutIt = IT; | |||
return remove(MutIt); | return remove(MutIt); | |||
} | } | |||
// erase - remove a node from the controlled sequence... and delete it. | // erase - remove a node from the controlled sequence... and delete it. | |||
iterator erase(iterator where) { | iterator erase(iterator where) { | |||
this->deleteNode(remove(where)); | this->deleteNode(remove(where)); | |||
return where; | return where; | |||
} | } | |||
/// Remove all nodes from the list like clear(), but do not call | ||||
/// removeNodeFromList() or deleteNode(). | ||||
/// | ||||
/// This should only be used immediately before freeing nodes in bulk to | ||||
/// avoid traversing the list and bringing all the nodes into cache. | ||||
void clearAndLeakNodesUnsafely() { | ||||
if (Head) { | ||||
Head = getTail(); | ||||
this->setPrev(Head, Head); | ||||
} | ||||
} | ||||
private: | private: | |||
// transfer - The heart of the splice function. Move linked list nodes f rom | // transfer - The heart of the splice function. Move linked list nodes f rom | |||
// [first, last) into position. | // [first, last) into position. | |||
// | // | |||
void transfer(iterator position, iplist &L2, iterator first, iterator las t) { | void transfer(iterator position, iplist &L2, iterator first, iterator las t) { | |||
assert(first != last && "Should be checked by callers"); | assert(first != last && "Should be checked by callers"); | |||
// Position cannot be contained in the range to be transferred. | ||||
// Check for the most common mistake. | ||||
assert(position != first && | ||||
"Insertion point can't be one of the transferred nodes"); | ||||
if (position != last) { | if (position != last) { | |||
// Note: we have to be careful about the case when we move the first node | // Note: we have to be careful about the case when we move the first node | |||
// in the list. This node is the list sentinel node and we can't mov e it. | // in the list. This node is the list sentinel node and we can't mov e it. | |||
NodeTy *ThisSentinel = getTail(); | NodeTy *ThisSentinel = getTail(); | |||
setTail(0); | setTail(0); | |||
NodeTy *L2Sentinel = L2.getTail(); | NodeTy *L2Sentinel = L2.getTail(); | |||
L2.setTail(0); | L2.setTail(0); | |||
// Remove [first, last) from its old position. | // Remove [first, last) from its old position. | |||
End of changes. 9 change blocks. | ||||
8 lines changed or deleted | 24 lines changed or added | |||
ilist_node.h | ilist_node.h | |||
---|---|---|---|---|
skipping to change at line 15 | skipping to change at line 15 | |||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | |||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This file defines the ilist_node class template, which is a convenient | // This file defines the ilist_node class template, which is a convenient | |||
// base class for creating classes that can be used with ilists. | // base class for creating classes that can be used with ilists. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_ADT_ILIST_NODE_H | #ifndef LLVM_ADT_ILISTNODE_H | |||
#define LLVM_ADT_ILIST_NODE_H | #define LLVM_ADT_ILISTNODE_H | |||
namespace llvm { | namespace llvm { | |||
template<typename NodeTy> | template<typename NodeTy> | |||
struct ilist_traits; | struct ilist_traits; | |||
/// ilist_half_node - Base class that provides prev services for sentinels. | /// ilist_half_node - Base class that provides prev services for sentinels. | |||
/// | /// | |||
template<typename NodeTy> | template<typename NodeTy> | |||
class ilist_half_node { | class ilist_half_node { | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
llvm-config.h | llvm-config.h | |||
---|---|---|---|---|
skipping to change at line 21 | skipping to change at line 21 | |||
/* This file enumerates all of the llvm variables from configure so that | /* This file enumerates all of the llvm variables from configure so that | |||
they can be in exported headers and won't override package specific | they can be in exported headers and won't override package specific | |||
directives. This is a C file so we can include it in the llvm-c headers . */ | directives. This is a C file so we can include it in the llvm-c headers . */ | |||
/* To avoid multiple inclusions of these variables when we include the expo rted | /* To avoid multiple inclusions of these variables when we include the expo rted | |||
headers and config.h, conditionally include these. */ | headers and config.h, conditionally include these. */ | |||
/* TODO: This is a bit of a hack. */ | /* TODO: This is a bit of a hack. */ | |||
#ifndef CONFIG_H | #ifndef CONFIG_H | |||
/* Installation directory for binary executables */ | /* Installation directory for binary executables */ | |||
#define LLVM_BINDIR "/home/ut/testing/llvm/3.2/bin" | #define LLVM_BINDIR "/home/ut/testing/llvm/3.3/bin" | |||
/* Time at which LLVM was configured */ | /* Time at which LLVM was configured */ | |||
#define LLVM_CONFIGTIME "Wed Jan 9 12:07:05 MSK 2013" | #define LLVM_CONFIGTIME "Tue Jun 18 03:16:37 MSK 2013" | |||
/* Installation directory for data files */ | /* Installation directory for data files */ | |||
#define LLVM_DATADIR "/home/ut/testing/llvm/3.2/share/llvm" | #define LLVM_DATADIR "/home/ut/testing/llvm/3.3/share/llvm" | |||
/* Target triple LLVM will generate code for by default */ | /* Target triple LLVM will generate code for by default */ | |||
#define LLVM_DEFAULT_TARGET_TRIPLE "i686-pc-linux-gnu" | #define LLVM_DEFAULT_TARGET_TRIPLE "i686-pc-linux-gnu" | |||
/* Installation directory for documentation */ | /* Installation directory for documentation */ | |||
#define LLVM_DOCSDIR "/home/ut/testing/llvm/3.2/share/doc/llvm" | #define LLVM_DOCSDIR "/home/ut/testing/llvm/3.3/share/doc/llvm" | |||
/* Define if threads enabled */ | /* Define if threads enabled */ | |||
#define LLVM_ENABLE_THREADS 1 | #define LLVM_ENABLE_THREADS 1 | |||
/* Installation directory for config files */ | /* Installation directory for config files */ | |||
#define LLVM_ETCDIR "/home/ut/testing/llvm/3.2/etc/llvm" | #define LLVM_ETCDIR "/home/ut/testing/llvm/3.3/etc/llvm" | |||
/* Has gcc/MSVC atomic intrinsics */ | /* Has gcc/MSVC atomic intrinsics */ | |||
#define LLVM_HAS_ATOMICS 1 | #define LLVM_HAS_ATOMICS 1 | |||
/* Host triple LLVM will be executed on */ | /* Host triple LLVM will be executed on */ | |||
#define LLVM_HOSTTRIPLE "i686-pc-linux-gnu" | #define LLVM_HOST_TRIPLE "i686-pc-linux-gnu" | |||
/* Installation directory for include files */ | /* Installation directory for include files */ | |||
#define LLVM_INCLUDEDIR "/home/ut/testing/llvm/3.2/include" | #define LLVM_INCLUDEDIR "/home/ut/testing/llvm/3.3/include" | |||
/* Installation directory for .info files */ | /* Installation directory for .info files */ | |||
#define LLVM_INFODIR "/home/ut/testing/llvm/3.2/info" | #define LLVM_INFODIR "/home/ut/testing/llvm/3.3/info" | |||
/* Installation directory for libraries */ | /* Installation directory for libraries */ | |||
#define LLVM_LIBDIR "/home/ut/testing/llvm/3.2/lib" | #define LLVM_LIBDIR "/home/ut/testing/llvm/3.3/lib" | |||
/* Installation directory for man pages */ | /* Installation directory for man pages */ | |||
#define LLVM_MANDIR "/home/ut/testing/llvm/3.2/man" | #define LLVM_MANDIR "/home/ut/testing/llvm/3.3/man" | |||
/* LLVM architecture name for the native architecture, if available */ | /* LLVM architecture name for the native architecture, if available */ | |||
#define LLVM_NATIVE_ARCH X86 | #define LLVM_NATIVE_ARCH X86 | |||
/* LLVM name for the native AsmParser init function, if available */ | /* LLVM name for the native AsmParser init function, if available */ | |||
#define LLVM_NATIVE_ASMPARSER LLVMInitializeX86AsmParser | #define LLVM_NATIVE_ASMPARSER LLVMInitializeX86AsmParser | |||
/* LLVM name for the native AsmPrinter init function, if available */ | /* LLVM name for the native AsmPrinter init function, if available */ | |||
#define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter | #define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter | |||
skipping to change at line 114 | skipping to change at line 114 | |||
/* Define to path to neato program if found or 'echo neato' otherwise */ | /* Define to path to neato program if found or 'echo neato' otherwise */ | |||
#define LLVM_PATH_NEATO "/usr/bin/neato" | #define LLVM_PATH_NEATO "/usr/bin/neato" | |||
/* Define to path to twopi program if found or 'echo twopi' otherwise */ | /* Define to path to twopi program if found or 'echo twopi' otherwise */ | |||
#define LLVM_PATH_TWOPI "/usr/bin/twopi" | #define LLVM_PATH_TWOPI "/usr/bin/twopi" | |||
/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise * / | /* Define to path to xdot.py program if found or 'echo xdot.py' otherwise * / | |||
/* #undef LLVM_PATH_XDOT_PY */ | /* #undef LLVM_PATH_XDOT_PY */ | |||
/* Installation prefix directory */ | /* Installation prefix directory */ | |||
#define LLVM_PREFIX "/home/ut/testing/llvm/3.2" | #define LLVM_PREFIX "/home/ut/testing/llvm/3.3" | |||
/* Define if we have the Intel JIT API runtime support library */ | ||||
#define LLVM_USE_INTEL_JITEVENTS 0 | ||||
/* Define if we have the oprofile JIT-support library */ | ||||
#define LLVM_USE_OPROFILE 0 | ||||
/* Major version of the LLVM API */ | /* Major version of the LLVM API */ | |||
#define LLVM_VERSION_MAJOR 3 | #define LLVM_VERSION_MAJOR 3 | |||
/* Minor version of the LLVM API */ | /* Minor version of the LLVM API */ | |||
#define LLVM_VERSION_MINOR 2 | #define LLVM_VERSION_MINOR 3 | |||
#endif | #endif | |||
End of changes. 12 change blocks. | ||||
12 lines changed or deleted | 18 lines changed or added | |||
lto.h | lto.h | |||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
|* License. See LICENSE.TXT for details. *| | |* License. See LICENSE.TXT for details. *| | |||
|* *| | |* *| | |||
|*===---------------------------------------------------------------------- ===*| | |*===---------------------------------------------------------------------- ===*| | |||
|* *| | |* *| | |||
|* This header provides public interface to an abstract link time optimizat ion*| | |* This header provides public interface to an abstract link time optimizat ion*| | |||
|* library. LLVM provides an implementation of this interface for use with *| | |* library. LLVM provides an implementation of this interface for use with *| | |||
|* llvm bitcode files. *| | |* llvm bitcode files. *| | |||
|* *| | |* *| | |||
\*===---------------------------------------------------------------------- ===*/ | \*===---------------------------------------------------------------------- ===*/ | |||
#ifndef LTO_H | #ifndef LLVM_C_LTO_H | |||
#define LTO_H 1 | #define LLVM_C_LTO_H | |||
#include <stdbool.h> | #include <stdbool.h> | |||
#include <stddef.h> | #include <stddef.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
/** | /** | |||
* @defgroup LLVMCLTO LTO | * @defgroup LLVMCLTO LTO | |||
* @ingroup LLVMC | * @ingroup LLVMC | |||
* | * | |||
* @{ | * @{ | |||
skipping to change at line 272 | skipping to change at line 272 | |||
*/ | */ | |||
extern bool | extern bool | |||
lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name); | lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name); | |||
/** | /** | |||
* Sets options to help debug codegen bugs. | * Sets options to help debug codegen bugs. | |||
*/ | */ | |||
extern void | extern void | |||
lto_codegen_debug_options(lto_code_gen_t cg, const char *); | lto_codegen_debug_options(lto_code_gen_t cg, const char *); | |||
/** | ||||
* Initializes LLVM disassemblers. | ||||
* FIXME: This doesn't really belong here. | ||||
*/ | ||||
extern void | ||||
lto_initialize_disassembler(void); | ||||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} | } | |||
#endif | #endif | |||
/** | /** | |||
* @} | * @} | |||
*/ | */ | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 9 lines changed or added | |||
raw_ostream.h | raw_ostream.h | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
class format_object_base; | class format_object_base; | |||
template <typename T> | template <typename T> | |||
class SmallVectorImpl; | class SmallVectorImpl; | |||
/// raw_ostream - This class implements an extremely fast bulk output strea m | /// raw_ostream - This class implements an extremely fast bulk output strea m | |||
/// that can *only* output to a stream. It does not support seeking, reope ning, | /// that can *only* output to a stream. It does not support seeking, reope ning, | |||
/// rewinding, line buffered disciplines etc. It is a simple buffer that ou tputs | /// rewinding, line buffered disciplines etc. It is a simple buffer that ou tputs | |||
/// a chunk at a time. | /// a chunk at a time. | |||
class raw_ostream { | class raw_ostream { | |||
private: | private: | |||
// Do not implement. raw_ostream is noncopyable. | ||||
void operator=(const raw_ostream &) LLVM_DELETED_FUNCTION; | void operator=(const raw_ostream &) LLVM_DELETED_FUNCTION; | |||
raw_ostream(const raw_ostream &) LLVM_DELETED_FUNCTION; | raw_ostream(const raw_ostream &) LLVM_DELETED_FUNCTION; | |||
/// The buffer is handled in such a way that the buffer is | /// The buffer is handled in such a way that the buffer is | |||
/// uninitialized, unbuffered, or out of space when OutBufCur >= | /// uninitialized, unbuffered, or out of space when OutBufCur >= | |||
/// OutBufEnd. Thus a single comparison suffices to determine if we | /// OutBufEnd. Thus a single comparison suffices to determine if we | |||
/// need to take the slow path to write a single character. | /// need to take the slow path to write a single character. | |||
/// | /// | |||
/// The buffer is in one of three states: | /// The buffer is in one of three states: | |||
/// 1. Unbuffered (BufferMode == Unbuffered) | /// 1. Unbuffered (BufferMode == Unbuffered) | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 0 lines changed or added | |||
system_error.h | system_error.h | |||
---|---|---|---|---|
skipping to change at line 17 | skipping to change at line 17 | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
// | // | |||
// This was lifted from libc++ and modified for C++03. This is called | // This was lifted from libc++ and modified for C++03. This is called | |||
// system_error even though it does not define that class because that's wh at | // system_error even though it does not define that class because that's wh at | |||
// it's called in C++0x. We don't define system_error because it is only us ed | // it's called in C++0x. We don't define system_error because it is only us ed | |||
// for exception handling, which we don't use in LLVM. | // for exception handling, which we don't use in LLVM. | |||
// | // | |||
//===---------------------------------------------------------------------- ===// | //===---------------------------------------------------------------------- ===// | |||
#ifndef LLVM_SYSTEM_SYSTEM_ERROR_H | #ifndef LLVM_SUPPORT_SYSTEM_ERROR_H | |||
#define LLVM_SYSTEM_SYSTEM_ERROR_H | #define LLVM_SUPPORT_SYSTEM_ERROR_H | |||
#include "llvm/Support/Compiler.h" | #include "llvm/Support/Compiler.h" | |||
/* | /* | |||
system_error synopsis | system_error synopsis | |||
namespace std | namespace std | |||
{ | { | |||
class error_category | class error_category | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
type_traits.h | type_traits.h | |||
---|---|---|---|---|
skipping to change at line 146 | skipping to change at line 146 | |||
template <typename T> struct remove_reference<T&> { typedef T type; }; | template <typename T> struct remove_reference<T&> { typedef T type; }; | |||
/// \brief Metafunction that determines whether the given type is a pointer | /// \brief Metafunction that determines whether the given type is a pointer | |||
/// type. | /// type. | |||
template <typename T> struct is_pointer : false_type {}; | template <typename T> struct is_pointer : false_type {}; | |||
template <typename T> struct is_pointer<T*> : true_type {}; | template <typename T> struct is_pointer<T*> : true_type {}; | |||
template <typename T> struct is_pointer<T* const> : true_type {}; | template <typename T> struct is_pointer<T* const> : true_type {}; | |||
template <typename T> struct is_pointer<T* volatile> : true_type {}; | template <typename T> struct is_pointer<T* volatile> : true_type {}; | |||
template <typename T> struct is_pointer<T* const volatile> : true_type {}; | template <typename T> struct is_pointer<T* const volatile> : true_type {}; | |||
/// \brief Metafunction that determines wheather the given type is a refere | ||||
nce. | ||||
template <typename T> struct is_reference : false_type {}; | ||||
template <typename T> struct is_reference<T&> : true_type {}; | ||||
/// \brief Metafunction that determines whether the given type is either an | /// \brief Metafunction that determines whether the given type is either an | |||
/// integral type or an enumeration type. | /// integral type or an enumeration type. | |||
/// | /// | |||
/// Note that this accepts potentially more integral types than we whitelis t | /// Note that this accepts potentially more integral types than we whitelis t | |||
/// above for is_integral because it is based on merely being convertible | /// above for is_integral because it is based on merely being convertible | |||
/// implicitly to an integral type. | /// implicitly to an integral type. | |||
template <typename T> class is_integral_or_enum { | template <typename T> class is_integral_or_enum { | |||
// Provide an overload which can be called with anything implicitly | // Provide an overload which can be called with anything implicitly | |||
// convertible to an unsigned long long. This should catch integer types and | // convertible to an unsigned long long. This should catch integer types and | |||
// enumeration types at least. We blacklist classes with conversion opera tors | // enumeration types at least. We blacklist classes with conversion opera tors | |||
skipping to change at line 206 | skipping to change at line 210 | |||
// remove_pointer - Metafunction to turn Foo* into Foo. Defined in | // remove_pointer - Metafunction to turn Foo* into Foo. Defined in | |||
// C++0x [meta.trans.ptr]. | // C++0x [meta.trans.ptr]. | |||
template <typename T> struct remove_pointer { typedef T type; }; | template <typename T> struct remove_pointer { typedef T type; }; | |||
template <typename T> struct remove_pointer<T*> { typedef T type; }; | template <typename T> struct remove_pointer<T*> { typedef T type; }; | |||
template <typename T> struct remove_pointer<T*const> { typedef T type; }; | template <typename T> struct remove_pointer<T*const> { typedef T type; }; | |||
template <typename T> struct remove_pointer<T*volatile> { typedef T type; } ; | template <typename T> struct remove_pointer<T*volatile> { typedef T type; } ; | |||
template <typename T> struct remove_pointer<T*const volatile> { | template <typename T> struct remove_pointer<T*const volatile> { | |||
typedef T type; }; | typedef T type; }; | |||
// If T is a pointer, just return it. If it is not, return T&. | ||||
template<typename T, typename Enable = void> | ||||
struct add_lvalue_reference_if_not_pointer { typedef T &type; }; | ||||
template<typename T> | ||||
struct add_lvalue_reference_if_not_pointer<T, | ||||
typename enable_if<is_pointer<T> >::ty | ||||
pe> { | ||||
typedef T type; | ||||
}; | ||||
// If T is a pointer to X, return a pointer to const X. If it is not, retur | ||||
n | ||||
// const T. | ||||
template<typename T, typename Enable = void> | ||||
struct add_const_past_pointer { typedef const T type; }; | ||||
template<typename T> | ||||
struct add_const_past_pointer<T, typename enable_if<is_pointer<T> >::type> | ||||
{ | ||||
typedef const typename remove_pointer<T>::type *type; | ||||
}; | ||||
template <bool, typename T, typename F> | template <bool, typename T, typename F> | |||
struct conditional { typedef T type; }; | struct conditional { typedef T type; }; | |||
template <typename T, typename F> | template <typename T, typename F> | |||
struct conditional<false, T, F> { typedef F type; }; | struct conditional<false, T, F> { typedef F type; }; | |||
} | } | |||
#ifdef LLVM_DEFINED_HAS_FEATURE | #ifdef LLVM_DEFINED_HAS_FEATURE | |||
#undef __has_feature | #undef __has_feature | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 28 lines changed or added | |||